hamlib-4.6.2/0000755000175000017500000000000014752216247007772 500000000000000hamlib-4.6.2/LICENSE0000644000175000017500000000463414752216205010720 00000000000000Hamlib - Ham Radio Control Libraries (C) 2010 Lockless Inc. for winpthreads.h Copyright (C) 2000,2001 Frank Singleton Copyright (C) 2000,2001 Stephane Fillod Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009, 2010,2011,2012 The Hamlib Group See the included README.md file for more information on Hamlib and the Hamlib Project or visit http://www.hamlib.org for documentation and links to the source code of Hamlib. The 'AUTHORS' file lists contributors known as the The Hamlib Group. The frontend library source code files and associated backend library source code files are licensed and released under the Lesser GNU Public License (LGPL): This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA The included file 'COPYING.LIB' is a copy of the GNU Lesser General Public License. Various other supplied program source files and example source files are licensed and released under the GNU Public License (GPL): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. The included file 'COPYING' is a copy of the GNU General Public License. hamlib-4.6.2/c++/0000755000175000017500000000000014752216241010334 500000000000000hamlib-4.6.2/c++/Makefile.am0000644000175000017500000000127314752216205012313 00000000000000 lib_LTLIBRARIES = libhamlib++.la libhamlib___la_SOURCES = rigclass.cc rotclass.cc ampclass.cc libhamlib___la_LDFLAGS = -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE) $(LDFLAGS) libhamlib___la_LIBADD = $(top_builddir)/src/libhamlib.la AM_CXXFLAGS=$(CXXFLAGS) check_PROGRAMS = testcpp testcpp_SOURCES = testcpp.cc testcpp_LDADD = libhamlib++.la $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) testcpp_DEPENDENCIES = libhamlib++.la check_SCRIPTS = testcpp.sh TESTS = $(check_SCRIPTS) testcpp.sh: echo 'LD_LIBRARY_PATH=$(top_builddir)/c++/.libs:$(top_builddir)/dummy/.libs ./testcpp' > testcpp.sh chmod +x ./testcpp.sh CLEANFILES = testcpp.sh hamlib-4.6.2/c++/Makefile.in0000644000175000017500000011361414752216215012330 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = testcpp$(EXEEXT) subdir = c++ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) libhamlib___la_DEPENDENCIES = $(top_builddir)/src/libhamlib.la am_libhamlib___la_OBJECTS = rigclass.lo rotclass.lo ampclass.lo libhamlib___la_OBJECTS = $(am_libhamlib___la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libhamlib___la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(libhamlib___la_LDFLAGS) \ $(LDFLAGS) -o $@ am_testcpp_OBJECTS = testcpp.$(OBJEXT) testcpp_OBJECTS = $(am_testcpp_OBJECTS) am__DEPENDENCIES_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ampclass.Plo \ ./$(DEPDIR)/rigclass.Plo ./$(DEPDIR)/rotclass.Plo \ ./$(DEPDIR)/testcpp.Po am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libhamlib___la_SOURCES) $(testcpp_SOURCES) DIST_SOURCES = $(libhamlib___la_SOURCES) $(testcpp_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp \ $(top_srcdir)/build-aux/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = $(CXXFLAGS) AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ lib_LTLIBRARIES = libhamlib++.la libhamlib___la_SOURCES = rigclass.cc rotclass.cc ampclass.cc libhamlib___la_LDFLAGS = -no-undefined -version-info $(ABI_VERSION):$(ABI_REVISION):$(ABI_AGE) $(LDFLAGS) libhamlib___la_LIBADD = $(top_builddir)/src/libhamlib.la testcpp_SOURCES = testcpp.cc testcpp_LDADD = libhamlib++.la $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) testcpp_DEPENDENCIES = libhamlib++.la check_SCRIPTS = testcpp.sh TESTS = $(check_SCRIPTS) CLEANFILES = testcpp.sh all: all-am .SUFFIXES: .SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu c++/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu c++/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib++.la: $(libhamlib___la_OBJECTS) $(libhamlib___la_DEPENDENCIES) $(EXTRA_libhamlib___la_DEPENDENCIES) $(AM_V_CXXLD)$(libhamlib___la_LINK) -rpath $(libdir) $(libhamlib___la_OBJECTS) $(libhamlib___la_LIBADD) $(LIBS) testcpp$(EXEEXT): $(testcpp_OBJECTS) $(testcpp_DEPENDENCIES) $(EXTRA_testcpp_DEPENDENCIES) @rm -f testcpp$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(testcpp_OBJECTS) $(testcpp_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ampclass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rigclass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rotclass.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testcpp.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) $(check_SCRIPTS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) $(check_SCRIPTS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? testcpp.sh.log: testcpp.sh @p='testcpp.sh'; \ b='testcpp.sh'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: for dir in "$(DESTDIR)$(libdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ampclass.Plo -rm -f ./$(DEPDIR)/rigclass.Plo -rm -f ./$(DEPDIR)/rotclass.Plo -rm -f ./$(DEPDIR)/testcpp.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ampclass.Plo -rm -f ./$(DEPDIR)/rigclass.Plo -rm -f ./$(DEPDIR)/rotclass.Plo -rm -f ./$(DEPDIR)/testcpp.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ check-am clean clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ uninstall-libLTLIBRARIES .PRECIOUS: Makefile testcpp.sh: echo 'LD_LIBRARY_PATH=$(top_builddir)/c++/.libs:$(top_builddir)/dummy/.libs ./testcpp' > testcpp.sh chmod +x ./testcpp.sh # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/c++/testcpp.cc0000644000175000017500000000077614752216205012257 00000000000000 /* * Hamlib sample C++ program */ #include #include int main(int argc, char* argv[]) { Rig myRig {RIG_MODEL_DUMMY}; try { myRig.setConf("rig_pathname", "/dev/pts/4"); myRig.open(); myRig.setFreq(MHz(144)); std::cout << myRig.getLevelI(RIG_LEVEL_STRENGTH) << "dB" << std::endl; std::cout << "Modes for freq 14.332: " << myRig.RngRxModes(MHz(14.332)) << std::endl; myRig.close(); } catch (const RigException &Ex) { Ex.print(); return 1; } return 0; } hamlib-4.6.2/c++/rotclass.cc0000644000175000017500000000536714752216205012430 00000000000000/** * \file src/rotclass.cc * \brief Ham Radio Control Libraries C++ interface * \author Stephane Fillod * \date 2002 * * Hamlib C++ interface is a frontend implementing wrapper functions. */ /* * Hamlib C++ bindings - main file * Copyright (c) 2002 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #define CHECK_ROT(cmd) { int _retval = cmd; if (_retval != RIG_OK) \ THROW(new RigException (_retval)); } Rotator::Rotator(rot_model_t rot_model) { theRot = rot_init(rot_model); if (!theRot) THROW(new RigException ("Rotator initialization error")); caps = theRot->caps; theRot->state.obj = (rig_ptr_t)this; } Rotator::~Rotator() { theRot->state.obj = NULL; CHECK_ROT( rot_cleanup(theRot) ); caps = NULL; } void Rotator::open(void) { CHECK_ROT( rot_open(theRot) ); } void Rotator::close(void) { CHECK_ROT( rot_close(theRot) ); } void Rotator::setConf(hamlib_token_t token, const char *val) { CHECK_ROT( rot_set_conf(theRot, token, val) ); } void Rotator::setConf(const char *name, const char *val) { CHECK_ROT( rot_set_conf(theRot, tokenLookup(name), val) ); } void Rotator::getConf(hamlib_token_t token, char *val) { CHECK_ROT( rot_get_conf(theRot, token, val) ); } void Rotator::getConf(const char *name, char *val) { CHECK_ROT( rot_get_conf(theRot, tokenLookup(name), val) ); } hamlib_token_t Rotator::tokenLookup(const char *name) { return rot_token_lookup(theRot, name); } void Rotator::setPosition(azimuth_t az, elevation_t el) { CHECK_ROT( rot_set_position(theRot, az, el) ); } void Rotator::getPosition(azimuth_t& az, elevation_t& el) { CHECK_ROT( rot_get_position(theRot, &az, &el) ); } void Rotator::stop() { CHECK_ROT(rot_stop(theRot)); } void Rotator::park() { CHECK_ROT(rot_park(theRot)); } void Rotator::reset (rot_reset_t reset) { CHECK_ROT( rot_reset(theRot, reset) ); } void Rotator::move (int direction, int speed) { CHECK_ROT( rot_move(theRot, direction, speed) ); } hamlib-4.6.2/c++/ampclass.cc0000644000175000017500000000512014752216205012364 00000000000000/** * \file src/ampclass.cc * \brief Ham Radio Control Libraries C++ interface * \author Stephane Fillod * \date 2002 * * Hamlib C++ interface is a frontend implementing wrapper functions. */ /* * Hamlib C++ bindings - main file * Copyright (c) 2002 by Stephane Fillod * Copyright (c) 2019 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include //#include #include #include #define CHECK_AMP(cmd) { int _retval = cmd; if (_retval != RIG_OK) \ THROW(new RigException (_retval)); } Amplifier::Amplifier(amp_model_t amp_model) { theAmp = amp_init(amp_model); if (!theAmp) THROW(new RigException ("Amplifier initialization error")); caps = theAmp->caps; theAmp->state.obj = (amp_ptr_t)this; } Amplifier::~Amplifier() { theAmp->state.obj = NULL; CHECK_AMP( amp_cleanup(theAmp) ); caps = NULL; } void Amplifier::open(void) { CHECK_AMP( amp_open(theAmp) ); } void Amplifier::close(void) { CHECK_AMP( amp_close(theAmp) ); } void Amplifier::setConf(hamlib_token_t token, const char *val) { CHECK_AMP( amp_set_conf(theAmp, token, val) ); } void Amplifier::setConf(const char *name, const char *val) { CHECK_AMP( amp_set_conf(theAmp, tokenLookup(name), val) ); } void Amplifier::getConf(hamlib_token_t token, char *val) { CHECK_AMP( amp_get_conf(theAmp, token, val) ); } void Amplifier::getConf(const char *name, char *val) { CHECK_AMP( amp_get_conf(theAmp, tokenLookup(name), val) ); } hamlib_token_t Amplifier::tokenLookup(const char *name) { return amp_token_lookup(theAmp, name); } void Amplifier::reset (amp_reset_t reset) { CHECK_AMP( amp_reset(theAmp, reset) ); } void Amplifier::setFreq(freq_t freq) { CHECK_AMP( amp_set_freq(theAmp, freq) ); } freq_t Amplifier::getFreq() { freq_t freq; CHECK_AMP( amp_get_freq(theAmp, &freq) ); return freq; } hamlib-4.6.2/c++/rigclass.cc0000644000175000017500000003205714752216205012401 00000000000000/** * \file src/rigclass.cc * \brief Ham Radio Control Libraries C++ interface * \author Stephane Fillod * \date 2001-2003 * * Hamlib C++ interface is a frontend implementing wrapper functions. */ /* * Hamlib C++ bindings - main file * Copyright (c) 2001-2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #define CHECK_RIG(cmd) { int _retval = cmd; if (_retval != RIG_OK) \ THROW(new RigException (_retval)); } static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg); static int hamlibpp_freq_event(RIG *rig, vfo_t vfo, freq_t freq, rig_ptr_t arg) { if (!rig || !rig->state.obj) return -RIG_EINVAL; /* assert rig == ((Rig*)rig->state.obj).theRig */ return (static_cast(rig->state.obj))->FreqEvent(vfo, freq, arg); } Rig::Rig(rig_model_t rig_model) { theRig = rig_init(rig_model); if (!theRig) THROW(new RigException ("Rig initialization error")); caps = theRig->caps; theRig->callbacks.freq_event = &hamlibpp_freq_event; theRig->state.obj = (rig_ptr_t)this; } Rig::~Rig() { theRig->state.obj = NULL; CHECK_RIG( rig_cleanup(theRig) ); caps = NULL; } void Rig::open(void) { CHECK_RIG( rig_open(theRig) ); } void Rig::close(void) { CHECK_RIG( rig_close(theRig) ); } void Rig::setConf(hamlib_token_t token, const char *val) { CHECK_RIG( rig_set_conf(theRig, token, val) ); } void Rig::setConf(const char *name, const char *val) { CHECK_RIG( rig_set_conf(theRig, tokenLookup(name), val) ); } void Rig::getConf(hamlib_token_t token, char *val) { CHECK_RIG( rig_get_conf(theRig, token, val) ); } void Rig::getConf(const char *name, char *val) { CHECK_RIG( rig_get_conf(theRig, tokenLookup(name), val) ); } hamlib_token_t Rig::tokenLookup(const char *name) { return rig_token_lookup(theRig, name); } void Rig::setFreq(freq_t freq, vfo_t vfo) { CHECK_RIG( rig_set_freq(theRig, vfo, freq) ); } freq_t Rig::getFreq(vfo_t vfo) { freq_t freq; CHECK_RIG( rig_get_freq(theRig, vfo, &freq) ); return freq; } void Rig::setMode(rmode_t mode, pbwidth_t width, vfo_t vfo) { CHECK_RIG(rig_set_mode(theRig, vfo, mode, width)); } rmode_t Rig::getMode(pbwidth_t& width, vfo_t vfo) { rmode_t mode; CHECK_RIG( rig_get_mode(theRig, vfo, &mode, &width) ); return mode; } void Rig::setVFO(vfo_t vfo) { CHECK_RIG( rig_set_vfo(theRig, vfo) ); } vfo_t Rig::getVFO() { vfo_t vfo; CHECK_RIG( rig_get_vfo(theRig, &vfo) ); return vfo; } void Rig::setPTT(ptt_t ptt, vfo_t vfo) { CHECK_RIG( rig_set_ptt(theRig, vfo, ptt) ); } ptt_t Rig::getPTT(vfo_t vfo) { ptt_t ptt; CHECK_RIG( rig_get_ptt(theRig, vfo, &ptt) ); return ptt; } dcd_t Rig::getDCD(vfo_t vfo) { dcd_t dcd; CHECK_RIG( rig_get_dcd(theRig, vfo, &dcd) ); return dcd; } void Rig::setLevel(setting_t level, int vali, vfo_t vfo) { value_t val; val.i = vali; CHECK_RIG( rig_set_level(theRig, vfo, level, val) ); } void Rig::setLevel(setting_t level, float valf, vfo_t vfo) { value_t val; val.f = valf; CHECK_RIG( rig_set_level(theRig, vfo, level, val) ); } void Rig::getLevel(setting_t level, int& vali, vfo_t vfo) { value_t val; if (RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); vali = val.i; } void Rig::getLevel(setting_t level, float& valf, vfo_t vfo) { value_t val; if (!RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); valf = val.f; } int Rig::getLevelI(setting_t level, vfo_t vfo) { value_t val; if (RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); return val.i; } float Rig::getLevelF(setting_t level, vfo_t vfo) { value_t val; if (!RIG_LEVEL_IS_FLOAT(level)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_level(theRig, vfo, level, &val) ); return val.f; } void Rig::setParm(setting_t parm, int vali) { value_t val; val.i = vali; CHECK_RIG( rig_set_parm(theRig, parm, val) ); } void Rig::setParm(setting_t parm, float valf) { value_t val; val.f = valf; CHECK_RIG( rig_set_parm(theRig, parm, val) ); } void Rig::getParm(setting_t parm, int& vali) { value_t val; if (RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); vali = val.i; } void Rig::getParm(setting_t parm, float& valf) { value_t val; if (!RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); valf = val.f; } int Rig::getParmI(setting_t parm) { value_t val; if (RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); return val.i; } float Rig::getParmF(setting_t parm) { value_t val; if (!RIG_LEVEL_IS_FLOAT(parm)) THROW(new RigException (-RIG_EINVAL)); CHECK_RIG( rig_get_parm(theRig, parm, &val) ); return val.f; } void Rig::setSplitFreq(freq_t tx_freq, vfo_t vfo) { CHECK_RIG( rig_set_split_freq(theRig, vfo, tx_freq) ); } freq_t Rig::getSplitFreq(vfo_t vfo) { freq_t freq; CHECK_RIG( rig_get_split_freq(theRig, vfo, &freq) ); return freq; } void Rig::setSplitMode(rmode_t mode, pbwidth_t width, vfo_t vfo) { CHECK_RIG(rig_set_split_mode(theRig, vfo, mode, width)); } rmode_t Rig::getSplitMode(pbwidth_t& width, vfo_t vfo) { rmode_t mode; CHECK_RIG( rig_get_split_mode(theRig, vfo, &mode, &width) ); return mode; } void Rig::setSplitFreqMode(freq_t tx_freq, rmode_t mode, pbwidth_t width, vfo_t vfo) { CHECK_RIG (rig_set_split_freq_mode (theRig, vfo, tx_freq, mode, width)); } freq_t Rig::getSplitFreqMode(rmode_t& mode, pbwidth_t& width, vfo_t vfo) { freq_t freq; CHECK_RIG (rig_get_split_freq_mode (theRig, vfo, &freq, &mode, &width)); return freq; } void Rig::setSplitVFO(split_t split, vfo_t vfo, vfo_t tx_vfo) { CHECK_RIG(rig_set_split_vfo(theRig, vfo, split, tx_vfo)); } split_t Rig::getSplitVFO(vfo_t &tx_vfo, vfo_t vfo) { split_t split; CHECK_RIG( rig_get_split_vfo(theRig, vfo, &split, &tx_vfo) ); return split; } bool Rig::hasGetLevel (setting_t level) { return rig_has_get_level(theRig, level) == level; } bool Rig::hasSetLevel (setting_t level) { return rig_has_set_level(theRig, level) == level; } bool Rig::hasGetParm (setting_t parm) { return rig_has_get_parm(theRig, parm) == parm; } bool Rig::hasSetParm (setting_t parm) { return rig_has_set_parm(theRig, parm) == parm; } const char *Rig::getInfo (void) { return rig_get_info(theRig); } pbwidth_t Rig::passbandNormal (rmode_t mode) { return rig_passband_normal(theRig, mode); } pbwidth_t Rig::passbandNarrow (rmode_t mode) { return rig_passband_narrow(theRig, mode); } pbwidth_t Rig::passbandWide (rmode_t mode) { return rig_passband_wide(theRig, mode); } void Rig::setRptrShift (rptr_shift_t rptr_shift, vfo_t vfo) { CHECK_RIG( rig_set_rptr_shift(theRig, vfo, rptr_shift) ); } rptr_shift_t Rig::getRptrShift (vfo_t vfo) { rptr_shift_t rptr_shift; CHECK_RIG( rig_get_rptr_shift(theRig, vfo, &rptr_shift) ); return rptr_shift; } void Rig::setRptrOffs (shortfreq_t rptr_offs, vfo_t vfo) { CHECK_RIG( rig_set_rptr_offs(theRig, vfo, rptr_offs) ); } shortfreq_t Rig::getRptrOffs (vfo_t vfo) { shortfreq_t rptr_offs; CHECK_RIG( rig_get_rptr_offs(theRig, vfo, &rptr_offs) ); return rptr_offs; } void Rig::setTs (shortfreq_t ts, vfo_t vfo) { CHECK_RIG( rig_set_ts(theRig, vfo, ts) ); } shortfreq_t Rig::getTs (vfo_t vfo) { shortfreq_t ts; CHECK_RIG( rig_get_ts(theRig, vfo, &ts) ); return ts; } void Rig::setCTCSS (tone_t tone, vfo_t vfo) { CHECK_RIG( rig_set_ctcss_tone(theRig, vfo, tone) ); } tone_t Rig::getCTCSS (vfo_t vfo) { tone_t tone; CHECK_RIG( rig_get_ctcss_tone(theRig, vfo, &tone) ); return tone; } void Rig::setDCS (tone_t code, vfo_t vfo) { CHECK_RIG( rig_set_dcs_code(theRig, vfo, code) ); } tone_t Rig::getDCS (vfo_t vfo) { tone_t code; CHECK_RIG( rig_get_dcs_code(theRig, vfo, &code) ); return code; } void Rig::setCTCSSsql (tone_t tone, vfo_t vfo) { CHECK_RIG( rig_set_ctcss_sql(theRig, vfo, tone) ); } tone_t Rig::getCTCSSsql (vfo_t vfo) { tone_t tone; CHECK_RIG( rig_get_ctcss_sql(theRig, vfo, &tone) ); return tone; } void Rig::setDCSsql (tone_t code, vfo_t vfo) { CHECK_RIG( rig_set_dcs_sql(theRig, vfo, code) ); } tone_t Rig::getDCSsql (vfo_t vfo) { tone_t code; CHECK_RIG( rig_get_dcs_sql(theRig, vfo, &code) ); return code; } void Rig::setFunc (setting_t func, bool status, vfo_t vfo) { CHECK_RIG( rig_set_func(theRig, vfo, func, status? 1:0) ); } bool Rig::getFunc (setting_t func, vfo_t vfo) { int status; CHECK_RIG( rig_get_func(theRig, vfo, func, &status) ); return status ? true : false; } void Rig::VFOop (vfo_op_t op, vfo_t vfo) { CHECK_RIG( rig_vfo_op(theRig, vfo, op) ); } bool Rig::hasVFOop (vfo_op_t op) { return rig_has_vfo_op(theRig, op)==op; } void Rig::scan (scan_t scan, int ch, vfo_t vfo) { CHECK_RIG( rig_scan(theRig, vfo, scan, ch) ); } bool Rig::hasScan (scan_t scan) { return rig_has_scan(theRig, scan)==scan; } void Rig::setRit(shortfreq_t rit, vfo_t vfo) { CHECK_RIG(rig_set_rit(theRig, vfo, rit)); } shortfreq_t Rig::getRit(vfo_t vfo) { shortfreq_t rit; CHECK_RIG( rig_get_rit(theRig, vfo, &rit) ); return rit; } void Rig::setXit(shortfreq_t xit, vfo_t vfo) { CHECK_RIG(rig_set_xit(theRig, vfo, xit)); } shortfreq_t Rig::getXit(vfo_t vfo) { shortfreq_t xit; CHECK_RIG( rig_get_xit(theRig, vfo, &xit) ); return xit; } void Rig::setAnt(const value_t option, ant_t ant, vfo_t vfo) { CHECK_RIG(rig_set_ant(theRig, vfo, ant, option)); } ant_t Rig::getAnt(ant_t &ant_rx, ant_t &ant_tx, ant_t ant, value_t &option, ant_t &ant_curr, vfo_t vfo) { CHECK_RIG( rig_get_ant(theRig, vfo, ant, &option, &ant_curr, &ant_tx, &ant_rx) ); return ant; } void Rig::sendDtmf(const char *digits, vfo_t vfo) { CHECK_RIG(rig_send_dtmf(theRig, vfo, digits)); } int Rig::recvDtmf(char *digits, vfo_t vfo) { int len; CHECK_RIG( rig_recv_dtmf(theRig, vfo, digits, &len) ); return len; } void Rig::sendMorse(const char *msg, vfo_t vfo) { CHECK_RIG(rig_send_morse(theRig, vfo, msg)); } shortfreq_t Rig::getResolution (rmode_t mode) { shortfreq_t res; res = rig_get_resolution(theRig, mode); if (res < 0) THROW(new RigException (res)); return res; } void Rig::reset (reset_t reset) { CHECK_RIG( rig_reset(theRig, reset) ); } bool Rig::hasGetFunc (setting_t func) { return rig_has_get_func(theRig, func)==func; } bool Rig::hasSetFunc (setting_t func) { return rig_has_set_func(theRig, func)==func; } unsigned int Rig::power2mW (float power, freq_t freq, rmode_t mode) { unsigned int mwpower; CHECK_RIG( rig_power2mW(theRig, &mwpower, power, freq, mode) ); return mwpower; } float Rig::mW2power (unsigned int mwpower, freq_t freq, rmode_t mode) { float power; CHECK_RIG( rig_mW2power(theRig, &power, mwpower, freq, mode) ); return power; } void Rig::setTrn (int trn) { CHECK_RIG( rig_set_trn(theRig, trn) ); } int Rig::getTrn () { int trn; CHECK_RIG( rig_get_trn(theRig, &trn) ); return trn; } void Rig::setBank (int bank, vfo_t vfo) { CHECK_RIG( rig_set_ts(theRig, vfo, bank) ); } void Rig::setMem (int ch, vfo_t vfo) { CHECK_RIG( rig_set_mem(theRig, vfo, ch) ); } int Rig::getMem (vfo_t vfo) { int mem; CHECK_RIG( rig_get_mem(theRig, vfo, &mem) ); return mem; } void Rig::setChannel (const channel_t *chan, vfo_t vfo) { CHECK_RIG( rig_set_channel(theRig, vfo, chan) ); } void Rig::getChannel (channel_t *chan,vfo_t vfo, int readOnly) { CHECK_RIG( rig_get_channel(theRig, vfo, chan, readOnly) ); } void Rig::setPowerStat (powerstat_t status) { CHECK_RIG( rig_set_powerstat(theRig, status) ); } powerstat_t Rig::getPowerStat (void) { powerstat_t status; CHECK_RIG( rig_get_powerstat(theRig, &status) ); return status; } rmode_t Rig::RngRxModes (freq_t freq) { unsigned modes = RIG_MODE_NONE; int i; for (i=0; istate.rx_range_list[i]; if (RIG_IS_FRNG_END(*rng)) { return (rmode_t)modes; } if (freq >= rng->startf && freq <= rng->endf) modes |= (unsigned)rng->modes; } return (rmode_t)modes; } rmode_t Rig::RngTxModes (freq_t freq) { unsigned modes = RIG_MODE_NONE; int i; for (i=0; istate.tx_range_list[i]; if (RIG_IS_FRNG_END(*rng)) { return (rmode_t)modes; } if (freq >= rng->startf && freq <= rng->endf) modes |= (unsigned)rng->modes; } return (rmode_t)modes; } hamlib-4.6.2/aclocal.m40000644000175000017500000015077714752216211011562 00000000000000# generated automatically by aclocal 1.16.3 -*- Autoconf -*- # Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # --------------------------------------------------------------------------- # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python python2 python3 dnl python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl python3.2 python3.1 python3.0 dnl python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. if test -z "$PYTHON"; then AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) fi am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version is >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_ERROR([Python interpreter is too old])]) am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do test "$am_cv_pathless_PYTHON" = none && break AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) fi am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) if test "$PYTHON" = :; then dnl Run any user-specified action, or abort. m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) else dnl Query Python for its version number. Although site.py simply uses dnl sys.version[:3], printing that failed with Python 3.10, since the dnl trailing zero was eliminated. So now we output just the major dnl and minor version numbers, as numbers. Apparently the tertiary dnl version is not of interest. AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[[:2]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl Use the values of $prefix and $exec_prefix for the corresponding dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made dnl distinct variables so they can be overridden if need be. However, dnl general consensus is that you shouldn't need this ability. AC_SUBST([PYTHON_PREFIX], ['${prefix}']) AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) dnl At times (like when building shared libraries) you may want dnl to know which OS platform Python thinks this is. AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) # Just factor out some code duplication. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': can_use_sysconfig = 0 except ImportError: pass" dnl Set up 4 directories: dnl pythondir -- where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory like in previous automake betas. This behavior dnl is more consistent with lispdir.m4 for example. dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON script directory], [am_cv_python_pythondir], [if test "x$prefix" = xNONE then am_py_prefix=$ac_default_prefix else am_py_prefix=$prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl pkgpythondir -- $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl pyexecdir -- directory for installing python extension modules dnl (shared libraries) dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], [am_cv_python_pyexecdir], [if test "x$exec_prefix" = xNONE then am_py_exec_prefix=$am_py_prefix else am_py_exec_prefix=$exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) dnl Run any user-specified action. $2 fi ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalent (first # word of sys.version), in order to cope with versions such as 2.2c1. # This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([macros/ax_append_flag.m4]) m4_include([macros/ax_cflags_warn_all.m4]) m4_include([macros/ax_cxx_compile_stdcxx.m4]) m4_include([macros/ax_lib_indi.m4]) m4_include([macros/ax_lib_nova.m4]) m4_include([macros/ax_lib_readline.m4]) m4_include([macros/ax_lua.m4]) m4_include([macros/ax_pkg_swig.m4]) m4_include([macros/ax_pthread.m4]) m4_include([macros/ax_python_devel.m4]) m4_include([macros/gr_pwin32.m4]) m4_include([macros/hl_getaddrinfo.m4]) m4_include([macros/libtool.m4]) m4_include([macros/ltoptions.m4]) m4_include([macros/ltsugar.m4]) m4_include([macros/ltversion.m4]) m4_include([macros/lt~obsolete.m4]) m4_include([macros/perl.m4]) m4_include([macros/pkg.m4]) m4_include([macros/tcl.m4]) hamlib-4.6.2/README.betatester0000644000175000017500000003155414752216205012735 00000000000000Hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) (C) Stephane Fillod 2000-2011 (C) The Hamlib Group 2000-2013 Why does Hamlib need beta-testers? ================================== Hamlib is developed by a team of radio enthusiasts around the world, for fun, much in the spirit of ham radio. (Note that it is not restricted for ham usage only). There are a great deal of protocols and rigs around the world developers may not own. However, protocols may be available, so backends can be implemented, but cannot always be tested by developers. That's where beta-testers are so precious. On top of that, I've been told that there's no such sure thing like bug free code. Feedback and improvement requests are also valuable. Okay, you volunteer as beta-tester, how to proceed? =================================================== First of all, you can start testing official releases. They are easier to test because they come in precompiled and packaged (.rpm, .deb, etc.) but they have the drawback of being older than the Git repository. Reports from these versions are still very appreciated. Please send them to the hamlib-developer@lists.sourceforge.net mailing list. However, the development of Hamlib is still very active, so it's better to test from the latest Git version of the code. And, depending on feedback you make, developers can commit a fix, so you can try out the change soon after, without waiting for the next official version. To proceed, you will have first to obtain either a daily snapshot or a check out the latest sources from the Git repository, then rebuild the Hamlib package and finally test it with your rig. Don't worry, it's much simpler than it looks, despite the size of the package. Pre-requisite: - some kind of internet access - POSIXish compiler toolchain (gcc, make, C library development headers, etc., see README.developer for a complete list and building from a Git checkout) So here we go: Daily Git master branch snapshots: ================================== Download the latest Git master branch snapshot from: http://n0nb.users.sourceforge.net You'll find a tarball with a name like hamlib-3.0~git-30e58df-20121009.tar.gz, i.e. a check out made 09 Oct 2012 With a Git SHA1 of 30e58df (The SHA1 is a signature of each commit. Each is unique and as our project is small, the first seven characters for the full 40 character SHA1 are likely unique. The shorthand SHA1 is automatically generated and may become longer in the future.), ready for building using the familiar "three step" (see below). Each morning by about 1130z a new snapshot is generated and uploaded and the prior day's version is removed. The advantage of the Git snapshot is that you won't need as many tools installed to build Hamlib as the work of the GNU Build System has already been done. Most of the other packages listed below will be needed. If you tell the 'configure' script to build certain parts of Hamlib like documentation or scripting language bindings the relevant optional packages will be needed. See 'configure --help' for more information. Here is a list of development packages needed for a complete build of the library (Debian package names are listed, other distributions may differ): * Gnu C (gcc) or any C99 compliant compiler # gcc --version * Gnu make (or any modern one, BSD okay) # make --version N.B. The Debian and derivatives (Ubuntu and friends) 'build-essentials' package will install a number of tools and minimize the number of packages that need to be installed manually. Optional, but highly recommended for a complete build: * GNU C++ (g++) # g++ --version * swig (for bindings) 1.3.14+ # swig -version * perl devel # h2xs * tcl devel # tcltk-depends * python devel # python-config * zlib devel # Needed by configure's test for Python * libxml2 devel # xml2-config --version * libgd2 devel # gdlib-config --version * libusb-1.0 devel # ver 1.0 or newer (not 0.1!) * libreadline devel # ver 5.2 or newer N.B The libusb package is required for building most of the 'kit' backend. The newer version is needed, not 0.1. Debian and derivatives package libusb-1.0 which is what is needed. Documentation: * Doxygen Git master branch daily snapshot build: ======================================= Reading the INSTALL file in top directory will explain in more detail how to do the following commands. ./configure [--prefix=$HOME/local] make make check make install The prefix argument is optional. Convention is that local packages be placed in /usr/local away from distribution installed packages This is the default location for the snapshots so it may be disregarded unless you wish to install Hamlib elsewhere. The example above would install Hamlib to the user's home directory under the 'local' subdirectory. Other useful options are '--with-perl-binding' or '--with-python-binding' or '--with-tcl-binding' if you are interested in Swig binding support for those scripting languages If you are unsure it is safe to ignore these options. 'make' will run the C and, optionally, the C++ compiler building all of the binary object files and finally linking all of them together to form the Hamlib "frontend" and "backend" libraries. The 'make check' target will run a few predetermined tests using the 'dummy' (rig model 1) backend and some other Hamlib functions in the build tree. This is a basic sanity check and cannot test all backends. The 'make install' target will require super user (root/administrator) privileges when installing to the system directories as a normal user. Some Linux distributions offer the 'sudo' command to grant temporary root privileges or the 'su' command to login as "root". Consult your distribution's documentation. NOTE! If Hamlib has not been previously installed as a locally built package you will need to make sure that 'ldconfig' is configured correctly and run after 'make install'. Most modern distributions have an /etc/ld.so.conf.d/ directory where local configuration can be made. Later versions of Debian and derivatives have a file named 'libc.conf' in this directory. The contents of libc.conf are: # libc default configuration /usr/local/lib If your system does not have such a file, one will need to be created and then 'ldconfig' will need to be run as the root user so that applications using the Hamlib libraries can find them. To delete the binary files from the source directory after compiling: make clean To also remove the Makefiles and other build files generated by 'configure', along with the binary files as with 'make clean' above: make distclean The 'configure' script will need to be run again as above. The above commands will clean things up so Hamlib can be compiled with other configure script options. To remove Hamlib from your system: sudo make uninstall Note that due to a limitation in a Perl support script that if the Perl binding is built and installed that not all of the files under /usr/local/lib/perl/PERL_VERSION will not be removed. Git checkout: ============= Please read the beginning of README.developer file, especially Section 1 which details the Git checkout, the required tools and versions (very important or make won't even work!), and how to use the bootstrap script. Structure: ========== For the brave who want to peruse the contents, here are what all the subdirectories are for (these are just a sample as more are added from time to time): rigs: rig backends rotors: rotator backends rigs/dummy: virtual dummy rig and rotator and other non-rig devices, for testing use. lib: library for functions missing on your system bindings Perl, Python, Tcl, and Visual Basic bindings c++: C++ bindings doc: documentation base and scripts to extract from src include/hamlib: exported header files go here include: non-distributed header files go there src: Hamlib frontend source directory tests: rigctl/rotctl and various C programs for testing Testing Hamlib: =============== Don't attempt to test Hamlib from the source directory unless you're a developer and you understand the side effects of *not* installing freshly generated objects (basically having to mess with LD_LIBRARY_PATH and .libs). Do an 'sudo make install' to install the libraries in the system area. (You did run 'sudo ldconfig' after 'sudo make install', right?) So here we go. First of all, identify your rig model id. Make sure /usr/local/bin (or the path you set --prefix to above) is in your $PATH, as your shell has to be able to locate rigctl. Run 'rigctl -l' to get a list of rigs supported by Hamlib. If you cannot find your radio in the list, please report to the hamlib-developer mailing list. The protocol manual and rig specifications will help us a lot. You found your rig's ID? Good! You're almost ready to use rigctl. Have a quick look at its manual page: man rigctl or: man -M /usr/local/man rigctl or simply: rigctl --help Let's say you own an Icom IC-756: rigctl -vvvvv -r /dev/ttyS0 -m 326 The -vvvvv is very important since this will increase verbosity, and give precious traces to developers if something goes wrong. At this level, the protocol data exchanged will also be dumped to the screen. Some backends produce a useful amount of data regarding function calls and critical variables with the -vvvv option without all the protocol data. Unless some problem shows up, you should be presented with a menu like "Rig command: ". Enter "?" followed by return to have the list of available commands. 'Q' or 'q' quits rigctl immediately. Most wanted functions to be tested are: '_' get misc information on the rig 'f' get frequency 'F' set frequency, in Hz 'm' get mode 'M' set mode (AM,FM,CW,USB,etc. and passband width in Hz) 'v' get vfo 'V' set vfo (VFOA, VFOB, etc.) f,F get_freq/set_freq try various (<1MHz, <30Mhz and >1GHz) v,V get_vfo/set_vfo VFOA, VFOB m,M get_mode/set_mode FM, USB, LSB, CW, WFM, etc. passband is in Hz (pass 0 for default) G vfo_op UP, DOWN _ get_info should give remote Id and firmware vers NB: some functions may not be implemented in the backend or simply not available on this rig. When reporting to the hamlib-developer mailing list, please include traces and also comments to tell developers if the action performed correctly on the rig. Tip: Traces can be hard to cut and paste sometimes. In that case, there's a handy tool for you: script(1) (the (1) is not a part of the command, rather it is a Unix convention telling which section of the manual it is found, in this case section 1, user commands. e.g. 'man 1 script'). It will make a typescript of everything printed on your terminal and save it to the file you give it. $ script my_rig_traces.txt Script started, file is my_rig_traces.txt $ rigctl -vvvvv -r /dev/ttyS0 -m 326 rig:rig_init called rig: loading backend icom icom: _init called rig_register (309) rig_register (326) rig:rig_open called Opened rig model 326, 'IC-756' Rig command: q rig:rig_close called rig:rig_cleanup called $ exit exit Script done, file is my_rig_traces.txt $ And then send my_rig_traces.txt to the hamlib-developer mailing list. Some models need S-meter calibration, because the rig only returns raw measurement. It's easy, it takes only 10mn. Here's how to proceed: 1. Fire up the rigctl program released with the Hamlib package, and pass along options as needed (serial speed, etc.). 2. Tune to some frequency reporting S0 to the radio S-Meter. 3. At rigctl prompt, issue "get_level" ('l' in short) of the level RAWSTR. 4. Write down the S-level read on radio front panel, and the RAWSTR value retrieved. 5. Repeat from step 2 with S9 and S9+60dB. Actually the more plots, the better, otherwise Hamlib does interpolation. 6. Send the table to the hamlib-developer mailing list and it will be added in the next release of Hamlib. NB: It is well known the S-Meter of any given radio is far from being accurate. For owners with a fully equipped lab, you may want to make the above-mentioned measurements with a good signal generator and a set of calibrated attenuators. Greg W8WWV has an insightful page about S-Meter calibration: http://www.seed-solutions.com/gregordy/Amateur%20Radio/Experimentation/SMeterBlues.htm Okay folks, test as much as you can, in the weirdest situations if possible. There is a special prize for those who find 'Segmentation fault' and other nasty bugs. Needless to say, patches are also very welcome (see README.developer). :-) Stephane - F8CFE and The Hamlib Group hamlib-4.6.2/Makefile.am0000644000175000017500000000175014752216205011743 00000000000000## Process this file with automake to produce Makefile.in aclocaldir = $(datadir)/aclocal aclocal_DATA = hamlib.m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = hamlib.pc EXTRA_DIST = PLAN LICENSE hamlib.m4 hamlib.pc.in README.md README.developer \ README.betatester README.freqranges README.multicast README.osx \ Android.mk doc_DATA = ChangeLog COPYING COPYING.LIB LICENSE \ README.md README.betatester README.developer SUBDIRS = macros include lib security \ $(BACKEND_LIST) \ $(RIG_BACKEND_LIST) \ $(ROT_BACKEND_LIST) \ $(AMP_BACKEND_LIST) \ security \ src \ $(BINDINGS) \ tests doc ## Static list of distributed directories. DIST_SUBDIRS = macros include lib src c++ bindings tests doc android scripts rotators/indi simulators\ security $(BACKEND_LIST) $(RIG_BACKEND_LIST) $(ROT_BACKEND_LIST) $(AMP_BACKEND_LIST) # Install any third party macros into our tree for distribution ACLOCAL_AMFLAGS = -I macros --install AM_CFLAGS=-D_TIME_BITS=64 -Winitializer-overrides hamlib-4.6.2/rigs/0000755000175000017500000000000014752216245010734 500000000000000hamlib-4.6.2/rigs/dummy/0000755000175000017500000000000014752216242012064 500000000000000hamlib-4.6.2/rigs/dummy/rot_dummy.c0000644000175000017500000005543314752216205014200 00000000000000/* * Hamlib Dummy backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include #include "hamlib/rotator.h" #include "dummy_common.h" #include "rig.h" #include "register.h" #include "idx_builtin.h" #include "rot_dummy.h" #include "rot_pstrotator.h" #include "rotlist.h" #define DUMMY_ROT_FUNC 0 #define DUMMY_ROT_LEVEL ROT_LEVEL_SPEED #define DUMMY_ROT_PARM 0 #define DUMMY_ROT_STATUS (ROT_STATUS_MOVING | ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT | \ ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN | \ ROT_STATUS_LIMIT_UP | ROT_STATUS_LIMIT_DOWN | ROT_STATUS_LIMIT_LEFT | ROT_STATUS_LIMIT_RIGHT) static int simulating = 0; // do we need rotator emulation for debug? struct dummy_rot_priv_data { azimuth_t az; elevation_t el; struct timeval tv; /* time last az/el update */ azimuth_t target_az; elevation_t target_el; rot_status_t status; setting_t funcs; value_t levels[RIG_SETTING_MAX]; value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_funcs; struct ext_list *ext_levels; struct ext_list *ext_parms; char *magic_conf; }; static const struct confparams dummy_ext_levels[] = { { TOK_EL_ROT_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { TOK_EL_ROT_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { TOK_EL_ROT_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", NULL, RIG_CONF_BUTTON }, { TOK_EL_ROT_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } }, { RIG_CONF_END, NULL, } }; static const struct confparams dummy_ext_funcs[] = { { TOK_EL_ROT_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; static const struct confparams dummy_ext_parms[] = { { TOK_EP_ROT_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { RIG_CONF_END, NULL, } }; /* cfgparams are configuration item generally used by the backend's open() method */ static const struct confparams dummy_cfg_params[] = { { TOK_CFG_ROT_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", "ROTATOR", RIG_CONF_STRING, { } }, { RIG_CONF_END, NULL, } }; static int dummy_rot_init(ROT *rot) { struct dummy_rot_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ROTSTATE(rot)->priv = (struct dummy_rot_priv_data *) calloc(1, sizeof(struct dummy_rot_priv_data)); if (!ROTSTATE(rot)->priv) { return -RIG_ENOMEM; } priv = ROTSTATE(rot)->priv; priv->ext_funcs = alloc_init_ext(dummy_ext_funcs); if (!priv->ext_funcs) { return -RIG_ENOMEM; } priv->ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->ext_levels) { return -RIG_ENOMEM; } priv->ext_parms = alloc_init_ext(dummy_ext_parms); if (!priv->ext_parms) { return -RIG_ENOMEM; } ROTPORT(rot)->type.rig = RIG_PORT_NONE; priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; priv->magic_conf = strdup("ROTATOR"); return RIG_OK; } static int dummy_rot_cleanup(ROT *rot) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); free(priv->ext_funcs); free(priv->ext_levels); free(priv->ext_parms); free(priv->magic_conf); free(ROTSTATE(rot)->priv); ROTSTATE(rot)->priv = NULL; return RIG_OK; } static int dummy_rot_open(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rot->caps->rot_model == ROT_MODEL_DUMMY) { simulating = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: dummy rotator so simulating speed\n", __func__); } return RIG_OK; } static int dummy_rot_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_set_conf(ROT *rot, hamlib_token_t token, const char *val) { struct dummy_rot_priv_data *priv; priv = (struct dummy_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: if (val) { free(priv->magic_conf); priv->magic_conf = strdup(val); } break; default: return -RIG_EINVAL; } return RIG_OK; } static int dummy_get_conf2(ROT *rot, hamlib_token_t token, char *val, int val_len) { struct dummy_rot_priv_data *priv; priv = (struct dummy_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: SNPRINTF(val, val_len, "%s", priv->magic_conf); break; default: return -RIG_EINVAL; } return RIG_OK; } static int dummy_get_conf(ROT *rot, hamlib_token_t token, char *val) { return dummy_get_conf2(rot, token, val, 128); } static int dummy_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); if (simulating) { priv->target_az = az; priv->target_el = el; gettimeofday(&priv->tv, NULL); } else { priv->az = priv->target_az = az; priv->el = priv->target_az = el; } return RIG_OK; } static void dummy_rot_simulate_rotation(ROT *rot) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; struct timeval tv; unsigned elapsed; /* ms */ gettimeofday(&tv, NULL); elapsed = (tv.tv_sec - priv->tv.tv_sec) * 1000 + (tv.tv_usec - priv->tv.tv_usec) / 1000; /* * Simulate rotation speed of 360 deg per minute */ #define DEG_PER_MS (360./60/1000) if (fabs(priv->target_az - priv->az) / DEG_PER_MS <= elapsed) { /* target reached */ priv->az = priv->target_az; priv->status &= ~(ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT); } else { if (priv->az < priv->target_az) { priv->az += (azimuth_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_RIGHT; } else { priv->az -= (azimuth_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT; } } if (fabs(priv->target_el - priv->el) / DEG_PER_MS <= elapsed) { /* target reached */ priv->el = priv->target_el; priv->status &= ~(ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN); } else { if (priv->el < priv->target_el) { priv->el += (elevation_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP; } else { priv->el -= (elevation_t)elapsed * DEG_PER_MS; priv->status |= ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_DOWN; } } if (priv->status & (ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_EL)) { priv->status |= ROT_STATUS_MOVING; } else { priv->status &= ~(ROT_STATUS_MOVING); } priv->tv = tv; } /* * Get position of rotor, simulating slow rotation */ static int dummy_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (simulating && priv->az == priv->target_az && priv->el == priv->target_el) { *az = priv->az; *el = priv->el; return RIG_OK; } if (simulating) { dummy_rot_simulate_rotation(rot); } *az = priv->az; *el = priv->el; return RIG_OK; } static int dummy_rot_stop(ROT *rot) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; azimuth_t az; elevation_t el; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); dummy_rot_get_position(rot, &az, &el); priv->target_az = priv->az = az; priv->target_el = priv->el = el; return RIG_OK; } static int dummy_rot_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Assume home is 0,0 */ dummy_rot_set_position(rot, 0, 0); return RIG_OK; } static int dummy_rot_reset(ROT *rot, rot_reset_t reset) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_rot_move(ROT *rot, int direction, int speed) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: Direction = %d, Speed = %d\n", __func__, direction, speed); switch (direction) { case ROT_MOVE_UP: return dummy_rot_set_position(rot, priv->target_az, 90); case ROT_MOVE_DOWN: return dummy_rot_set_position(rot, priv->target_az, 0); case ROT_MOVE_CCW: return dummy_rot_set_position(rot, -180, priv->target_el); case ROT_MOVE_CW: return dummy_rot_set_position(rot, 180, priv->target_el); case ROT_MOVE_UP_LEFT: dummy_rot_set_position(rot, priv->target_az, 90); return dummy_rot_set_position(rot, -180, priv->target_el); case ROT_MOVE_UP_RIGHT: dummy_rot_set_position(rot, priv->target_az, 90); return dummy_rot_set_position(rot, 180, priv->target_el); case ROT_MOVE_DOWN_LEFT: dummy_rot_set_position(rot, priv->target_az, 0); return dummy_rot_set_position(rot, -180, priv->target_el); case ROT_MOVE_DOWN_RIGHT: dummy_rot_set_position(rot, priv->target_az, 0); return dummy_rot_set_position(rot, 180, priv->target_el); default: return -RIG_EINVAL; } return RIG_OK; } static const char *dummy_rot_get_info(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "Dummy rotator"; } static int dummy_set_func(ROT *rot, setting_t func, int status) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, rot_strfunc(func), status); if (status) { priv->funcs |= func; } else { priv->funcs &= ~func; } return RIG_OK; } static int dummy_get_func(ROT *rot, setting_t func, int *status) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; *status = (priv->funcs & func) ? 1 : 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strfunc(func)); return RIG_OK; } static int dummy_set_level(ROT *rot, setting_t level, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; char lstr[32]; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } priv->levels[idx] = val; if (ROT_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rot_strlevel(level), lstr); return RIG_OK; } static int dummy_get_level(ROT *rot, setting_t level, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } *val = priv->levels[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rot_strlevel(level)); return RIG_OK; } static int dummy_set_ext_level(ROT *rot, hamlib_token_t token, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICLEVEL: case TOK_EL_ROT_MAGICFUNC: case TOK_EL_ROT_MAGICOP: case TOK_EL_ROT_MAGICCOMBO: break; default: return -RIG_EINVAL; } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: return -RIG_EINTERNAL; } elp = find_ext(priv->ext_levels, token); if (!elp) { return -RIG_EINTERNAL; } /* store value */ elp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); return RIG_OK; } static int dummy_get_ext_level(ROT *rot, hamlib_token_t token, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICLEVEL: case TOK_EL_ROT_MAGICFUNC: case TOK_EL_ROT_MAGICOP: case TOK_EL_ROT_MAGICCOMBO: break; default: return -RIG_EINVAL; } elp = find_ext(priv->ext_levels, token); if (!elp) { return -RIG_EINTERNAL; } /* load value */ *val = elp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } static int dummy_set_ext_func(ROT *rot, hamlib_token_t token, int status) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICEXTFUNC: break; default: return -RIG_EINVAL; } switch (cfp->type) { case RIG_CONF_CHECKBUTTON: break; case RIG_CONF_BUTTON: break; default: return -RIG_EINTERNAL; } elp = find_ext(priv->ext_funcs, token); if (!elp) { return -RIG_EINTERNAL; } /* store value */ elp->val.i = status; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, cfp->name, status); return RIG_OK; } static int dummy_get_ext_func(ROT *rot, hamlib_token_t token, int *status) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EL_ROT_MAGICEXTFUNC: break; default: return -RIG_EINVAL; } elp = find_ext(priv->ext_funcs, token); if (!elp) { return -RIG_EINTERNAL; } /* load value */ *status = elp->val.i; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } static int dummy_set_parm(ROT *rot, setting_t parm, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; char pstr[32]; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } if (ROT_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; return RIG_OK; } static int dummy_get_parm(ROT *rot, setting_t parm, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; int idx; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { return -RIG_EINVAL; } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); return RIG_OK; } static int dummy_set_ext_parm(ROT *rot, hamlib_token_t token, value_t val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EP_ROT_MAGICPARM: break; default: return -RIG_EINVAL; } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: return -RIG_EINTERNAL; } epp = find_ext(priv->ext_parms, token); if (!epp) { return -RIG_EINTERNAL; } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); return RIG_OK; } static int dummy_get_ext_parm(ROT *rot, hamlib_token_t token, value_t *val) { struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; const struct confparams *cfp; struct ext_list *epp; cfp = rot_ext_lookup_tok(rot, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case TOK_EP_ROT_MAGICPARM: break; default: return -RIG_EINVAL; } epp = find_ext(priv->ext_parms, token); if (!epp) { return -RIG_EINTERNAL; } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } static int dummy_rot_get_status(ROT *rot, rot_status_t *status) { const struct dummy_rot_priv_data *priv = (struct dummy_rot_priv_data *) ROTSTATE(rot)->priv; if (simulating) { dummy_rot_simulate_rotation(rot); } *status = priv->status; return RIG_OK; } /* * Dummy rotator capabilities. */ struct rot_caps dummy_rot_caps = { ROT_MODEL(ROT_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", .version = "20220531.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_NONE, .min_az = -180., .max_az = 450., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .has_get_func = DUMMY_ROT_FUNC, .has_set_func = DUMMY_ROT_FUNC, .has_get_level = DUMMY_ROT_LEVEL, .has_set_level = ROT_LEVEL_SET(DUMMY_ROT_LEVEL), .has_get_parm = DUMMY_ROT_PARM, .has_set_parm = ROT_PARM_SET(DUMMY_ROT_PARM), .level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .extlevels = dummy_ext_levels, .extfuncs = dummy_ext_funcs, .extparms = dummy_ext_parms, .cfgparams = dummy_cfg_params, .has_status = DUMMY_ROT_STATUS, .rot_init = dummy_rot_init, .rot_cleanup = dummy_rot_cleanup, .rot_open = dummy_rot_open, .rot_close = dummy_rot_close, .set_conf = dummy_set_conf, .get_conf = dummy_get_conf, .set_position = dummy_rot_set_position, .get_position = dummy_rot_get_position, .park = dummy_rot_park, .stop = dummy_rot_stop, .reset = dummy_rot_reset, .move = dummy_rot_move, .set_func = dummy_set_func, .get_func = dummy_get_func, .set_level = dummy_set_level, .get_level = dummy_get_level, .set_parm = dummy_set_parm, .get_parm = dummy_get_parm, .set_ext_func = dummy_set_ext_func, .get_ext_func = dummy_get_ext_func, .set_ext_level = dummy_set_ext_level, .get_ext_level = dummy_get_ext_level, .set_ext_parm = dummy_set_ext_parm, .get_ext_parm = dummy_get_ext_parm, .get_info = dummy_rot_get_info, .get_status = dummy_rot_get_status, }; DECLARE_INITROT_BACKEND(dummy) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&dummy_rot_caps); rot_register(&netrotctl_caps); rot_register(&pstrotator_caps); rot_register(&satrotctl_caps); return RIG_OK; } hamlib-4.6.2/rigs/dummy/sdrsharp.c0000644000175000017500000003214214752216205013777 00000000000000/* * Hamlib rigctld backend - works with SDR#'s gpredict plugin for example * Copyright (c) 2023 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define TRUE 1 #define FALSE 0 #define MAXCMDLEN 128 #define MAXXMLLEN 128 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:4532" #define SDRSHARP_VFOS (RIG_VFO_A) #define SDRSHARP_MODES (RIG_MODE_NONE) struct sdrsharp_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_set_bwA; /* True if this function is available */ float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /* * read_transaction * Assumes rig!=NULL, xml!=NULL, xml_len>=MAXXMLLEN */ static int read_transaction(RIG *rig, char *xml, int xml_len) { int retval; int retry; char *delims; char *terminator = "\n"; ENTERFUNC; retry = 2; delims = "\n"; xml[0] = 0; do { char tmp_buf[MAXXMLLEN]; // plenty big for expected sdrsharp responses hopefully if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } int len = read_string(RIGPORT(rig), (unsigned char *) tmp_buf, sizeof(tmp_buf), delims, strlen(delims), 0, 1); if (len > 0) { retry = 3; } if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } if (strlen(xml) + strlen(tmp_buf) < xml_len - 1) { strncat(xml, tmp_buf, xml_len - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: xml buffer overflow!!\nTrying to add len=%d\nTo len=%d\n", __func__, (int)strlen(tmp_buf), (int)strlen(xml)); RETURNFUNC(-RIG_EPROTO); } } while (retry-- > 0 && strstr(xml, terminator) == NULL); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (strstr(xml, terminator)) { // rig_debug(RIG_DEBUG_TRACE, "%s: got %s\n", __func__, terminator); retval = RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: did not get %s\n", __func__, terminator); retval = -(101 + RIG_EPROTO); } RETURNFUNC(retval); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, char *xml, int xml_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (xml_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, (unsigned char *) xml, strlen(xml)); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int sdrsharp_transaction(RIG *rig, char *cmd, char *value, int value_len) { char xml[MAXXMLLEN]; int retry = 3; ENTERFUNC; ELAPSED1; set_transaction_active(rig); if (value) { value[0] = 0; } do { int retval; if (retry != 3) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } retval = write_transaction(rig, cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { set_transaction_inactive(rig); RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } if (value) { read_transaction(rig, xml, sizeof(xml)); // this might time out -- that's OK strncpy(value, xml, value_len); } } while (((value && strlen(value) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no value returned\n", __func__); set_transaction_inactive(rig); RETURNFUNC(RIG_EPROTO); } ELAPSED2; set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } /* * sdrsharp_init * Assumes rig!=NULL */ static int sdrsharp_init(RIG *rig) { struct sdrsharp_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct sdrsharp_priv_data *)calloc(1, sizeof( struct sdrsharp_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct sdrsharp_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); RETURNFUNC(RIG_OK); } /* * sdrsharp_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int sdrsharp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char value[MAXARGLEN]; struct sdrsharp_priv_data *priv = (struct sdrsharp_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = "f\n"; int retval; retval = sdrsharp_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: READBMF failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } *freq = 0; sscanf(value, "%lf", freq); if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else // future support in SDRSHARP maybe? { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * sdrsharp_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int sdrsharp_open(RIG *rig) { int retval; char value[MAXARGLEN]; ENTERFUNC; value[0] = '?'; value[1] = 0; freq_t freq; retval = sdrsharp_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: sdrsharp_get_freq not working!!\n", __func__); RETURNFUNC(RIG_EPROTO); } STATE(rig)->current_vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo), value); RETURNFUNC(retval); } /* * sdrsharp_close * Assumes rig!=NULL */ static int sdrsharp_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * sdrsharp_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int sdrsharp_cleanup(RIG *rig) { struct sdrsharp_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (!rig) { RETURNFUNC2(-RIG_EINVAL); } priv = (struct sdrsharp_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; // we really don't need to free this up as it's only done once // was causing problem when cleanup was followed by rig_open // model_sdrsharp was not getting refilled // if we can figure out that one we can re-enable this #if 0 int i; for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_sdrsharp) { free(modeMap[i].mode_sdrsharp); modeMap[i].mode_sdrsharp = NULL; modeMap[i].mode_hamlib = 0; } } #endif RETURNFUNC2(RIG_OK); } /* * sdrsharp_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int sdrsharp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd[MAXARGLEN]; char value[1024]; //struct sdrsharp_priv_data *priv = (struct sdrsharp_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } #if 0 if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } #endif SNPRINTF(cmd, sizeof(cmd), "F %.0lf\n", freq); retval = sdrsharp_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(value, "RPRT %d", &retval); RETURNFUNC2(retval); } /* * sdrsharp_get_vfo * assumes rig!=NULL, vfo != NULL */ static int sdrsharp_get_vfo(RIG *rig, vfo_t *vfo) { ENTERFUNC; *vfo = RIG_VFO_A; RETURNFUNC(RIG_OK); } struct rig_caps sdrsharp_caps = { RIG_MODEL(RIG_MODEL_SDRSHARP), .model_name = "SDR#/gpredict", .mfg_name = "Airspy", .version = "20230127.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, //.targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 2, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = SDRSHARP_MODES, .low_power = -1, .high_power = -1, SDRSHARP_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = SDRSHARP_MODES, .low_power = -1, .high_power = -1, SDRSHARP_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {SDRSHARP_MODES, 1}, {SDRSHARP_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .rig_init = sdrsharp_init, .rig_open = sdrsharp_open, .rig_close = sdrsharp_close, .rig_cleanup = sdrsharp_cleanup, .get_vfo = sdrsharp_get_vfo, .set_freq = sdrsharp_set_freq, .get_freq = sdrsharp_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/dummy/dummy_common.h0000644000175000017500000000211414752216205014655 00000000000000/* * Hamlib Dummy backend - shared routines * Copyright (c) 2020 by Mikael Nousiainen * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DUMMY_COMMON_H #define _DUMMY_COMMON_H 1 #include "hamlib/rig.h" struct ext_list *alloc_init_ext(const struct confparams *cfp); struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token); #endif /* _DUMMY_H */ hamlib-4.6.2/rigs/dummy/Makefile.am0000644000175000017500000000054714752216205014045 00000000000000DUMMYSRC = dummy_common.c dummy_common.h dummy.c dummy.h rot_dummy.c rot_dummy.h rot_pstrotator.c rot_pstrotator.h netrigctl.c netrotctl.c flrig.c flrig.h trxmanager.c trxmanager.h amp_dummy.c amp_dummy.h netampctl.c tci1x.c aclog.c sdrsharp.c quisk.c noinst_LTLIBRARIES = libhamlib-dummy.la libhamlib_dummy_la_SOURCES = $(DUMMYSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/dummy/netrigctl.c0000644000175000017500000021305314752216205014146 00000000000000/* * Hamlib Netrigctl backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "iofunc.h" #include "misc.h" #include "num_stdio.h" #include "dummy.h" #define CMD_MAX 64 #define BUF_MAX 1024 #define CHKSCN1ARG(a) if ((a) != 1) return -RIG_EPROTO; else do {} while(0) struct netrigctl_priv_data { vfo_t vfo_curr; int rigctld_vfo_mode; vfo_t rx_vfo; vfo_t tx_vfo; }; int netrigctl_get_vfo_mode(RIG *rig) { struct netrigctl_priv_data *priv; priv = (struct netrigctl_priv_data *)STATE(rig)->priv; return priv->rigctld_vfo_mode; } /* * Helper function with protocol return code parsing */ static int netrigctl_transaction(RIG *rig, char *cmd, int len, char *buf) { int ret; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called len=%d\n", __func__, len); /* flush anything in the read buffer before command is sent */ rig_flush(rp); ret = write_block(rp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret < 0) { return ret; } if (strncmp(buf, NETRIGCTL_RET, strlen(NETRIGCTL_RET)) == 0) { return atoi(buf + strlen(NETRIGCTL_RET)); } return ret; } /* this will fill vfostr with the vfo value if the vfo mode is enabled * otherwise string will be null terminated * this allows us to use the string in snprintf in either mode */ static int netrigctl_vfostr(RIG *rig, char *vfostr, int len, vfo_t vfo) { struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); if (len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: len must be >=5, len=%d\n", __func__, len); return -RIG_EPROTO; } vfostr[0] = 0; priv = (struct netrigctl_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo==RIG_VFO_CURR, curr=%s\n", __func__, rig_strvfo(priv->vfo_curr)); vfo = priv->vfo_curr; if (vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; } } else if (vfo == RIG_VFO_RX) { vfo = priv->rx_vfo; } else if (vfo == RIG_VFO_TX) { vfo = priv->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt=%d\n", __func__, STATE(rig)->vfo_opt); if (STATE(rig)->vfo_opt || priv->rigctld_vfo_mode) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt vfo=%u\n", __func__, vfo); char *myvfo; switch (vfo) { case RIG_VFO_B: myvfo = "VFOB"; break; case RIG_VFO_C: myvfo = "VFOC"; break; case RIG_VFO_MAIN: myvfo = "Main"; break; case RIG_VFO_MAIN_A: myvfo = "MainA"; break; case RIG_VFO_MAIN_B: myvfo = "MainB"; break; case RIG_VFO_SUB: myvfo = "Sub"; break; case RIG_VFO_SUB_A: myvfo = "SubA"; break; case RIG_VFO_SUB_B: myvfo = "SubB"; break; case RIG_VFO_MEM: myvfo = "MEM"; break; default: myvfo = "VFOA"; } SNPRINTF(vfostr, len, " %s", myvfo); } return RIG_OK; } static int netrigctl_init(RIG *rig) { // cppcheck says leak here but it's freed in cleanup struct netrigctl_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct netrigctl_priv_data *)calloc(1, sizeof( struct netrigctl_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct netrigctl_priv_data)); rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); /* * set arbitrary initial status * VFO will be updated in open call */ priv->vfo_curr = RIG_VFO_A; priv->rigctld_vfo_mode = 0; return RIG_OK; } static int netrigctl_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int parse_array_int(const char *s, const char *delim, int *array, int array_len) { char *p; char *dup = strdup(s); char *rest = dup; int n = 0; while ((p = strtok_r(rest, delim, &rest))) { if (n == array_len) // too many items { return n; } array[n] = atoi(p); //printf("%d\n", array[n]); ++n; } free(dup); return n; } int parse_array_double(const char *s, const char *delim, double *array, int array_len) { char *p; char *dup = strdup(s); char *rest = dup; int n = 0; while ((p = strtok_r(rest, delim, &rest))) { if (n == array_len) // too many items { return n; } array[n] = atof(p); //printf("%f\n", array[n]); ++n; } free(dup); return n; } static int netrigctl_open(RIG *rig) { int ret, i; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); int prot_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct netrigctl_priv_data *priv; ENTERFUNC; priv = (struct netrigctl_priv_data *)STATE(rig)->priv; priv->rx_vfo = RIG_VFO_A; priv->tx_vfo = RIG_VFO_B; SNPRINTF(cmd, sizeof(cmd), "\\chk_vfo\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (sscanf(buf, "%d", &priv->rigctld_vfo_mode) == 1) { STATE(rig)->vfo_opt = priv->rigctld_vfo_mode; rig_debug(RIG_DEBUG_TRACE, "%s: chkvfo=%d\n", __func__, priv->rigctld_vfo_mode); } else if (ret == 2) { if (buf[0]) { sscanf(buf, "%d", &priv->rigctld_vfo_mode); } } else if (ret < 0) { rig_debug(RIG_DEBUG_WARN, "%s: chk_vfo error: %s\n", __func__, rigerror(ret)); } else { rig_debug(RIG_DEBUG_ERR, "%s: unknown value returned from netrigctl_transaction=%d\n", __func__, ret); } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo_mode=%d\n", __func__, priv->rigctld_vfo_mode); SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } prot_ver = atoi(buf); #define RIGCTLD_PROT_VER 0 if (prot_ver < RIGCTLD_PROT_VER) { RETURNFUNC(-RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->deprecated_itu_region = atoi(buf); for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &(rs->rx_range_list[i].startf), &(rs->rx_range_list[i].endf), &(rs->rx_range_list[i].modes), &(rs->rx_range_list[i].low_power), &(rs->rx_range_list[i].high_power), &(rs->rx_range_list[i].vfo), &(rs->rx_range_list[i].ant) ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->rx_range_list[i])) { break; } } for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &rs->tx_range_list[i].startf, &rs->tx_range_list[i].endf, &rs->tx_range_list[i].modes, &rs->tx_range_list[i].low_power, &rs->tx_range_list[i].high_power, &rs->tx_range_list[i].vfo, &rs->tx_range_list[i].ant ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->tx_range_list[i])) { break; } switch (i) { } rig->caps->tx_range_list1->startf = rs->tx_range_list[i].startf; rig->caps->tx_range_list1->endf = rs->tx_range_list[i].endf; rig->caps->tx_range_list1->modes = rs->tx_range_list[i].modes; rig->caps->tx_range_list1->low_power = rs->tx_range_list[i].low_power; rig->caps->tx_range_list1->high_power = rs->tx_range_list[i].high_power; rig->caps->tx_range_list1->vfo = rs->tx_range_list[i].vfo; rig->caps->tx_range_list1->ant = rs->tx_range_list[i].ant; } for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->tuning_steps[i].modes, &rs->tuning_steps[i].ts); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_TS_END(rs->tuning_steps[i])) { break; } } for (i = 0; i < HAMLIB_FLTLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->filters[i].modes, &rs->filters[i].width); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FLT_END(rs->filters[i])) { break; } } #if 0 /* TODO */ chan_t chan_list[HAMLIB_CHANLSTSIZ]; /*!< Channel list, zero ended */ #endif ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_rit = rs->max_rit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_xit = rs->max_xit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_ifshift = rs->max_ifshift = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->announces = atoi(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->preamp[0], &rs->preamp[1], &rs->preamp[2], &rs->preamp[3], &rs->preamp[4], &rs->preamp[5], &rs->preamp[6]); rig->caps->preamp[0] = rs->preamp[0]; rig->caps->preamp[1] = rs->preamp[1]; rig->caps->preamp[2] = rs->preamp[2]; rig->caps->preamp[3] = rs->preamp[3]; rig->caps->preamp[4] = rs->preamp[4]; rig->caps->preamp[5] = rs->preamp[5]; rig->caps->preamp[6] = rs->preamp[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->preamp[ret] = rs->preamp[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->attenuator[0], &rs->attenuator[1], &rs->attenuator[2], &rs->attenuator[3], &rs->attenuator[4], &rs->attenuator[5], &rs->attenuator[6]); rig->caps->attenuator[0] = rs->attenuator[0]; rig->caps->attenuator[1] = rs->attenuator[1]; rig->caps->attenuator[2] = rs->attenuator[2]; rig->caps->attenuator[3] = rs->attenuator[3]; rig->caps->attenuator[4] = rs->attenuator[4]; rig->caps->attenuator[5] = rs->attenuator[5]; rig->caps->attenuator[6] = rs->attenuator[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->attenuator[ret] = rs->attenuator[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_func = rs->has_get_func = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_func = rs->has_set_func = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_level = rs->has_get_level = strtoll(buf, NULL, 0); #if 0 // don't think we need this anymore if (rs->has_get_level & RIG_LEVEL_RAWSTR) { /* include STRENGTH because the remote rig may be able to provide a front end emulation, if it can't then an -RIG_EINVAL will be returned */ rs->has_get_level |= RIG_LEVEL_STRENGTH; rig->caps->has_get_level |= RIG_LEVEL_STRENGTH; } #endif ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_level = rs->has_set_level = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->has_get_parm = strtoll(buf, NULL, 0); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_parm = rs->has_set_parm = strtoll(buf, NULL, 0); for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->rx_range_list[i]); i++) { rs->mode_list |= rs->rx_range_list[i].modes; rs->vfo_list |= rs->rx_range_list[i].vfo; } for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->tx_range_list[i]); i++) { rs->mode_list |= rs->tx_range_list[i].modes; rs->vfo_list |= rs->tx_range_list[i].vfo; } if (rs->vfo_list == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo_list empty, defaulting to A/B\n", __func__); rs->vfo_list = RIG_VFO_A | RIG_VFO_B; } if (prot_ver == 0) { RETURNFUNC(RIG_OK); } // otherwise we continue reading protocol 1 fields do { char setting[32], value[1024]; hamlib_port_t *pttp = PTTPORT(rig); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); strtok(buf, "\r\n"); // chop the EOL rig_debug(RIG_DEBUG_VERBOSE, "## %s\n", buf); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } if (strncmp(buf, "done", 4) == 0) { RETURNFUNC(RIG_OK); } if (sscanf(buf, "%31[^=]=%1023[^\t\n]", setting, value) == 2) { if (strcmp(setting, "vfo_ops") == 0) { rig->caps->vfo_ops = STATE(rig)->vfo_ops = strtoll(value, NULL, 0); rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, rig->caps->vfo_ops); } else if (strcmp(setting, "ptt_type") == 0) { ptt_type_t temp = (ptt_type_t)strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type='%s'(%d)\n", __func__, value, temp); if (RIG_PTT_RIG_MICDATA == pttp->type.ptt || temp == RIG_PTT_RIG_MICDATA) { /* * remote PTT must always be RIG_PTT_RIG_MICDATA * if there is any PTT capability and we have not * locally overridden it */ pttp->type.ptt = RIG_PTT_RIG_MICDATA; rig->caps->ptt_type = STATE(rig)->ptt_type = RIG_PTT_RIG_MICDATA; rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, pttp->type.ptt); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type= %d\n", __func__, temp); pttp->type.ptt = temp; rig->caps->ptt_type = STATE(rig)->ptt_type = temp; } } else if (strcmp(setting, "targetable_vfo") == 0) { rig->caps->targetable_vfo = STATE(rig)->targetable_vfo = strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: targetable_vfo=0x%2x\n", __func__, rig->caps->targetable_vfo); } else if (strcmp(setting, "has_set_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_vfo = NULL; } } else if (strcmp(setting, "has_get_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_vfo = NULL; } } else if (strcmp(setting, "has_set_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_freq = NULL; } } else if (strcmp(setting, "has_get_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_freq = NULL; } } else if (strcmp(setting, "has_set_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_conf = NULL; } } else if (strcmp(setting, "has_get_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_conf = NULL; } } else if (strcmp(setting, "has_get_ant") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_ant = NULL; } } else if (strcmp(setting, "has_set_ant") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_ant = NULL; } } #if 0 // for the future else if (strcmp(setting, "has_set_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_trn = NULL; } } else if (strcmp(setting, "has_get_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_trn = NULL; } } #endif else if (strcmp(setting, "has_power2mW") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->power2mW = NULL; } } else if (strcmp(setting, "has_mW2power") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->mW2power = NULL; } } else if (strcmp(setting, "timeout") == 0) { // use the rig's timeout value plus 500ms for potential network delays rig->caps->timeout = strtol(value, NULL, 0) + 500; rig_debug(RIG_DEBUG_TRACE, "%s: timeout value = '%s', final timeout=%d\n", __func__, value, rig->caps->timeout); } else if (strcmp(setting, "rig_model") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rig_model=%s\n", __func__, value); } else if (strcmp(setting, "rigctld_version") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rigctld_version=%s\n", __func__, value); } else if (strcmp(setting, "ctcss_list") == 0) { int n; double ctcss[CTCSS_LIST_SIZE]; rig->caps->ctcss_list = calloc(CTCSS_LIST_SIZE, sizeof(tone_t)); n = parse_array_double(value, " \n\r", ctcss, CTCSS_LIST_SIZE); for (i = 0; i < CTCSS_LIST_SIZE && ctcss[i] != 0; ++i) { rig->caps->ctcss_list[i] = ctcss[i] * 10; } if (n < CTCSS_LIST_SIZE) { rig->caps->ctcss_list[n] = 0; } } else if (strcmp(setting, "dcs_list") == 0) { int n; int dcs[DCS_LIST_SIZE + 1]; rig->caps->dcs_list = calloc(DCS_LIST_SIZE, sizeof(tone_t)); n = parse_array_int(value, " \n\r", dcs, DCS_LIST_SIZE); for (i = 0; i < DCS_LIST_SIZE && dcs[i] != 0; i++) { rig->caps->dcs_list[i] = dcs[i]; } if (n < DCS_LIST_SIZE) { rig->caps->dcs_list[n] = 0; } } else if (strcmp(setting, "agc_levels") == 0) { char *p = strtok(value, " "); rig->caps->agc_levels[0] = RIG_AGC_NONE; // default value gets overwritten rig->caps->agc_level_count = 0; while (p) { int agc_code; char agc_string[32]; int n = sscanf(p, "%d=%31s\n", &agc_code, agc_string); if (n == 2) { rig->caps->agc_levels[i++] = agc_code; rig->caps->agc_level_count++; rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has agc code=%d, level=%s\n", __func__, agc_code, agc_string); } else { rig_debug(RIG_DEBUG_ERR, "%s did not parse code=agc from '%s'\n", __func__, p); } rig_debug(RIG_DEBUG_VERBOSE, "%d=%s\n", agc_code, agc_string); p = strtok(NULL, " "); } } else if (strcmp(setting, "level_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int level; sscanf(p, "%d", &level); if (RIG_LEVEL_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &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); 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, ";"); } } else if (strcmp(setting, "parm_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int level; sscanf(p, "%d", &level); rig->caps->parm_gran[i].step.s = 0; if (RIG_PARM_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &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 if (RIG_PARM_IS_STRING(level)) { rig->caps->parm_gran[i].step.s = strdup(value); } else // must be INT { int min, max, step; sscanf(p, "%*d=%d,%d,%d", &min, &max, &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, ";"); } } else if (strcmp(setting, "hamlib_version") == 0) { printf("rigctld: %s\n", value); } else { // not an error -- just a warning for backward compatibility rig_debug(RIG_DEBUG_ERR, "%s: unknown setting='%s'\n", __func__, buf); } } else { rig_debug(RIG_DEBUG_ERR, "%s: invalid dumpcaps line, expected 'setting=value', got '%s'\n", __func__, buf); } } while (1); if (rs->auto_power_on) { rig_set_powerstat(rig, 1); } RETURNFUNC(RIG_OK); } static int netrigctl_close(RIG *rig) { const struct rig_state *rs = STATE(rig); int ret; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rs->auto_power_off && rs->comm_state) { rig_set_powerstat(rig, 0); } ret = netrigctl_transaction(rig, "q\n", 2, buf); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: close error %s\n", __func__, rigerror(ret)); return ret; } rig_debug(RIG_DEBUG_ERR, "%s: done\n", __func__); usleep(10 * 1000); return RIG_OK; } static int netrigctl_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); #if 1 // implement set_freq VFO later if it can be detected ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "F%s %"FREQFMT"\n", vfostr, freq); #else SNPRINTF(cmd, sizeof(cmd), "F %"FREQFMT"\n", freq); #endif ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s\n", __func__, strtok(cmd, "\r\n")); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; #if 0 // disable until we figure out if we can do this without breaking backwards compatibility char vfotmp[16]; #endif rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "f%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s, reply=%s\n", __func__, strtok(cmd, "\r\n"), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, freq)); #if 0 // implement set_freq VFO later if it can be detected ret = read_string(RIGPORT(rig), buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *vfotmp = rig_parse_vfo(buf); #endif return RIG_OK; } static int netrigctl_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "M%s %s %li\n", vfostr, rig_strrmode(mode), width); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "m%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *width = atoi(buf); return RIG_OK; } static int netrigctl_set_vfo(RIG *rig, vfo_t vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct netrigctl_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "V %s\n", rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd='%s'\n", __func__, cmd); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } priv->vfo_curr = vfo; // remember our vfo STATE(rig)->current_vfo = vfo; return ret; } static int netrigctl_get_vfo(RIG *rig, vfo_t *vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct netrigctl_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "v\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret == -RIG_ENAVAIL || ret == -RIG_ENIMPL) { // for rigs without get_vfo we'll use our saved vfo *vfo = priv->vfo_curr; return RIG_OK; } if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *vfo = rig_parse_vfo(buf); priv->vfo_curr = *vfo; return RIG_OK; } static int netrigctl_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; hamlib_port_t *pttp = PTTPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, ptt=%d, ptt_type=%d\n", __func__, rig_strvfo(vfo), ptt, pttp->type.ptt); if (pttp->type.ptt == RIG_PTT_NONE) { return RIG_OK; } ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "T%s %d\n", vfostr, ptt); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s", __func__, cmd); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "t%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ptt = atoi(buf); return RIG_OK; } static int netrigctl_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcd%s\n", vfostr); /* FIXME */ ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *dcd = atoi(buf); return RIG_OK; } static int netrigctl_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "R%s %s\n", vfostr, rig_strptrshift(rptr_shift)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "r%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *rptr_shift = rig_parse_rptr_shift(buf); return RIG_OK; } static int netrigctl_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "O%s %ld\n", vfostr, rptr_offs); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "o%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rptr_offs = atoi(buf); return RIG_OK; } static int netrigctl_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "C%s %u\n", vfostr, tone); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "c%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int netrigctl_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "D%s %u\n", vfostr, code); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "d%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int netrigctl_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_ctcss_sql%s %u\n", vfostr, tone); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_ctcss_sql%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int netrigctl_set_dcs_sql(RIG *rig, vfo_t vfo, unsigned int code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_dcs_sql%s %u\n", vfostr, code); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_dcs_sql(RIG *rig, vfo_t vfo, unsigned int *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcs_sql%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int netrigctl_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "I%s %"FREQFMT"\n", vfostr, tx_freq); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "i%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, tx_freq)); return RIG_OK; } static int netrigctl_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "X%s %s %li\n", vfostr, rig_strrmode(tx_mode), tx_width); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "x%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tx_width = atoi(buf); return RIG_OK; } static int netrigctl_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, vfotx=%s, split=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo), split); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "S%s %d %s\n", vfostr, split, rig_strvfo(tx_vfo)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "s%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *split = atoi(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_vfo = rig_parse_vfo(buf); return RIG_OK; } static int netrigctl_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "J%s %ld\n", vfostr, rit); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "j%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rit = atoi(buf); return RIG_OK; } static int netrigctl_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Z%s %ld\n", vfostr, xit); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "z%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *xit = atoi(buf); return RIG_OK; } static int netrigctl_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "N%s %ld\n", vfostr, ts); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "n%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ts = atoi(buf); return RIG_OK; } static int netrigctl_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "U%s %s %i\n", vfostr, rig_strfunc(func), status); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (strlen(rig_strfunc(func)) == 0) { return -RIG_ENAVAIL; } SNPRINTF(cmd, sizeof(cmd), "u%s %s\n", vfostr, rig_strfunc(func)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *status = atoi(buf); return RIG_OK; } static int netrigctl_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char lstr[32]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "L%s %s %s\n", vfostr, rig_strlevel(level), lstr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "l%s %s\n", vfostr, rig_strlevel(level)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_LEVEL_IS_FLOAT(level)) { val->f = atof(buf); } else { val->i = atoi(buf); } return RIG_OK; } static int netrigctl_set_powerstat(RIG *rig, powerstat_t status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\set_powerstat %d\n", status); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_powerstat(RIG *rig, powerstat_t *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\get_powerstat\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { int offset = 0; // see if there is a RPRT answer to make SDR++ happy if (strstr(buf, "RPRT")) { offset = 4; } *status = atoi(&buf[offset]); } else { // was causing problems with sdr++ since it does not have PS command // a return of 1 should indicate there is no powerstat command available // so we fake the ON status // also a problem with Flex 6xxx and Log4OM not working due to lack of PS command if (ret != -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_ON\n", __func__, ret); *status = RIG_POWER_ON; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_OFF\n", __func__, ret); *status = RIG_POWER_OFF; } } return RIG_OK; // always return RIG_OK } static int netrigctl_set_parm(RIG *rig, setting_t parm, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char pstr[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } SNPRINTF(cmd, sizeof(cmd), "P %s %s\n", rig_strparm(parm), pstr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_parm(RIG *rig, setting_t parm, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "p %s\n", rig_strparm(parm)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_PARM_IS_FLOAT(parm)) { val->f = atoi(buf); } else { val->i = atoi(buf); } return RIG_OK; } static int netrigctl_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; int i_ant = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x, option=%d\n", __func__, ant, option.i); switch (ant) { case RIG_ANT_1: i_ant = 0; break; case RIG_ANT_2: i_ant = 1; break; case RIG_ANT_3: i_ant = 2; break; case RIG_ANT_4: i_ant = 3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: more than 4 antennas? ant=0x%02x\n", __func__, ant); } ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Y%s %d %d\n", vfostr, i_ant, option.i); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (ant == RIG_ANT_CURR) { SNPRINTF(cmd, sizeof(cmd), "y%s\n", vfostr); } else { SNPRINTF(cmd, sizeof(cmd), "y%s %u\n", vfostr, ant); } ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: buf='%s'\n", __func__, buf); ret = sscanf(buf, "%u\n", ant_curr); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 ant integer in '%s', got %d\n", __func__, buf, ret); } if (ant != RIG_ANT_CURR) { ret = sscanf(buf, "%d\n", &option->i); } if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%d\n", &(option->i)); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } return RIG_OK; } static int netrigctl_set_bank(RIG *rig, vfo_t vfo, int bank) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "B %d\n", bank); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "E%s %d\n", vfostr, ch); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_mem(RIG *rig, vfo_t vfo, int *ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "e %s\n", vfostr); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ch = atoi(buf); return RIG_OK; } static int netrigctl_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "g %s %d\n", rig_strscan(scan), ch); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "G%s %s\n", vfostr, rig_strvfop(op)); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { return -RIG_ENIMPL; } static int netrigctl_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { return -RIG_ENIMPL; } static const char *netrigctl_get_info(RIG *rig) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } static int netrigctl_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { int ret, len; char *cmdp; const char cmd[] = "\\send_dtmf "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + digits + \n + \0) len = strlen(cmd) + strlen(digits) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, digits); ret = netrigctl_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\recv_dtmf\n"); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > *length) { ret = *length; } strncpy(digits, buf, ret); *length = ret; digits [ret] = '\0'; return RIG_OK; } static int netrigctl_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\send_voice_mem %d\n", ch); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_send_morse(RIG *rig, vfo_t vfo, const char *msg) { int ret, len; char *cmdp; const char cmd[] = "\\send_morse "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + msg + \n + \0) len = strlen(cmd) + strlen(msg) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, msg); ret = netrigctl_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_stop_morse(RIG *rig, vfo_t vfo) { int ret; char cmd[] = "\\stop_morse\n"; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_vfo_opt(RIG *rig, int status) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_vfo_opt %d\n", status); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } STATE(rig)->vfo_opt = status; return RIG_OK; } #if 0 // for the futurem -- would have to poll to get the pushed data static int netrigctl_set_trn(RIG *rig, int trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_trn %s\n", trn ? "ON" : "OFF"); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret < 0) { return -RIG_EPROTO; } return RIG_OK; } static int netrigctl_get_trn(RIG *rig, int *trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_trn\n"); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } if (strstr(buf, "OFF")) { *trn = RIG_TRN_OFF; } else if (strstr(buf, "RIG")) { *trn = RIG_TRN_RIG; } else if (strstr(buf, "POLL")) { *trn = RIG_TRN_POLL; } else { rig_debug(RIG_DEBUG_ERR, "%s: Expected OFF, RIG, or POLL, got '%s'\n", __func__, buf); ret = -RIG_EINVAL; } RETURNFUNC(ret); } #endif static int netrigctl_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\mW2power %u %.0f %s\n", mwpower, freq, rig_strrmode(mode)); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *power = atof(buf); RETURNFUNC(RIG_OK); } static int netrigctl_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { char cmdbuf[64]; char buf[BUF_MAX]; int ret; ENTERFUNC; // we shouldn't need any precision than microwatts SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\power2mW %.3f %.0f %s\n", power, freq, rig_strrmode(mode)); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *mwpower = atof(buf); RETURNFUNC(RIG_OK); } int netrigctl_password(RIG *rig, const char *key1) { char cmdbuf[256]; char buf[BUF_MAX]; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: key1=%s\n", __func__, key1); SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\password %s\n", key1); retval = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (retval != RIG_OK) { retval = -RIG_EPROTO; } RETURNFUNC(retval); } int netrigctl_set_lock_mode(RIG *rig, int lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_lock_mode %d\n", lock); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } return (RIG_OK); } int netrigctl_get_lock_mode(RIG *rig, int *lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; hamlib_port_t *rp = RIGPORT(rig); SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_lock_mode\n"); ret = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret == 0) { return -RIG_EPROTO; } sscanf(buf, "%d", lock); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); return (RIG_OK); } int netrigctl_send_raw(RIG *rig, char *s) { int ret; char buf[BUF_MAX]; ret = netrigctl_transaction(rig, s, strlen(s), buf); return ret; } /* * Netrigctl rig capabilities. */ struct rig_caps netrigctl_caps = { RIG_MODEL(RIG_MODEL_NETRIGCTL), .model_name = "NET rigctl", .mfg_name = "Hamlib", .version = "20240418.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = 0, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NETWORK, .timeout = 10000, /* enough for the worst rig we have */ .retry = 5, /* following fields updated in rig_state at opening time */ .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { }, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { }, .transceive = RIG_TRN_OFF, .attenuator = { }, .preamp = { }, .rx_range_list2 = { RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { }, .filters = { RIG_FLT_END, }, .max_rit = 0, .max_xit = 0, .max_ifshift = 0, .priv = NULL, .rig_init = netrigctl_init, .rig_cleanup = netrigctl_cleanup, .rig_open = netrigctl_open, .rig_close = netrigctl_close, .set_freq = netrigctl_set_freq, .get_freq = netrigctl_get_freq, .set_mode = netrigctl_set_mode, .get_mode = netrigctl_get_mode, .set_vfo = netrigctl_set_vfo, .get_vfo = netrigctl_get_vfo, .set_powerstat = netrigctl_set_powerstat, .get_powerstat = netrigctl_get_powerstat, .set_level = netrigctl_set_level, .get_level = netrigctl_get_level, .set_func = netrigctl_set_func, .get_func = netrigctl_get_func, .set_parm = netrigctl_set_parm, .get_parm = netrigctl_get_parm, .get_info = netrigctl_get_info, .set_ptt = netrigctl_set_ptt, .get_ptt = netrigctl_get_ptt, .get_dcd = netrigctl_get_dcd, .set_rptr_shift = netrigctl_set_rptr_shift, .get_rptr_shift = netrigctl_get_rptr_shift, .set_rptr_offs = netrigctl_set_rptr_offs, .get_rptr_offs = netrigctl_get_rptr_offs, .set_ctcss_tone = netrigctl_set_ctcss_tone, .get_ctcss_tone = netrigctl_get_ctcss_tone, .set_dcs_code = netrigctl_set_dcs_code, .get_dcs_code = netrigctl_get_dcs_code, .set_ctcss_sql = netrigctl_set_ctcss_sql, .get_ctcss_sql = netrigctl_get_ctcss_sql, .set_dcs_sql = netrigctl_set_dcs_sql, .get_dcs_sql = netrigctl_get_dcs_sql, .set_split_freq = netrigctl_set_split_freq, .get_split_freq = netrigctl_get_split_freq, .set_split_mode = netrigctl_set_split_mode, .get_split_mode = netrigctl_get_split_mode, .set_split_vfo = netrigctl_set_split_vfo, .get_split_vfo = netrigctl_get_split_vfo, .set_rit = netrigctl_set_rit, .get_rit = netrigctl_get_rit, .set_xit = netrigctl_set_xit, .get_xit = netrigctl_get_xit, .set_ts = netrigctl_set_ts, .get_ts = netrigctl_get_ts, .set_ant = netrigctl_set_ant, .get_ant = netrigctl_get_ant, .set_bank = netrigctl_set_bank, .set_mem = netrigctl_set_mem, .get_mem = netrigctl_get_mem, .vfo_op = netrigctl_vfo_op, .scan = netrigctl_scan, .send_dtmf = netrigctl_send_dtmf, .recv_dtmf = netrigctl_recv_dtmf, .send_morse = netrigctl_send_morse, .send_voice_mem = netrigctl_send_voice_mem, .stop_morse = netrigctl_stop_morse, .set_channel = netrigctl_set_channel, .get_channel = netrigctl_get_channel, .set_vfo_opt = netrigctl_set_vfo_opt, //.set_trn = netrigctl_set_trn, //.get_trn = netrigctl_get_trn, .power2mW = netrigctl_power2mW, .mW2power = netrigctl_mW2power, .password = netrigctl_password, .set_lock_mode = netrigctl_set_lock_mode, .get_lock_mode = netrigctl_get_lock_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/dummy/Makefile.in0000644000175000017500000005746014752216216014066 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/dummy ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_dummy_la_LIBADD = am__objects_1 = dummy_common.lo dummy.lo rot_dummy.lo \ rot_pstrotator.lo netrigctl.lo netrotctl.lo flrig.lo \ trxmanager.lo amp_dummy.lo netampctl.lo tci1x.lo aclog.lo \ sdrsharp.lo quisk.lo am_libhamlib_dummy_la_OBJECTS = $(am__objects_1) libhamlib_dummy_la_OBJECTS = $(am_libhamlib_dummy_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/aclog.Plo ./$(DEPDIR)/amp_dummy.Plo \ ./$(DEPDIR)/dummy.Plo ./$(DEPDIR)/dummy_common.Plo \ ./$(DEPDIR)/flrig.Plo ./$(DEPDIR)/netampctl.Plo \ ./$(DEPDIR)/netrigctl.Plo ./$(DEPDIR)/netrotctl.Plo \ ./$(DEPDIR)/quisk.Plo ./$(DEPDIR)/rot_dummy.Plo \ ./$(DEPDIR)/rot_pstrotator.Plo ./$(DEPDIR)/sdrsharp.Plo \ ./$(DEPDIR)/tci1x.Plo ./$(DEPDIR)/trxmanager.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_dummy_la_SOURCES) DIST_SOURCES = $(libhamlib_dummy_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DUMMYSRC = dummy_common.c dummy_common.h dummy.c dummy.h rot_dummy.c rot_dummy.h rot_pstrotator.c rot_pstrotator.h netrigctl.c netrotctl.c flrig.c flrig.h trxmanager.c trxmanager.h amp_dummy.c amp_dummy.h netampctl.c tci1x.c aclog.c sdrsharp.c quisk.c noinst_LTLIBRARIES = libhamlib-dummy.la libhamlib_dummy_la_SOURCES = $(DUMMYSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/dummy/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/dummy/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-dummy.la: $(libhamlib_dummy_la_OBJECTS) $(libhamlib_dummy_la_DEPENDENCIES) $(EXTRA_libhamlib_dummy_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_dummy_la_OBJECTS) $(libhamlib_dummy_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aclog.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amp_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flrig.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netampctl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrigctl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrotctl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quisk.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rot_pstrotator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdrsharp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tci1x.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trxmanager.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/aclog.Plo -rm -f ./$(DEPDIR)/amp_dummy.Plo -rm -f ./$(DEPDIR)/dummy.Plo -rm -f ./$(DEPDIR)/dummy_common.Plo -rm -f ./$(DEPDIR)/flrig.Plo -rm -f ./$(DEPDIR)/netampctl.Plo -rm -f ./$(DEPDIR)/netrigctl.Plo -rm -f ./$(DEPDIR)/netrotctl.Plo -rm -f ./$(DEPDIR)/quisk.Plo -rm -f ./$(DEPDIR)/rot_dummy.Plo -rm -f ./$(DEPDIR)/rot_pstrotator.Plo -rm -f ./$(DEPDIR)/sdrsharp.Plo -rm -f ./$(DEPDIR)/tci1x.Plo -rm -f ./$(DEPDIR)/trxmanager.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/aclog.Plo -rm -f ./$(DEPDIR)/amp_dummy.Plo -rm -f ./$(DEPDIR)/dummy.Plo -rm -f ./$(DEPDIR)/dummy_common.Plo -rm -f ./$(DEPDIR)/flrig.Plo -rm -f ./$(DEPDIR)/netampctl.Plo -rm -f ./$(DEPDIR)/netrigctl.Plo -rm -f ./$(DEPDIR)/netrotctl.Plo -rm -f ./$(DEPDIR)/quisk.Plo -rm -f ./$(DEPDIR)/rot_dummy.Plo -rm -f ./$(DEPDIR)/rot_pstrotator.Plo -rm -f ./$(DEPDIR)/sdrsharp.Plo -rm -f ./$(DEPDIR)/tci1x.Plo -rm -f ./$(DEPDIR)/trxmanager.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/dummy/quisk.c0000644000175000017500000020431114752216205013304 00000000000000/* * Hamlib Quisk backend - main file * Copyright (c) 2023 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "iofunc.h" #include "misc.h" #include "num_stdio.h" #include "dummy.h" #define CMD_MAX 64 #define BUF_MAX 1024 #define CHKSCN1ARG(a) if ((a) != 1) return -RIG_EPROTO; else do {} while(0) struct quisk_priv_data { vfo_t vfo_curr; int rigctld_vfo_mode; vfo_t rx_vfo; vfo_t tx_vfo; }; #if 0 int quisk_get_vfo_mode(RIG *rig) { struct quisk_priv_data *priv; priv = (struct quisk_priv_data *)STATE(rig)->priv; return priv->rigctld_vfo_mode; } #endif /* * Helper function with protocol return code parsing */ static int quisk_transaction(RIG *rig, char *cmd, int len, char *buf) { int ret; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called len=%d\n", __func__, len); /* flush anything in the read buffer before command is sent */ rig_flush(rp); ret = write_block(rp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret < 0) { return ret; } if (strncmp(buf, NETRIGCTL_RET, strlen(NETRIGCTL_RET)) == 0) { return atoi(buf + strlen(NETRIGCTL_RET)); } return ret; } /* this will fill vfostr with the vfo value if the vfo mode is enabled * otherwise string will be null terminated * this allows us to use the string in snprintf in either mode */ static int quisk_vfostr(RIG *rig, char *vfostr, int len, vfo_t vfo) { struct quisk_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); if (len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: len must be >=5, len=%d\n", __func__, len); return -RIG_EPROTO; } vfostr[0] = 0; priv = (struct quisk_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo==RIG_VFO_CURR, curr=%s\n", __func__, rig_strvfo(priv->vfo_curr)); vfo = priv->vfo_curr; if (vfo == RIG_VFO_NONE) { vfo = RIG_VFO_A; } } else if (vfo == RIG_VFO_RX) { vfo = priv->rx_vfo; } else if (vfo == RIG_VFO_TX) { vfo = priv->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt=%d\n", __func__, STATE(rig)->vfo_opt); if (STATE(rig)->vfo_opt || priv->rigctld_vfo_mode) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo_opt vfo=%u\n", __func__, vfo); char *myvfo; switch (vfo) { case RIG_VFO_B: myvfo = "VFOB"; break; case RIG_VFO_C: myvfo = "VFOC"; break; case RIG_VFO_MAIN: myvfo = "Main"; break; case RIG_VFO_MAIN_A: myvfo = "MainA"; break; case RIG_VFO_MAIN_B: myvfo = "MainB"; break; case RIG_VFO_SUB: myvfo = "Sub"; break; case RIG_VFO_SUB_A: myvfo = "SubA"; break; case RIG_VFO_SUB_B: myvfo = "SubB"; break; case RIG_VFO_MEM: myvfo = "MEM"; break; default: myvfo = "VFOA"; } SNPRINTF(vfostr, len, " %s", myvfo); } return RIG_OK; } static int quisk_init(RIG *rig) { // cppcheck says leak here but it's freed in cleanup struct quisk_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct quisk_priv_data *)calloc(1, sizeof( struct quisk_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct quisk_priv_data)); rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); /* * set arbitrary initial status * VFO will be updated in open call */ priv->vfo_curr = RIG_VFO_A; priv->rigctld_vfo_mode = 0; return RIG_OK; } static int quisk_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } // these are in netrigctl.c extern int parse_array_int(const char *s, const char *delim, int *array, int array_len); extern int parse_array_double(const char *s, const char *delim, double *array, int array_len); static int quisk_open(RIG *rig) { int ret, i; struct rig_state *rs = STATE(rig); int prot_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct quisk_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; priv = (struct quisk_priv_data *)rs->priv; priv->rx_vfo = RIG_VFO_A; priv->tx_vfo = RIG_VFO_A; SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } prot_ver = atoi(buf); #define RIGCTLD_PROT_VER 0 if (prot_ver < RIGCTLD_PROT_VER) { RETURNFUNC(-RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->deprecated_itu_region = atoi(buf); for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &(rs->rx_range_list[i].startf), &(rs->rx_range_list[i].endf), &(rs->rx_range_list[i].modes), &(rs->rx_range_list[i].low_power), &(rs->rx_range_list[i].high_power), &(rs->rx_range_list[i].vfo), &(rs->rx_range_list[i].ant) ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->rx_range_list[i])) { break; } } for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &rs->tx_range_list[i].startf, &rs->tx_range_list[i].endf, &rs->tx_range_list[i].modes, &rs->tx_range_list[i].low_power, &rs->tx_range_list[i].high_power, &rs->tx_range_list[i].vfo, &rs->tx_range_list[i].ant ); if (ret != 7) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FRNG_END(rs->tx_range_list[i])) { break; } switch (i) { } rig->caps->tx_range_list1->startf = rs->tx_range_list[i].startf; rig->caps->tx_range_list1->endf = rs->tx_range_list[i].endf; rig->caps->tx_range_list1->modes = rs->tx_range_list[i].modes; rig->caps->tx_range_list1->low_power = rs->tx_range_list[i].low_power; rig->caps->tx_range_list1->high_power = rs->tx_range_list[i].high_power; rig->caps->tx_range_list1->vfo = rs->tx_range_list[i].vfo; rig->caps->tx_range_list1->ant = rs->tx_range_list[i].ant; } for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->tuning_steps[i].modes, &rs->tuning_steps[i].ts); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_TS_END(rs->tuning_steps[i])) { break; } } for (i = 0; i < HAMLIB_FLTLSTSIZ; i++) { ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%"SCNXll"%ld", &rs->filters[i].modes, &rs->filters[i].width); if (ret != 2) { RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_FLT_END(rs->filters[i])) { break; } } #if 0 /* TODO */ chan_t chan_list[HAMLIB_CHANLSTSIZ]; /*!< Channel list, zero ended */ #endif ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_rit = rs->max_rit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_xit = rs->max_xit = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->max_ifshift = rs->max_ifshift = atol(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->announces = atoi(buf); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->preamp[0], &rs->preamp[1], &rs->preamp[2], &rs->preamp[3], &rs->preamp[4], &rs->preamp[5], &rs->preamp[6]); rig->caps->preamp[0] = rs->preamp[0]; rig->caps->preamp[1] = rs->preamp[1]; rig->caps->preamp[2] = rs->preamp[2]; rig->caps->preamp[3] = rs->preamp[3]; rig->caps->preamp[4] = rs->preamp[4]; rig->caps->preamp[5] = rs->preamp[5]; rig->caps->preamp[6] = rs->preamp[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->preamp[ret] = rs->preamp[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->attenuator[0], &rs->attenuator[1], &rs->attenuator[2], &rs->attenuator[3], &rs->attenuator[4], &rs->attenuator[5], &rs->attenuator[6]); rig->caps->attenuator[0] = rs->attenuator[0]; rig->caps->attenuator[1] = rs->attenuator[1]; rig->caps->attenuator[2] = rs->attenuator[2]; rig->caps->attenuator[3] = rs->attenuator[3]; rig->caps->attenuator[4] = rs->attenuator[4]; rig->caps->attenuator[5] = rs->attenuator[5]; rig->caps->attenuator[6] = rs->attenuator[6]; if (ret < 0 || ret >= HAMLIB_MAXDBLSTSIZ) { ret = 0; } rig->caps->attenuator[ret] = rs->attenuator[ret] = RIG_DBLST_END; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_func = rs->has_get_func = strtoll(buf, NULL, 0); HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_func = rs->has_set_func = strtoll(buf, NULL, 0); HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_get_level = rs->has_get_level = strtoll(buf, NULL, 0); #if 0 // don't think we need this anymore if (rs->has_get_level & RIG_LEVEL_RAWSTR) { /* include STRENGTH because the remote rig may be able to provide a front end emulation, if it can't then an -RIG_EINVAL will be returned */ rs->has_get_level |= RIG_LEVEL_STRENGTH; rig->caps->has_get_level |= RIG_LEVEL_STRENGTH; } #endif HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rig->caps->has_set_level = rs->has_set_level = strtoll(buf, NULL, 0); HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } rs->has_get_parm = strtoll(buf, NULL, 0); #if 0 HAMLIB_TRACE; ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } HAMLIB_TRACE; rig->caps->has_set_parm = rs->has_set_parm = strtoll(buf, NULL, 0); for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->rx_range_list[i]); i++) { rs->mode_list |= rs->rx_range_list[i].modes; rs->vfo_list |= rs->rx_range_list[i].vfo; } HAMLIB_TRACE; for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rs->tx_range_list[i]); i++) { rs->mode_list |= rs->tx_range_list[i].modes; rs->vfo_list |= rs->tx_range_list[i].vfo; } HAMLIB_TRACE; if (rs->vfo_list == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo_list empty, defaulting to A/B\n", __func__); rs->vfo_list = RIG_VFO_A | RIG_VFO_B; } HAMLIB_TRACE; #endif if (prot_ver == 0) { RETURNFUNC(RIG_OK); } HAMLIB_TRACE; // otherwise we continue reading protocol 1 fields do { char setting[32], value[1024]; hamlib_port_t *pttp = PTTPORT(rig); ret = read_string(rp, (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); strtok(buf, "\r\n"); // chop the EOL if (ret <= 0) { RETURNFUNC((ret < 0) ? ret : -RIG_EPROTO); } if (strncmp(buf, "done", 4) == 0) { RETURNFUNC(RIG_OK); } if (sscanf(buf, "%31[^=]=%1023[^\t\n]", setting, value) == 2) { if (strcmp(setting, "vfo_ops") == 0) { rig->caps->vfo_ops = strtoll(value, NULL, 0); rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, rig->caps->vfo_ops); } else if (strcmp(setting, "ptt_type") == 0) { ptt_type_t temp = (ptt_type_t)strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type='%s'(%d)\n", __func__, value, temp); if (RIG_PTT_RIG_MICDATA == pttp->type.ptt || temp == RIG_PTT_RIG_MICDATA) { /* * remote PTT must always be RIG_PTT_RIG_MICDATA * if there is any PTT capability and we have not * locally overridden it */ pttp->type.ptt = RIG_PTT_RIG_MICDATA; rig->caps->ptt_type = RIG_PTT_RIG_MICDATA; rig_debug(RIG_DEBUG_TRACE, "%s: %s set to %d\n", __func__, setting, pttp->type.ptt); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt_type= %d\n", __func__, temp); pttp->type.ptt = temp; rig->caps->ptt_type = temp; } } else if (strcmp(setting, "targetable_vfo") == 0) { rig->caps->targetable_vfo = strtol(value, NULL, 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: targetable_vfo=0x%2x\n", __func__, rig->caps->targetable_vfo); } else if (strcmp(setting, "has_set_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_vfo = NULL; } } else if (strcmp(setting, "has_get_vfo") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_vfo = NULL; } } else if (strcmp(setting, "has_set_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_freq = NULL; } } else if (strcmp(setting, "has_get_freq") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_freq = NULL; } } else if (strcmp(setting, "has_set_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_conf = NULL; } } else if (strcmp(setting, "has_get_conf") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_conf = NULL; } } #if 0 // for the future else if (strcmp(setting, "has_set_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->set_trn = NULL; } } else if (strcmp(setting, "has_get_trn") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->get_trn = NULL; } } #endif else if (strcmp(setting, "has_power2mW") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->power2mW = NULL; } } else if (strcmp(setting, "has_mW2power") == 0) { int has = strtol(value, NULL, 0); if (!has) { rig->caps->mW2power = NULL; } } else if (strcmp(setting, "timeout") == 0) { // use the rig's timeout value plus 500ms for potential network delays rig->caps->timeout = strtol(value, NULL, 0) + 500; rig_debug(RIG_DEBUG_TRACE, "%s: timeout value = '%s', final timeout=%d\n", __func__, value, rig->caps->timeout); } else if (strcmp(setting, "rig_model") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rig_model=%s\n", __func__, value); } else if (strcmp(setting, "rigctld_version") == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: rigctld_version=%s\n", __func__, value); } else if (strcmp(setting, "ctcss_list") == 0) { int n; double ctcss[CTCSS_LIST_SIZE]; rig->caps->ctcss_list = calloc(CTCSS_LIST_SIZE, sizeof(tone_t)); n = parse_array_double(value, " \n\r", ctcss, CTCSS_LIST_SIZE); for (i = 0; i < CTCSS_LIST_SIZE && ctcss[i] != 0; ++i) { rig->caps->ctcss_list[i] = ctcss[i] * 10; } if (n < CTCSS_LIST_SIZE) { rig->caps->ctcss_list[n] = 0; } } else if (strcmp(setting, "dcs_list") == 0) { int n; int dcs[DCS_LIST_SIZE + 1]; rig->caps->dcs_list = calloc(DCS_LIST_SIZE, sizeof(tone_t)); n = parse_array_int(value, " \n\r", dcs, DCS_LIST_SIZE); for (i = 0; i < DCS_LIST_SIZE && dcs[i] != 0; i++) { rig->caps->dcs_list[i] = dcs[i]; } if (n < DCS_LIST_SIZE) { rig->caps->dcs_list[n] = 0; } } else if (strcmp(setting, "agc_levels") == 0) { char *p = strtok(value, " "); rig->caps->agc_levels[0] = RIG_AGC_NONE; // default value gets overwritten rig->caps->agc_level_count = 0; while (p) { int agc_code; char agc_string[32]; int n = sscanf(p, "%d=%31s\n", &agc_code, agc_string); if (n == 2) { rig->caps->agc_levels[i++] = agc_code; rig->caps->agc_level_count++; rig_debug(RIG_DEBUG_VERBOSE, "%s: rig has agc code=%d, level=%s\n", __func__, agc_code, agc_string); } else { rig_debug(RIG_DEBUG_ERR, "%s did not parse code=agc from '%s'\n", __func__, p); } rig_debug(RIG_DEBUG_VERBOSE, "%d=%s\n", agc_code, agc_string); p = strtok(NULL, " "); } } else if (strcmp(setting, "level_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int level; sscanf(p, "%d", &level); if (RIG_LEVEL_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &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); 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, ";"); } } else if (strcmp(setting, "parm_gran") == 0) { char *p = strtok(value, ";"); for (i = 0; p != NULL && i < RIG_SETTING_MAX; ++i) { int level; sscanf(p, "%d", &level); if (RIG_LEVEL_IS_FLOAT(level)) { double min, max, step; sscanf(p, "%*d=%lf,%lf,%lf", &min, &max, &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); 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, ";"); } } else { // not an error -- just a warning for backward compatibility rig_debug(RIG_DEBUG_ERR, "%s: unknown setting='%s'\n", __func__, buf); } } else { rig_debug(RIG_DEBUG_ERR, "%s: invalid dumpcaps line, expected 'setting=value', got '%s'\n", __func__, buf); } } while (1); if (rs->auto_power_on) { rig_set_powerstat(rig, 1); } RETURNFUNC(RIG_OK); } static int quisk_close(RIG *rig) { const struct rig_state *rs = STATE(rig); int ret; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rs->auto_power_off && rs->comm_state) { rig_set_powerstat(rig, 0); } ret = quisk_transaction(rig, "q\n", 2, buf); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: close error %s\n", __func__, rigerror(ret)); return ret; } rig_debug(RIG_DEBUG_ERR, "%s: done\n", __func__); usleep(10 * 1000); return RIG_OK; } static int quisk_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); #if 1 // implement set_freq VFO later if it can be detected ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "F%s %"FREQFMT"\n", vfostr, freq); #else SNPRINTF(cmd, sizeof(cmd), "F %"FREQFMT"\n", freq); #endif ret = quisk_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s\n", __func__, strtok(cmd, "\r\n")); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; #if 0 // disable until we figure out if we can do this without breaking backwards compatibility char vfotmp[16]; #endif rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "f%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s, reply=%s\n", __func__, strtok(cmd, "\r\n"), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, freq)); #if 0 // implement set_freq VFO later if it can be detected ret = read_string(RIGPORT(rig), buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *vfotmp = rig_parse_vfo(buf); #endif return RIG_OK; } static int quisk_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "M%s %s %li\n", vfostr, rig_strrmode(mode), width); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s\n", __func__, rig_strvfo(vfo)); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "m%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *width = atoi(buf); return RIG_OK; } #if 0 static int quisk_set_vfo(RIG *rig, vfo_t vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; struct quisk_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct quisk_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "V%s %s\n", vfostr, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd='%s'\n", __func__, cmd); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } priv->vfo_curr = vfo; // remember our vfo STATE(rig)->current_vfo = vfo; return ret; } static int quisk_get_vfo(RIG *rig, vfo_t *vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct quisk_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct quisk_priv_data *)STATE(rig)->priv; SNPRINTF(cmd, sizeof(cmd), "v\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret == -RIG_ENAVAIL || ret == -RIG_ENIMPL) { // for rigs without get_vfo we'll use our saved vfo *vfo = priv->vfo_curr; return RIG_OK; } if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *vfo = rig_parse_vfo(buf); priv->vfo_curr = *vfo; return RIG_OK; } #endif static int quisk_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, ptt=%d, ptt_type=%d\n", __func__, rig_strvfo(vfo), ptt, PTTPORT(rig)->type.ptt); if (PTTPORT(rig)->type.ptt == RIG_PTT_NONE) { return RIG_OK; } ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "T%s %d\n", vfostr, ptt); rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%s", __func__, cmd); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "t%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ptt = atoi(buf); return RIG_OK; } static int quisk_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcd%s\n", vfostr); /* FIXME */ ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *dcd = atoi(buf); return RIG_OK; } static int quisk_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "R%s %s\n", vfostr, rig_strptrshift(rptr_shift)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "r%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *rptr_shift = rig_parse_rptr_shift(buf); return RIG_OK; } static int quisk_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "O%s %ld\n", vfostr, rptr_offs); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "o%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rptr_offs = atoi(buf); return RIG_OK; } static int quisk_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "C%s %u\n", vfostr, tone); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "c%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int quisk_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "D%s %u\n", vfostr, code); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "d%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int quisk_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_ctcss_sql%s %u\n", vfostr, tone); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_ctcss_sql%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int quisk_set_dcs_sql(RIG *rig, vfo_t vfo, unsigned int code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\set_dcs_sql%s %u\n", vfostr, code); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_dcs_sql(RIG *rig, vfo_t vfo, unsigned int *code) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "\\get_dcs_sql%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } #if 0 static int quisk_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "I%s %"FREQFMT"\n", vfostr, tx_freq); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "i%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, tx_freq)); return RIG_OK; } static int quisk_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "X%s %s %li\n", vfostr, rig_strrmode(tx_mode), tx_width); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "x%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_mode = rig_parse_mode(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tx_width = atoi(buf); return RIG_OK; } static int quisk_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, vfotx=%s, split=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo), split); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "S%s %d %s\n", vfostr, split, rig_strvfo(tx_vfo)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "s%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *split = atoi(buf); ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_vfo = rig_parse_vfo(buf); return RIG_OK; } #endif static int quisk_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "J%s %ld\n", vfostr, rit); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "j%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rit = atoi(buf); return RIG_OK; } #if 0 static int quisk_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Z%s %ld\n", vfostr, xit); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "z%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *xit = atoi(buf); return RIG_OK; } #endif #if 0 static int quisk_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "N%s %ld\n", vfostr, ts); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "n%s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ts = atoi(buf); return RIG_OK; } #endif static int quisk_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "U%s %s %i\n", vfostr, rig_strfunc(func), status); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (strlen(rig_strfunc(func)) == 0) { return -RIG_ENAVAIL; } SNPRINTF(cmd, sizeof(cmd), "u%s %s\n", vfostr, rig_strfunc(func)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *status = atoi(buf); return RIG_OK; } static int quisk_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char lstr[32]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "L%s %s %s\n", vfostr, rig_strlevel(level), lstr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "l%s %s\n", vfostr, rig_strlevel(level)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_LEVEL_IS_FLOAT(level)) { val->f = atof(buf); } else { val->i = atoi(buf); } return RIG_OK; } #if 0 static int quisk_set_powerstat(RIG *rig, powerstat_t status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\set_powerstat %d\n", status); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_powerstat(RIG *rig, powerstat_t *status) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\get_powerstat\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { int offset = 0; // see if there is a RPRT answer to make SDR++ happy if (strstr(buf, "RPRT")) { offset = 4; } *status = atoi(&buf[offset]); } else { // was causing problems with sdr++ since it does not have PS command // a return of 1 should indicate there is no powerstat command available // so we fake the ON status // also a problem with Flex 6xxx and Log4OM not working due to lack of PS command if (ret != RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_ON\n", __func__, ret); *status = RIG_POWER_ON; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: PS command failed (ret=%d) so returning RIG_POWER_OFF\n", __func__, ret); *status = RIG_POWER_OFF; } } return RIG_OK; // always return RIG_OK } #endif static int quisk_set_parm(RIG *rig, setting_t parm, value_t val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char pstr[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } SNPRINTF(cmd, sizeof(cmd), "P %s %s\n", rig_strparm(parm), pstr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_parm(RIG *rig, setting_t parm, value_t *val) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "p %s\n", rig_strparm(parm)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_PARM_IS_FLOAT(parm)) { val->f = atoi(buf); } else { val->i = atoi(buf); } return RIG_OK; } #if 0 static int quisk_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; int i_ant = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x, option=%d\n", __func__, ant, option.i); switch (ant) { case RIG_ANT_1: i_ant = 0; break; case RIG_ANT_2: i_ant = 1; break; case RIG_ANT_3: i_ant = 2; break; case RIG_ANT_4: i_ant = 3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: more than 4 antennas? ant=0x%02x\n", __func__, ant); } ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "Y%s %d %d\n", vfostr, i_ant, option.i); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } if (ant == RIG_ANT_CURR) { SNPRINTF(cmd, sizeof(cmd), "y%s\n", vfostr); } else { SNPRINTF(cmd, sizeof(cmd), "y%s %u\n", vfostr, ant); } ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: buf='%s'\n", __func__, buf); ret = sscanf(buf, "%u\n", ant_curr); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 ant integer in '%s', got %d\n", __func__, buf, ret); } if (ant != RIG_ANT_CURR) { ret = sscanf(buf, "%d\n", &option->i); } if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } ret = read_string(RIGPORT(rig), (unsigned char *) buf, BUF_MAX, "\n", 1, 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%d\n", &(option->i)); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } return RIG_OK; } static int quisk_set_bank(RIG *rig, vfo_t vfo, int bank) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "B %d\n", bank); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_set_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "E%s %d\n", vfostr, ch); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_get_mem(RIG *rig, vfo_t vfo, int *ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "e %s\n", vfostr); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ch = atoi(buf); return RIG_OK; } static int quisk_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "g %s %d\n", rig_strscan(scan), ch); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif #if 0 static int quisk_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } SNPRINTF(cmd, sizeof(cmd), "G%s %s\n", vfostr, rig_strvfop(op)); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif static const char *quisk_get_info(RIG *rig) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } #if 0 static int quisk_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { int ret, len; char *cmdp, cmd[] = "\\send_dtmf "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + digits + \n + \0) len = strlen(cmd) + strlen(digits) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, digits); ret = quisk_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif #if 0 static int quisk_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\recv_dtmf\n"); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > *length) { ret = *length; } strncpy(digits, buf, ret); *length = ret; digits [ret] = '\0'; return RIG_OK; } #endif #if 0 static int quisk_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\send_voice_mem %d\n", ch); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif #if 0 static int quisk_send_morse(RIG *rig, vfo_t vfo, const char *msg) { int ret, len; char *cmdp, cmd[] = "\\send_morse "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + msg + \n + \0) len = strlen(cmd) + strlen(msg) + 2; cmdp = calloc(1, len); if (cmdp == NULL) { return -RIG_ENOMEM; } SNPRINTF(cmdp, len, "%s%s\n", cmd, msg); ret = quisk_transaction(rig, cmdp, strlen(cmdp), buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int quisk_stop_morse(RIG *rig, vfo_t vfo) { int ret; char cmd[] = "\\stop_morse\n"; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = quisk_transaction(rig, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif static int quisk_set_vfo_opt(RIG *rig, int status) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_vfo_opt %d\n", status); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } STATE(rig)->vfo_opt = status; return RIG_OK; } #if 0 // for the futurem -- would have to poll to get the pushed data static int quisk_set_trn(RIG *rig, int trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_trn %s\n", trn ? "ON" : "OFF"); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret < 0) { return -RIG_EPROTO; } return RIG_OK; } static int quisk_get_trn(RIG *rig, int *trn) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_trn\n"); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } if (strstr(buf, "OFF")) { *trn = RIG_TRN_OFF; } else if (strstr(buf, "RIG")) { *trn = RIG_TRN_RIG; } else if (strstr(buf, "POLL")) { *trn = RIG_TRN_POLL; } else { rig_debug(RIG_DEBUG_ERR, "%s: Expected OFF, RIG, or POLL, got '%s'\n", __func__, buf); ret = -RIG_EINVAL; } RETURNFUNC(ret); } #endif static int quisk_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { char cmdbuf[32]; char buf[BUF_MAX]; int ret; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\mW2power %u %.0f %s\n", mwpower, freq, rig_strrmode(mode)); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *power = atof(buf); RETURNFUNC(RIG_OK); } static int quisk_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { char cmdbuf[64]; char buf[BUF_MAX]; int ret; ENTERFUNC; // we shouldn't need any precision than microwatts SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\power2mW %.3f %.0f %s\n", power, freq, rig_strrmode(mode)); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret <= 0) { RETURNFUNC(-RIG_EPROTO); } *mwpower = atof(buf); RETURNFUNC(RIG_OK); } int quisk_password(RIG *rig, const char *key1) { char cmdbuf[256]; char buf[BUF_MAX]; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: key1=%s\n", __func__, key1); SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\password %s\n", key1); retval = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (retval != RIG_OK) { retval = -RIG_EPROTO; } RETURNFUNC(retval); } #if 0 int quisk_set_lock_mode(RIG *rig, int lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\set_lock_mode %d\n", lock); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret > 0) { return -RIG_EPROTO; } return (RIG_OK); } #endif #if 0 int quisk_get_lock_mode(RIG *rig, int *lock) { char cmdbuf[256]; char buf[BUF_MAX]; int ret; SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\get_lock_mode\n"); ret = quisk_transaction(rig, cmdbuf, strlen(cmdbuf), buf); if (ret == 0) { return -RIG_EPROTO; } sscanf(buf, "%d", lock); return (RIG_OK); } #endif #if 0 int quisk_send_raw(RIG *rig, char *s) { int ret; char buf[BUF_MAX]; ret = quisk_transaction(rig, s, strlen(s), buf); return ret; } #endif /* * Netrigctl rig capabilities. */ struct rig_caps quisk_caps = { RIG_MODEL(RIG_MODEL_QUISK), .model_name = "Quisk", .mfg_name = "N2ADR James Ahlstrom", .version = "20230709.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = 0, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NETWORK, .timeout = 10000, /* enough for the worst rig we have */ .retry = 5, /* following fields updated in rig_state at opening time */ .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { }, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { }, .transceive = RIG_TRN_OFF, .attenuator = { }, .preamp = { }, .rx_range_list2 = { RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { }, .filters = { RIG_FLT_END, }, .max_rit = 0, .max_xit = 0, .max_ifshift = 0, .priv = NULL, .rig_init = quisk_init, .rig_cleanup = quisk_cleanup, .rig_open = quisk_open, .rig_close = quisk_close, .set_freq = quisk_set_freq, .get_freq = quisk_get_freq, .set_mode = quisk_set_mode, .get_mode = quisk_get_mode, // .set_vfo = quisk_set_vfo, // .get_vfo = quisk_get_vfo, // .set_powerstat = quisk_set_powerstat, // .get_powerstat = quisk_get_powerstat, .set_level = quisk_set_level, .get_level = quisk_get_level, .set_func = quisk_set_func, .get_func = quisk_get_func, .set_parm = quisk_set_parm, .get_parm = quisk_get_parm, .get_info = quisk_get_info, .set_ptt = quisk_set_ptt, .get_ptt = quisk_get_ptt, .get_dcd = quisk_get_dcd, .set_rptr_shift = quisk_set_rptr_shift, .get_rptr_shift = quisk_get_rptr_shift, .set_rptr_offs = quisk_set_rptr_offs, .get_rptr_offs = quisk_get_rptr_offs, .set_ctcss_tone = quisk_set_ctcss_tone, .get_ctcss_tone = quisk_get_ctcss_tone, .set_dcs_code = quisk_set_dcs_code, .get_dcs_code = quisk_get_dcs_code, .set_ctcss_sql = quisk_set_ctcss_sql, .get_ctcss_sql = quisk_get_ctcss_sql, .set_dcs_sql = quisk_set_dcs_sql, .get_dcs_sql = quisk_get_dcs_sql, // .set_split_freq = quisk_set_split_freq, // .get_split_freq = quisk_get_split_freq, // .set_split_mode = quisk_set_split_mode, // .get_split_mode = quisk_get_split_mode, // .set_split_vfo = quisk_set_split_vfo, // .get_split_vfo = quisk_get_split_vfo, .set_rit = quisk_set_rit, .get_rit = quisk_get_rit, // .set_xit = quisk_set_xit, // .get_xit = quisk_get_xit, // .set_ts = quisk_set_ts, // .get_ts = quisk_get_ts, // .set_ant = quisk_set_ant, // .get_ant = quisk_get_ant, // .set_bank = quisk_set_bank, // .set_mem = quisk_set_mem, // .get_mem = quisk_get_mem, // .vfo_op = quisk_vfo_op, // .scan = quisk_scan, // .send_dtmf = quisk_send_dtmf, // .recv_dtmf = quisk_recv_dtmf, // .send_morse = quisk_send_morse, // .send_voice_mem = quisk_send_voice_mem, // .stop_morse = quisk_stop_morse, // .set_channel = quisk_set_channel, // .get_channel = quisk_get_channel, .set_vfo_opt = quisk_set_vfo_opt, //.set_trn = quisk_set_trn, //.get_trn = quisk_get_trn, .power2mW = quisk_power2mW, .mW2power = quisk_mW2power, .password = quisk_password, // .set_lock_mode = quisk_set_lock_mode, // .get_lock_mode = quisk_get_lock_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/dummy/trxmanager.h0000644000175000017500000000221214752216205014321 00000000000000/* * Hamlib TRXManager backend - main header * Copyright (c) 2017 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * Derived from flrig.h * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TRXMANAGER_H #define _TRXMANAGER_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20210613" #define EOM "\r" #define TRUE 1 #define FALSE 0 extern struct rig_caps trxmanager_caps; #endif /* _TRXMANAGER_H */ hamlib-4.6.2/rigs/dummy/dummy.h0000644000175000017500000000335314752216205013313 00000000000000/* * Hamlib Dummy backend - main header * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DUMMY_H #define _DUMMY_H 1 #include "hamlib/rig.h" #include "token.h" /* backend conf */ #define TOK_CFG_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_MAGICEXTFUNC TOKEN_BACKEND(6) extern struct rig_caps dummy_caps; extern struct rig_caps dummy_no_vfo_caps; extern struct rig_caps netrigctl_caps; extern struct rig_caps flrig_caps; extern struct rig_caps trxmanager_caps; extern struct rig_caps tci1x_caps; extern struct rig_caps aclog_caps; extern struct rig_caps sdrsharp_caps; extern struct rig_caps quisk_caps; int netrigctl_get_vfo_mode(RIG *); #endif /* _DUMMY_H */ hamlib-4.6.2/rigs/dummy/Android.mk0000644000175000017500000000051314752216205013713 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dummy.c rot_dummy.c netrigctl.c netrotctl.c flrig.c trxmanager.c dummy_common.c sdrsharp.c LOCAL_MODULE := dummy LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/dummy/tci1x.c0000644000175000017500000016404514752216205013211 00000000000000/* * Hamlib TCI 1.X backend - main file * Copyright (c) 2021 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include #include #include "dummy_common.h" #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define MAXCMDLEN 8192 #define MAXBUFLEN 8192 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:50001" #define FALSE 0 #ifdef TRUE #undef TRUE #endif #define TRUE (!FALSE) #define TCI_VFOS (RIG_VFO_A|RIG_VFO_B) #define TCI1X_MODES (RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM | RIG_MODE_AM) #define TCI1X_LEVELS (RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_MICGAIN | RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER_METER | RIG_LEVEL_RFPOWER_METER_WATTS | RIG_LEVEL_RFPOWER) #define TCI1X_PARM (TOK_TCI1X_VERIFY_FREQ|TOK_TCI1X_VERIFY_PTT) #define streq(s1,s2) (strcmp(s1,s2)==0) static int tci1x_init(RIG *rig); static int tci1x_open(RIG *rig); static int tci1x_close(RIG *rig); static int tci1x_cleanup(RIG *rig); static int tci1x_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tci1x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tci1x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tci1x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tci1x_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tci1x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tci1x_get_vfo(RIG *rig, vfo_t *vfo); static int tci1x_set_vfo(RIG *rig, vfo_t vfo); static int tci1x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tci1x_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int tci1x_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int tci1x_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int tci1x_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int tci1x_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tci1x_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int tci1x_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); #ifdef XXNOTIMPLEMENTED static int tci1x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tci1x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tci1x_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int tci1x_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); #endif static const char *tci1x_get_info(RIG *rig); static int tci1x_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int tci1x_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); struct tci1x_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set returned from tci1x */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_verify_cmds; // has the verify cmd in FLRig 1.3.54.1 or higher float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; }; /* level's and parm's tokens */ #define TOK_TCI1X_VERIFY_FREQ TOKEN_BACKEND(1) #define TOK_TCI1X_VERIFY_PTT TOKEN_BACKEND(2) static const struct confparams tci1x_ext_parms[] = { { TOK_TCI1X_VERIFY_FREQ, "VERIFY_FREQ", "Verify set_freq", "If true will verify set_freq otherwise is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { TOK_TCI1X_VERIFY_PTT, "VERIFY_PTT", "Verify set_ptt", "If true will verify set_ptt otherwise set_ptt is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; struct rig_caps tci1x_caps = { RIG_MODEL(RIG_MODEL_TCI1X), .model_name = "TCI1.X", .mfg_name = "Expert Elec", .version = "20211125.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 1, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = TCI1X_LEVELS, .has_set_level = RIG_LEVEL_SET(TCI1X_LEVELS), .has_get_parm = TCI1X_PARM, .has_set_parm = RIG_PARM_SET(TCI1X_PARM), .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TCI1X_MODES, .low_power = -1, .high_power = -1, TCI_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TCI1X_MODES, .low_power = -1, .high_power = -1, TCI_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {TCI1X_MODES, 1}, {TCI1X_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .extparms = tci1x_ext_parms, .rig_init = tci1x_init, .rig_open = tci1x_open, .rig_close = tci1x_close, .rig_cleanup = tci1x_cleanup, .set_freq = tci1x_set_freq, .get_freq = tci1x_get_freq, .set_mode = tci1x_set_mode, .get_mode = tci1x_get_mode, .set_vfo = tci1x_set_vfo, .get_vfo = tci1x_get_vfo, .get_info = tci1x_get_info, .set_ptt = tci1x_set_ptt, .get_ptt = tci1x_get_ptt, .set_split_mode = tci1x_set_split_mode, .set_split_freq = tci1x_set_split_freq, .get_split_freq = tci1x_get_split_freq, .set_split_vfo = tci1x_set_split_vfo, .get_split_vfo = tci1x_get_split_vfo, .set_split_freq_mode = tci1x_set_split_freq_mode, .get_split_freq_mode = tci1x_get_split_freq_mode, #ifdef XXNOTIMPLEMENTED .set_level = tci1x_set_level, .get_level = tci1x_get_level, .set_ext_parm = tci1x_set_ext_parm, .get_ext_parm = tci1x_get_ext_parm, #endif .power2mW = tci1x_power2mW, .mW2power = tci1x_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; //Structure for mapping tci1x dynmamic modes to hamlib modes //tci1x displays modes as the rig displays them struct s_modeMap { rmode_t mode_hamlib; char *mode_tci1x; }; //FLRig will provide us the modes for the selected rig //We will then put them in this struct static struct s_modeMap modeMap[] = { {RIG_MODE_USB, NULL}, {RIG_MODE_LSB, NULL}, {RIG_MODE_PKTUSB, NULL}, {RIG_MODE_PKTLSB, NULL}, {RIG_MODE_AM, NULL}, {RIG_MODE_FM, NULL}, {RIG_MODE_FMN, NULL}, {RIG_MODE_WFM, NULL}, {RIG_MODE_CW, NULL}, {RIG_MODE_CWR, NULL}, {RIG_MODE_RTTY, NULL}, {RIG_MODE_RTTYR, NULL}, {RIG_MODE_C4FM, NULL}, {0, NULL} }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /* * * read_transaction * Assumes rig!=NULL, buf!=NULL, buf_len big enough to hold response */ static int read_transaction(RIG *rig, unsigned char *buf, int buf_len) { int retry; char *delims = ";"; ENTERFUNC; retry = 0; do { if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } int len = read_string(RIGPORT(rig), buf, buf_len, delims, strlen(delims), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: string='%s'\n", __func__, buf); if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } } while (retry-- > 0 && strlen((char *) buf) == 0); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } RETURNFUNC(RIG_OK); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, const unsigned char *buf, int buf_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (buf_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, buf, buf_len); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int tci1x_transaction(RIG *rig, char *cmd, char *cmd_arg, char *value, int value_len) { int retry = 0; unsigned char frame[1024]; ENTERFUNC; memset(frame, 0, sizeof(frame)); if (value) { value[0] = 0; } frame[0] = 0x81; frame[1] = strlen(cmd); frame[2] = 0x00; frame[3] = 0x00; frame[4] = 0x00; frame[5] = 0x00; frame[6] = 0x00; frame[7] = 0x00; frame[8] = 0x00; frame[9] = 0x00; frame[10] = 0x00; frame[11] = 0x00; strcat((char *) &frame[12], cmd); do { int retval; if (retry < 2) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } retval = write_transaction(rig, frame, strlen(cmd) + 12); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } read_transaction(rig, (unsigned char *) value, value_len); rig_debug(RIG_DEBUG_VERBOSE, "%s: value=%s\n", __func__, value); } while ((value && (strlen(value) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { RETURNFUNC(RIG_EPROTO); } RETURNFUNC(RIG_OK); } /* * tci1x_init * Assumes rig!=NULL */ static int tci1x_init(RIG *rig) { struct tci1x_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct tci1x_priv_data *)calloc(1, sizeof( struct tci1x_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tci1x_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); priv->ext_parms = alloc_init_ext(tci1x_ext_parms); if (!priv->ext_parms) { RETURNFUNC(-RIG_ENOMEM); } RETURNFUNC(RIG_OK); } /* * modeMapGetTCI * Assumes mode!=NULL * Return the string for TCI for the given hamlib mode */ static const char *modeMapGetTCI(rmode_t modeHamlib) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_tci1x == NULL) { continue; } rig_debug(RIG_DEBUG_TRACE, "%s: checking modeMap[%d]=%.0f to modeHamlib=%.0f, mode_tci1x='%s'\n", __func__, i, (double)modeMap[i].mode_hamlib, (double)modeHamlib, modeMap[i].mode_tci1x); if (modeMap[i].mode_hamlib == modeHamlib && strlen(modeMap[i].mode_tci1x) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s matched mode=%.0f, returning '%s'\n", __func__, (double)modeHamlib, modeMap[i].mode_tci1x); return (modeMap[i].mode_tci1x); } } rig_debug(RIG_DEBUG_ERR, "%s: FlRig does not have mode: %s\n", __func__, rig_strrmode(modeHamlib)); return ("ERROR"); } /* * modeMapGetHamlib * Assumes mode!=NULL * Return the hamlib mode from the given TCI string */ static rmode_t modeMapGetHamlib(const char *modeTCI) { int i; char modeTCICheck[MAXBUFLEN + 2]; SNPRINTF(modeTCICheck, sizeof(modeTCICheck), "|%s|", modeTCI); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { rig_debug(RIG_DEBUG_TRACE, "%s: find '%s' in '%s'\n", __func__, modeTCICheck, modeMap[i].mode_tci1x); if (modeMap[i].mode_tci1x && strcmp(modeMap[i].mode_tci1x, modeTCICheck) == 0) { return (modeMap[i].mode_hamlib); } } rig_debug(RIG_DEBUG_TRACE, "%s: mode requested: %s, not in modeMap\n", __func__, modeTCI); return (RIG_MODE_NONE); } /* * modeMapAdd * Assumes modes!=NULL */ static void modeMapAdd(rmode_t *modes, rmode_t mode_hamlib, char *mode_tci1x) { int i; int len1; rig_debug(RIG_DEBUG_TRACE, "%s:mode_tci1x=%s\n", __func__, mode_tci1x); // if we already have it just return // We get ERROR if the mode is not known so non-ERROR is OK if (modeMapGetHamlib(mode_tci1x) != RIG_MODE_NONE) { return; } len1 = strlen(mode_tci1x) + 3; /* bytes needed for allocating */ for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_hamlib == mode_hamlib) { int len2; *modes |= modeMap[i].mode_hamlib; /* we will pipe delimit all the entries for easier matching */ /* all entries will have pipe symbol on both sides */ if (modeMap[i].mode_tci1x == NULL) { modeMap[i].mode_tci1x = calloc(1, len1); if (modeMap[i].mode_tci1x == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: error allocating memory for modeMap\n", __func__); return; } } len2 = strlen(modeMap[i].mode_tci1x); /* current len w/o null */ modeMap[i].mode_tci1x = realloc(modeMap[i].mode_tci1x, strlen(modeMap[i].mode_tci1x) + len1); if (strlen(modeMap[i].mode_tci1x) == 0) { modeMap[i].mode_tci1x[0] = '|'; } strncat(modeMap[i].mode_tci1x, mode_tci1x, len1 + len2); strncat(modeMap[i].mode_tci1x, "|", len1 + len2); rig_debug(RIG_DEBUG_TRACE, "%s: Adding mode=%s, index=%d, result=%s\n", __func__, mode_tci1x, i, modeMap[i].mode_tci1x); return; } } } /* * tci1x_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int tci1x_open(RIG *rig) { int retval; int trx_count = 0; char value[MAXBUFLEN]; char arg[MAXBUFLEN]; rmode_t modes; char *p; char *pr; //struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; arg[0] = '?'; arg[1] = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: version %s\n", __func__, rig->caps->version); char *websocket = "GET / HTTP/1.1\r\nHost: localhost:50001\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: TnwnvtFT6akIBYQC7nh3vA==\r\nSec-WebSocket-Version: 13\r\n\r\n"; write_transaction(rig, (unsigned char *) websocket, strlen(websocket)); do { retval = read_transaction(rig, (unsigned char *) value, sizeof(value)); rig_debug(RIG_DEBUG_VERBOSE, "%s: value=%s\n", __func__, value); } while (retval == RIG_OK && strlen(value) > 0); retval = tci1x_transaction(rig, "device;", NULL, value, sizeof(value)); dump_hex((unsigned char *)value, strlen(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: DEVICE failed: %s\n", __func__, rigerror(retval)); // we fall through and assume old version } sscanf(&value[2], "device:%8191s", value); rig_debug(RIG_DEBUG_VERBOSE, "%s: TCI Device is %s\n", __func__, arg); // Receive only retval = tci1x_transaction(rig, "receive_only;", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: RECEIVE_ONLY failed: %s\n", __func__, rigerror(retval)); } sscanf(&value[2], "receive_only:%8191s", value); rig_debug(RIG_DEBUG_VERBOSE, "%s: readonly is %8191s\n", __func__, arg); // TRX count retval = tci1x_transaction(rig, "trx_count;", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: TRX_COUNT failed..not fatal: %s\n", __func__, rigerror(retval)); } sscanf(&value[2], "trx_count:%d", &trx_count); rig_debug(RIG_DEBUG_VERBOSE, "Trx count=%d\n", trx_count); freq_t freq; retval = tci1x_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tci1x_get_freq not working!!\n", __func__); } STATE(rig)->current_vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo), value); //tci1x_get_split_vfo(rig, vfo, &priv->split, &vfo_tx); RETURNFUNC2(RIG_OK); /* find out available widths and modes */ retval = tci1x_transaction(rig, "modulations_list;", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(&value[2], "modulations_list:%8191s", arg); rig_debug(RIG_DEBUG_VERBOSE, "%s: modes=%s\n", __func__, arg); modes = 0; pr = value; /* The following modes in TCI are not implemented yet A1A AM-2 AM6.0 AM-D1 -- doesn't appear to be read/set AM-D2 -- doesn't appear to be read/set AM-D3 -- doesn't appear to be read/set AMW -- don't have mode in rig.h CW2.4 -- could be CW CW500 -- could be CWN but CWN not in rig.h CW-N -- could be CWN but CWN not in rig.h CWN -- dcould be CWN but CWN not in rig.h CW-NR -- don't have mode in rig.h DATA2-LSB DV DV-R F1B FM-D1 -- doesn't appear to be read/set FM-D2 -- doesn't appear to be read/set FM-D3 -- doesn't appear to be read/set H3E M11 USB-D -- doesn't appear to be read/set USB-D1 -- doesn't appear to be read/set USB-D2 -- doesn't appear to be read/set USB-D3 -- doesn't appear to be read/set USER-L -- doesn't appear to be read/set USER-U -- doesn't appear to be read/set */ for (p = strtok_r(value, ",", &pr); p != NULL; p = strtok_r(NULL, ",", &pr)) { if (streq(p, "AM-D")) { modeMapAdd(&modes, RIG_MODE_PKTAM, p); } else if (streq(p, "AM")) { modeMapAdd(&modes, RIG_MODE_AM, p); } else if (streq(p, "AM-N")) { modeMapAdd(&modes, RIG_MODE_AMN, p); } else if (streq(p, "AMN")) { modeMapAdd(&modes, RIG_MODE_AMN, p); } else if (streq(p, "CW")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CW-L")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-LSB")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-R")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-U")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CW-USB")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CWL")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CWU")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "D-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "D-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA-FM")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } else if (streq(p, "DATA-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-R")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIG")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIGI")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIGL")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DIGU")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DSB")) { modeMapAdd(&modes, RIG_MODE_DSB, p); } else if (streq(p, "FM")) { modeMapAdd(&modes, RIG_MODE_FM, p); } else if (streq(p, "FM-D")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } else if (streq(p, "FMN")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } else if (streq(p, "FM-N")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } else if (streq(p, "FMW")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "FSK")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "FSK-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "LCW")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "LSB")) { modeMapAdd(&modes, RIG_MODE_LSB, p); } else if (streq(p, "LSB-D")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "LSB-D1")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } 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-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, "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); } else if (streq(p, "PSK-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "RTTY-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "RTTY-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY(U)")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY(R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "SAH")) { modeMapAdd(&modes, RIG_MODE_SAH, p); } else if (streq(p, "SAL")) { modeMapAdd(&modes, RIG_MODE_SAL, p); } else if (streq(p, "SAM")) { modeMapAdd(&modes, RIG_MODE_SAM, p); } else if (streq(p, "USB")) { modeMapAdd(&modes, RIG_MODE_USB, p); } else if (streq(p, "USB-D")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USB-D1")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USB-D2")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USB-D3")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USER-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USER-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "W-FM")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "WFM")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "UCW")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "C4FM")) { modeMapAdd(&modes, RIG_MODE_C4FM, p); } else if (streq(p, "SPEC")) { modeMapAdd(&modes, RIG_MODE_SPEC, p); } else if (streq(p, "DRM")) // we don't support DRM yet (or maybe ever) { rig_debug(RIG_DEBUG_VERBOSE, "%s: no mapping for mode %s\n", __func__, p); } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode (new?) for this rig='%s'\n", __func__, p); } } STATE(rig)->mode_list = modes; retval = rig_strrmodes(modes, value, sizeof(value)); if (retval != RIG_OK) // we might get TRUNC but we can still print the debug { rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_VERBOSE, "%s: hamlib modes=%s\n", __func__, value); RETURNFUNC2(retval); } /* * tci1x_close * Assumes rig!=NULL */ static int tci1x_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * tci1x_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int tci1x_cleanup(RIG *rig) { struct tci1x_priv_data *priv; ENTERFUNC; priv = (struct tci1x_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* * tci1x_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int tci1x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char value[MAXARGLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = vfo == RIG_VFO_A ? "vfo:0:0;" : "vfo:0:1:"; int retval; int n; retval = tci1x_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tci1x_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } n = sscanf(&value[2], "vfo:%*d,%*d,%lf", freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: got '%s', scanned %d items\n", __func__, value, n); if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * tci1x_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int tci1x_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } else if (vfo == RIG_VFO_TX && priv->split) { vfo = RIG_VFO_B; // if split always TX on VFOB } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.0f", freq); value_t val; rig_get_ext_parm(rig, TOK_TCI1X_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set_verify_vfoA/B=%d\n", __func__, val.i); if (vfo == RIG_VFO_A) { cmd = "rig.set_vfoA"; if (val.i) { cmd = "rig.set_verify_vfoA"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqA = freq; } else { cmd = "rig.set_vfoB"; if (val.i) { cmd = "rig.set_verify_vfoB"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqB = freq; } retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * tci1x_set_ptt * Assumes rig!=NULL */ static int tci1x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_arg[MAXARGLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", ptt); value_t val; char *cmd = "rig.set_ptt"; rig_get_ext_parm(rig, TOK_TCI1X_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: fast_set_ptt=%d\n", __func__, val.i); if (val.i) { cmd = "rig.set_ptt_fast"; } retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->ptt = ptt; RETURNFUNC(RIG_OK); } /* * tci1x_get_ptt * Assumes rig!=NUL, ptt!=NULL */ static int tci1x_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char value[MAXCMDLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); int retval; retval = tci1x_transaction(rig, "rig.get_ptt", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } *ptt = atoi(value); rig_debug(RIG_DEBUG_TRACE, "%s: '%s'\n", __func__, value); priv->ptt = *ptt; RETURNFUNC(RIG_OK); } /* * tci1x_set_split_mode * Assumes rig!=NULL */ static int tci1x_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (vfo) { case RIG_VFO_CURR: vfo = STATE(rig)->current_vfo; break; case RIG_VFO_TX: vfo = RIG_VFO_B; break; } // If no change don't do it...modes are kept up to date by client calls // to get_mode and set_mode so should be current here rig_debug(RIG_DEBUG_TRACE, "%s: vfoa privmode=%s\n", __func__, rig_strrmode(priv->curr_modeA)); rig_debug(RIG_DEBUG_TRACE, "%s: vfob privmode=%s\n", __func__, rig_strrmode(priv->curr_modeB)); // save some VFO swapping .. may replace with VFO specific calls that won't cause VFO change if (vfo == RIG_VFO_A && mode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_B && mode == priv->curr_modeB) { RETURNFUNC(RIG_OK); } retval = tci1x_set_mode(rig, vfo, mode, width); rig_debug(RIG_DEBUG_TRACE, "%s: set mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(retval); } /* * tci1x_set_mode * Assumes rig!=NULL */ static int tci1x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; int needBW; int vfoSwitched; char cmd_arg[MAXCMDLEN]; char *p; char *pttmode; char *ttmode = NULL; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); // if ptt is on do not set mode if (priv->ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: returning because priv->ptt=%d\n", __func__, (int)priv->ptt); RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate since we can't set mode directly // MDB vfoSwitched = 0; rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo = %s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); // If we don't have the get_bwA call we have to switch VFOs ourself if (!priv->has_get_bwA && vfo == RIG_VFO_B && STATE(rig)->current_vfo != RIG_VFO_B) { vfoSwitched = 1; rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOB = %d\n", __func__, vfoSwitched); } if (vfoSwitched) // swap to B and we'll swap back later { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOB = %d\n", __func__, vfoSwitched); retval = tci1x_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } // Set the mode if (modeMapGetTCI(mode)) { ttmode = strdup(modeMapGetTCI(mode)); } else { rig_debug(RIG_DEBUG_ERR, "%s: modeMapGetFlRig failed on mode=%d\n", __func__, (int)mode); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: got ttmode = %s\n", __func__, ttmode == NULL ? "NULL" : ttmode); if (ttmode == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: strdup failed\n", __func__); RETURNFUNC(-RIG_EINTERNAL); } // if (strncmp(ttmode,"ERROR",5)==0) RETURNFUNC(-RIG_EINTERN); pttmode = ttmode; if (ttmode[0] == '|') { pttmode = &ttmode[1]; } // remove first pipe symbol p = strchr(pttmode, '|'); if (p) { *p = 0; } // remove any other pipe SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", pttmode); free(ttmode); if (!priv->has_get_modeA) { retval = tci1x_transaction(rig, "rig.set_mode", cmd_arg, NULL, 0); } else { char *cmd = "rig.set_modeA"; if (vfo == RIG_VFO_B) { cmd = "rig.set_modeB"; } else { // we make VFO_B mode unknown so it expires the cache priv->curr_modeB = RIG_MODE_NONE; } retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // Determine if we need to update the bandwidth needBW = 0; if (vfo == RIG_VFO_A) { needBW = priv->curr_widthA != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOA, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else if (vfo == RIG_VFO_B) { needBW = priv->curr_widthB != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOB, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else { rig_debug(RIG_DEBUG_TRACE, "%s: needBW unknown vfo=%s\n", __func__, rig_strvfo(vfo)); } // Need to update the bandwidth if (width > 0 && needBW) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%ld", width); retval = tci1x_transaction(rig, "rig.set_bandwidth", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } } // Return to VFOA if needed rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOA? = %d\n", __func__, vfoSwitched); if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOA\n", __func__); retval = tci1x_set_vfo(rig, RIG_VFO_A); if (retval < 0) { RETURNFUNC(retval); } } if (vfo == RIG_VFO_A) { priv->curr_modeA = mode; priv->curr_widthA = width; } else { priv->curr_modeB = mode; priv->curr_widthB = width; } rig_debug(RIG_DEBUG_TRACE, "%s: Return modeA=%s, widthA=%d\n,modeB=%s, widthB=%d\n", __func__, rig_strrmode(priv->curr_modeA), (int)priv->curr_widthA, rig_strrmode(priv->curr_modeB), (int)priv->curr_widthB); RETURNFUNC(RIG_OK); } /* * tci1x_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int tci1x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int vfoSwitched; char value[MAXCMDLEN]; char *cmdp; vfo_t curr_vfo; rmode_t my_mode; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } curr_vfo = STATE(rig)->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->ptt) { if (vfo == RIG_VFO_A) { *mode = priv->curr_modeA; } else { *mode = priv->curr_modeB; } rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate vfoSwitched = 0; if (priv->has_get_modeA == 0 && vfo == RIG_VFO_B && curr_vfo != RIG_VFO_B) { vfoSwitched = 1; } if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s switch to VFOB=%d\n", __func__, priv->has_get_modeA); retval = tci1x_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } cmdp = "rig.get_mode"; /* default to old way */ if (priv->has_get_modeA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in tci1x */ /* vfo B may not be getting polled though in TCI */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_modeA"; if (vfo == RIG_VFO_B) { cmdp = "rig.get_modeB"; } } retval = tci1x_transaction(rig, cmdp, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, cmdp, rigerror(retval)); RETURNFUNC(retval); } my_mode = modeMapGetHamlib(value); *mode = my_mode; rig_debug(RIG_DEBUG_TRACE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); if (vfo == RIG_VFO_A) { priv->curr_modeA = *mode; } else { priv->curr_modeB = *mode; } /* Get the bandwidth */ cmdp = "rig.get_bw"; /* default to old way */ if (priv->has_get_bwA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in tci1x */ /* vfo B may not be getting polled though in TCI */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_bwA"; if (vfo == RIG_VFO_B) { cmdp = "rig.get_bwB"; } } retval = tci1x_transaction(rig, cmdp, NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: mode=%s width='%s'\n", __func__, rig_strrmode(*mode), value); // we get 2 entries pipe separated for bandwidth, lower and upper if (strlen(value) > 0) { char *p = value; /* we might get two values and then we want the 2nd one */ if (strchr(value, '|') != NULL) { p = strchr(value, '|') + 1; } *width = atoi(p); } if (vfo == RIG_VFO_A) { priv->curr_widthA = *width; } else { priv->curr_widthB = *width; } // Return to VFOA if needed if (vfoSwitched) { retval = tci1x_set_vfo(rig, RIG_VFO_A); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * tci1x_set_vfo * assumes rig!=NULL */ static int tci1x_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd_arg[MAXBUFLEN]; struct rig_state *rs = STATE(rig); const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX used\n", __func__); vfo = RIG_VFO_B; // always TX on VFOB } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", vfo == RIG_VFO_A ? "A" : "B"); retval = tci1x_transaction(rig, "rig.set_AB", cmd_arg, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig.set_AB failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } STATE(rig)->current_vfo = vfo; rs->tx_vfo = RIG_VFO_B; // always VFOB /* for some rigs TCI turns off split when VFOA is selected */ /* so if we are in split and asked for A we have to turn split back on */ if (priv->split && vfo == RIG_VFO_A) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", priv->split); retval = tci1x_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * tci1x_get_vfo * assumes rig!=NULL, vfo != NULL */ static int tci1x_get_vfo(RIG *rig, vfo_t *vfo) { char value[MAXCMDLEN]; ENTERFUNC; int retval; retval = tci1x_transaction(rig, "rig.get_AB", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo value=%s\n", __func__, value); switch (value[0]) { case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; default: *vfo = RIG_VFO_CURR; RETURNFUNC(-RIG_EINVAL); } if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(-RIG_EINVAL); } STATE(rig)->current_vfo = *vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(RIG_OK); } /* * tci1x_set_split_freq * assumes rig!=NULL */ static int tci1x_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int retval; char cmd_arg[MAXBUFLEN]; freq_t qtx_freq; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), tx_freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } // we always split on VFOB so if no change just return retval = tci1x_get_freq(rig, RIG_VFO_B, &qtx_freq); if (retval != RIG_OK) { RETURNFUNC(retval); } if (tx_freq == qtx_freq) { RETURNFUNC(RIG_OK); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.6f", tx_freq); retval = tci1x_transaction(rig, "rig.set_vfoB", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->curr_freqB = tx_freq; RETURNFUNC(RIG_OK); } /* * tci1x_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ static int tci1x_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = tci1x_get_freq(rig, RIG_VFO_B, tx_freq); priv->curr_freqB = *tx_freq; RETURNFUNC(retval); } /* * tci1x_set_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int tci1x_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; vfo_t qtx_vfo; split_t qsplit; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; char cmd_arg[MAXBUFLEN]; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__, rig_strvfo(tx_vfo)); retval = tci1x_get_split_vfo(rig, RIG_VFO_A, &qsplit, &qtx_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } if (split == qsplit) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", split); retval = tci1x_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->split = split; RETURNFUNC(RIG_OK); } /* * tci1x_get_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int tci1x_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { char value[MAXCMDLEN]; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; int retval; retval = tci1x_transaction(rig, "rig.get_split", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } *tx_vfo = RIG_VFO_B; *split = atoi(value); priv->split = *split; rig_debug(RIG_DEBUG_TRACE, "%s tx_vfo=%s, split=%d\n", __func__, rig_strvfo(*tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * tci1x_set_split_freq_mode * assumes rig!=NULL */ static int tci1x_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; rmode_t qmode; pbwidth_t qwidth; struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE(rig)->priv; ENTERFUNC; // we always do split on VFOB retval = tci1x_set_freq(rig, RIG_VFO_B, freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s tci1x_set_freq failed\n", __func__); RETURNFUNC(retval); } // Make VFOB mode match VFOA mode, keep VFOB width retval = tci1x_get_mode(rig, RIG_VFO_B, &qmode, &qwidth); if (retval != RIG_OK) { RETURNFUNC(retval); } if (qmode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } retval = tci1x_set_mode(rig, RIG_VFO_B, priv->curr_modeA, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s tci1x_set_mode failed\n", __func__); RETURNFUNC(retval); } retval = tci1x_set_vfo(rig, RIG_VFO_A); RETURNFUNC(retval); } /* * tci1x_get_split_freq_mode * assumes rig!=NULL, freq!=NULL, mode!=NULL, width!=NULL */ static int tci1x_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; ENTERFUNC; if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX) { RETURNFUNC(-RIG_ENTARGET); } retval = tci1x_get_freq(rig, RIG_VFO_B, freq); if (RIG_OK == retval) { retval = tci1x_get_mode(rig, vfo, mode, width); } RETURNFUNC(retval); } #ifdef XXNOTIMPLEMENTED static int tci1x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; char *param_type = "i4"; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s level=%d, val=%f\n", __func__, rig_strvfo(vfo), (int)level, val.f); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } switch (level) { case RIG_LEVEL_RF: cmd = "rig.set_rfgain"; val.f *= 100; break; case RIG_LEVEL_AF: cmd = "rig.set_volume"; val.f *= 100; break; case RIG_LEVEL_MICGAIN: cmd = "rig.set_micgain"; val.f *= 100; break; case RIG_LEVEL_RFPOWER: cmd = "rig.set_power"; val.f *= 100; break; default: rig_debug(RIG_DEBUG_ERR, "%s: invalid level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "<%s>%d", param_type, (int)val.f, param_type); retval = tci1x_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * tci1x_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ static int tci1x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char value[MAXARGLEN]; char *cmd; int retval; const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: cmd = "rig.get_volume"; break; case RIG_LEVEL_RF: cmd = "rig.get_rfgain"; break; case RIG_LEVEL_MICGAIN: cmd = "rig.get_micgain"; break; case RIG_LEVEL_STRENGTH: cmd = "rig.get_smeter"; break; case RIG_LEVEL_RFPOWER: cmd = "rig.get_power"; break; case RIG_LEVEL_RFPOWER_METER_WATTS: case RIG_LEVEL_RFPOWER_METER: cmd = "rig.get_pwrmeter"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } retval = tci1x_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tci1x_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // most levels are 0-100 -- may have to allow for different ranges switch (level) { case RIG_LEVEL_STRENGTH: val->i = atoi(value) - 54; //if (val->i > 0) val->i /= 10; rig_debug(RIG_DEBUG_TRACE, "%s: val.i='%s'(%d)\n", __func__, value, val->i); break; case RIG_LEVEL_RFPOWER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER_WATTS: val->f = atof(value) * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; default: val->f = atof(value) / 100; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%f)\n", __func__, value, val->f); } RETURNFUNC(RIG_OK); } #endif /* * tci1x_get_info * assumes rig!=NULL */ static const char *tci1x_get_info(RIG *rig) { const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; return (priv->info); } static int tci1x_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const struct tci1x_priv_data *priv = (struct tci1x_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); power *= priv->powermeter_scale; *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int tci1x_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } #ifdef XXNOTIMPLEMENTED static int tci1x_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_TCI1X_VERIFY_FREQ: case TOK_TCI1X_VERIFY_PTT: if (val.i && !priv->has_verify_cmds) { rig_debug(RIG_DEBUG_ERR, "%s: FLRig version 1.3.54.18 or higher needed to support fast functions\n", __func__); RETURNFUNC(-RIG_EINVAL); } break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int tci1x_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; /* TODO: load value from priv->ext_parms */ cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_TCI1X_VERIFY_FREQ: case TOK_TCI1X_VERIFY_PTT: break; default: RETURNFUNC(-RIG_EINVAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int tci1x_set_ext_parm(RIG *rig, setting_t parm, value_t val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; int idx; char pstr[32]; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; RETURNFUNC(RIG_OK); } static int tci1x_get_ext_parm(RIG *rig, setting_t parm, value_t *val) { struct tci1x_priv_data *priv = (struct tci1x_priv_data *)STATE(rig)->priv; int idx; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); RETURNFUNC(RIG_OK); } #endif hamlib-4.6.2/rigs/dummy/rot_pstrotator.c0000644000175000017500000003425614752216205015266 00000000000000/* i Hamlib PSTRotator backend * Copyright (c) 2024 Michael Black W9MDB * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include #include #include "hamlib/rotator.h" #include "dummy_common.h" #include "rig.h" #include "register.h" #include "idx_builtin.h" #include "misc.h" #include "iofunc.h" #include "rot_pstrotator.h" #include "rotlist.h" #include "network.h" #define PSTROTATOR_ROT_FUNC 0 #define PSTROTATOR_ROT_LEVEL ROT_LEVEL_SPEED #define PSTROTATOR_ROT_PARM 0 #define PSTROTATOR_ROT_STATUS (ROT_STATUS_MOVING | ROT_STATUS_MOVING_AZ | ROT_STATUS_MOVING_LEFT | ROT_STATUS_MOVING_RIGHT | \ ROT_STATUS_MOVING_EL | ROT_STATUS_MOVING_UP | ROT_STATUS_MOVING_DOWN ) struct pstrotator_rot_priv_data { azimuth_t az; elevation_t el; struct timeval tv; /* time last az/el update */ azimuth_t target_az; elevation_t target_el; rot_status_t status; int sockfd2; // the reply port for PSTRotator which is port+1 pthread_t threadid; int receiving; // true if we are receiving az/el data }; static int write_transaction(ROT *rot, char *cmd) { int try = rot->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = ROTPORT(rot); // This shouldn't ever happen...but just in case // We need to avoid an empty write as rotctld replies with blank line if (strlen(cmd) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); return (retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { char cmd2[64]; if (strchr(cmd, '\r') == NULL) { sprintf(cmd2, "%s\r", cmd); } retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return (-RIG_EIO); } } return RIG_OK; } static void set_timeout(int fd, int sec, int usec) { struct timeval timeout; timeout.tv_sec = sec; timeout.tv_usec = usec; //rig_debug(RIG_DEBUG_VERBOSE, "%s: sec=%d, usec=%d, timeout = %.6lf\n", __func__, // sec, usec, sec + usec / 1e6); if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: setsockopt failed: %s\n", __func__, strerror(errno)); } } void readPacket(int sockfd, char *buf, int buf_len, int expected) { struct sockaddr_in serverAddr; socklen_t addrLen = sizeof(serverAddr); buf[0] = 0; if (expected) { set_timeout(sockfd, 1, 0); } else { set_timeout(sockfd, 0, 0); } ssize_t n = recvfrom(sockfd, buf, buf_len, 0, (struct sockaddr *)&serverAddr, &addrLen); if (n < 0) { #ifdef _WIN32 int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK || err == WSAETIMEDOUT) { #if 0 if (expected) rig_debug(RIG_DEBUG_ERR, "%s: recvfrom timed out. Is PSTRotator Setup/UDP Control enabled?\n", __func__); #endif } else { rig_debug(RIG_DEBUG_ERR, "%s: recvfrom error %d: %s\n", __func__, err, strerror(errno)); } #else if (errno == EWOULDBLOCK || errno == EAGAIN) { if (expected) rig_debug(RIG_DEBUG_ERR, "%s: recvfrom timed out. Is PSTRotator Setup/UDP Control checked?\n", __func__); } else { rig_debug(RIG_DEBUG_ERR, "%s: recvfrom error: %s\n", __func__, strerror(errno)); } #endif n = 0; } buf[n] = '\0'; // Null-terminate the received data strtok(buf, "\r\n"); // get rid of CRs and such //if (n > 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: buf=%s\n", __func__, buf); } } #if defined(HAVE_PTHREAD) #if 0 typedef struct pstrotator_handler_args_sw { int port; // port for reading PstRotator messages -- always +1 from base port } pstrotator_handler_args; typedef struct pstrotator_handler_priv_data_s { pthread_t thread_id; pstrotator_handler_args args; } pstrotator_handler_priv_data; #endif static void *pstrotator_handler_start(void *arg) { ROT *rot = (ROT *)arg; struct rot_state *rs = STATE(rot); struct pstrotator_rot_priv_data *priv = rs->priv; pstrotator_handler_priv_data *pstrotator_handler_priv; rs->pstrotator_handler_priv_data = calloc(1, sizeof(pstrotator_handler_priv_data)); if (rs->pstrotator_handler_priv_data == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: priv is NULL?\n", __func__); return NULL; } pstrotator_handler_priv = (pstrotator_handler_priv_data *) rs->pstrotator_handler_priv_data; pstrotator_handler_priv->args.rot = rot; pstrotator_handler_priv->pstrotator_handler_thread_run = 1; priv->receiving = 0; while (pstrotator_handler_priv->pstrotator_handler_thread_run) { int az = 0, el = 0; char buf[256]; readPacket(priv->sockfd2, buf, sizeof(buf), 1); if (strlen(buf) == 0) { hl_usleep(20 * 1000); continue; } //dump_hex((unsigned char *)buf, strlen(buf)); int n = sscanf(buf, "AZ:%g", &priv->az); n += sscanf(buf, "EL:%g", &priv->el); if (n > 0) { priv->receiving = 1; } if (priv->az != az && priv->el != el) { priv->status = ROT_STATUS_MOVING; } else if (priv->az < az) { priv->status = ROT_STATUS_MOVING_LEFT; } else if (priv->az > az) { priv->status = ROT_STATUS_MOVING_RIGHT; } else if (priv->el < el) { priv->status = ROT_STATUS_MOVING_DOWN; } else if (priv->el > el) { priv->status = ROT_STATUS_MOVING_UP; } else { priv->status = ROT_STATUS_NONE; } //if (n > 0) rig_debug(RIG_DEBUG_CACHE, "%s: az=%.1f, el=%.1f\n", __func__, priv->az, priv->el); } return NULL; } #endif static int pstrotator_rot_init(ROT *rot) { struct pstrotator_rot_priv_data *priv; struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rs->priv = (struct pstrotator_rot_priv_data *) calloc(1, sizeof(struct pstrotator_rot_priv_data)); if (!rs->priv) { return -RIG_ENOMEM; } priv = rs->priv; ROTPORT(rot)->type.rig = RIG_PORT_UDP_NETWORK; priv->az = priv->el = 0; priv->target_az = priv->target_el = 0; strcpy(ROTPORT(rot)->pathname, "192.168.56.1:12000"); return RIG_OK; } static int pstrotator_rot_cleanup(ROT *rot) { struct rot_state *rs = ROTSTATE(rot); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); free(rs->priv); rs->priv = NULL; return RIG_OK; } static int pstrotator_rot_open(ROT *rot) { struct pstrotator_rot_priv_data *priv; int port = 0; int n1, n2, n3, n4; int sockfd; int retval; struct sockaddr_in clientAddr; struct rot_state *rs = ROTSTATE(rot); pthread_attr_t attr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct pstrotator_rot_priv_data *)rs->priv; //priv->port2 = rs->rotport; //priv->port2.type.rig = RIG_PORT_UDP_NETWORK; rig_debug(RIG_DEBUG_VERBOSE, "%s: pathname=%s\n", __func__, ROTPORT(rot)->pathname); sscanf(ROTPORT(rot)->pathname, "%d.%d.%d.%d:%d", &n1, &n2, &n3, &n4, &port); //sprintf(priv->port2.pathname, "%d.%d.%d.%d:%d", n1, n2, n3, n4, port+1); //rig_debug(RIG_DEBUG_VERBOSE, "%s: port2 pathname=%s\n", __func__, priv->port2.pathname); //network_open(&priv->port2, port+1); if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: socket failed: %s\n", __func__, strerror(errno)); return -RIG_EINTERNAL; } // Bind socket to client address memset(&clientAddr, 0, sizeof(clientAddr)); clientAddr.sin_family = AF_INET; clientAddr.sin_addr.s_addr = INADDR_ANY; clientAddr.sin_port = htons(12001); if (bind(sockfd, (const struct sockaddr *)&clientAddr, sizeof(clientAddr)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: bind failed: %s\n", __func__, strerror(errno)); return -RIG_EINTERNAL; } priv->sockfd2 = sockfd; set_timeout(priv->sockfd2, 1, 0); pthread_attr_init(&attr); retval = pthread_create(&priv->threadid, &attr, pstrotator_handler_start, rot); if (retval != 0) { rig_debug(RIG_DEBUG_ERR, "%s; pthread_create error: %s\n", __func__, strerror(errno)); return -RIG_EINTERNAL; } return RIG_OK; } static int pstrotator_rot_close(ROT *rot) { struct pstrotator_rot_priv_data *priv; priv = (struct pstrotator_rot_priv_data *)ROTSTATE(rot)->priv; pstrotator_handler_priv_data *pstrotator_handler_priv; pstrotator_handler_priv = (pstrotator_handler_priv_data *) ROTSTATE(rot)->pstrotator_handler_priv_data; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); pstrotator_handler_priv->pstrotator_handler_thread_run = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: waiting for thread to stop\n", __func__); pthread_join(priv->threadid, NULL); rig_debug(RIG_DEBUG_VERBOSE, "%s: thread stopped\n", __func__); priv->threadid = 0; return RIG_OK; } #if 0 static int pstrotator_set_conf(ROT *rot, hamlib_token_t token, const char *val) { struct pstrotator_rot_priv_data *priv; priv = (struct pstrotator_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: if (val) { free(priv->magic_conf); priv->magic_conf = strdup(val); } break; default: return -RIG_EINVAL; } return RIG_OK; } #endif #if 0 static int pstrotator_get_conf2(ROT *rot, hamlib_token_t token, char *val, int val_len) { struct pstrotator_rot_priv_data *priv; priv = (struct pstrotator_rot_priv_data *)ROTSTATE(rot)->priv; switch (token) { case TOK_CFG_ROT_MAGICCONF: SNPRINTF(val, val_len, "%s", priv->magic_conf); break; default: return -RIG_EINVAL; } return RIG_OK; } #endif #if 0 static int pstrotator_get_conf(ROT *rot, hamlib_token_t token, char *val) { return pstrotator_get_conf2(rot, token, val, 128); } #endif static int pstrotator_rot_set_position(ROT *rot, azimuth_t az, elevation_t el) { struct pstrotator_rot_priv_data *priv = (struct pstrotator_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %.2f %.2f\n", __func__, az, el); char cmd[64]; sprintf(cmd, "%f.2", az); write_transaction(rot, cmd); sprintf(cmd, "%f.2", el); write_transaction(rot, cmd); priv->az = az; priv->el = el; return RIG_OK; } /* * Get position of rotor, simulating slow rotation */ static int pstrotator_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { struct pstrotator_rot_priv_data *priv = (struct pstrotator_rot_priv_data *) ROTSTATE(rot)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); write_transaction(rot, "AZ?"); write_transaction(rot, "EL?"); hl_usleep(10 * 1000); *az = priv->az; *el = priv->el; return RIG_OK; } static int pstrotator_rot_park(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); write_transaction(rot, "1"); return RIG_OK; } static const char *pstrotator_rot_get_info(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "PSTRotator"; } static int pstrotator_rot_get_status(ROT *rot, rot_status_t *status) { const struct pstrotator_rot_priv_data *priv = (struct pstrotator_rot_priv_data *) ROTSTATE(rot)->priv; *status = priv->status; return RIG_OK; } /* * Dummy rotator capabilities. */ struct rot_caps pstrotator_caps = { ROT_MODEL(ROT_MODEL_PSTROTATOR), .model_name = "PstRotator", .mfg_name = "YO3DMU", .version = "20240613.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_UDP_NETWORK, .timeout = 1000, .min_az = -180., .max_az = 450., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .has_get_func = PSTROTATOR_ROT_FUNC, .has_set_func = PSTROTATOR_ROT_FUNC, .has_get_level = PSTROTATOR_ROT_LEVEL, .has_set_level = ROT_LEVEL_SET(PSTROTATOR_ROT_LEVEL), .has_get_parm = PSTROTATOR_ROT_PARM, .has_set_parm = ROT_PARM_SET(PSTROTATOR_ROT_PARM), //.level_gran = { [ROT_LVL_SPEED] = { .min = { .i = 1 }, .max = { .i = 4 }, .step = { .i = 1 } } }, .has_status = PSTROTATOR_ROT_STATUS, .rot_init = pstrotator_rot_init, .rot_cleanup = pstrotator_rot_cleanup, .rot_open = pstrotator_rot_open, .rot_close = pstrotator_rot_close, .set_position = pstrotator_rot_set_position, .get_position = pstrotator_rot_get_position, .park = pstrotator_rot_park, .get_info = pstrotator_rot_get_info, .get_status = pstrotator_rot_get_status, }; hamlib-4.6.2/rigs/dummy/amp_dummy.h0000644000175000017500000000203414752216205014143 00000000000000/* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AMP_DUMMY_H #define _AMP_DUMMY_H 1 #include "amplifier.h" extern const struct amp_caps dummy_amp_caps; extern const struct amp_caps netampctl_caps; #endif /* _AMP_DUMMY_H */ hamlib-4.6.2/rigs/dummy/flrig.c0000644000175000017500000022555314752216205013266 00000000000000/* * Hamlib FLRig backend - main file * Copyright (c) 2017 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include #include #include #include "dummy_common.h" #include "flrig.h" #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define MAXCMDLEN 8192 #define MAXXMLLEN 8192 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:12345" #define FLRIG_VFOS (RIG_VFO_A|RIG_VFO_B) #define FLRIG_MODES (RIG_MODE_AM | RIG_MODE_PKTAM | RIG_MODE_CW | RIG_MODE_CWR |\ RIG_MODE_RTTY | RIG_MODE_RTTYR |\ RIG_MODE_PKTLSB | RIG_MODE_PKTUSB |\ RIG_MODE_SSB | RIG_MODE_LSB | RIG_MODE_USB |\ RIG_MODE_FM | RIG_MODE_WFM | RIG_MODE_FMN | RIG_MODE_PKTFM |\ RIG_MODE_C4FM | RIG_MODE_DSTAR) #define FLRIG_LEVELS (RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_MICGAIN | RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER_METER | RIG_LEVEL_RFPOWER_METER_WATTS | RIG_LEVEL_RFPOWER | RIG_LEVEL_SWR) #define FLRIG_PARM (TOK_FLRIG_VERIFY_FREQ|TOK_FLRIG_VERIFY_PTT) #define streq(s1,s2) (strcmp(s1,s2)==0) static int flrig_init(RIG *rig); static int flrig_open(RIG *rig); static int flrig_close(RIG *rig); static int flrig_cleanup(RIG *rig); static int flrig_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int flrig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int flrig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int flrig_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int flrig_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int flrig_get_vfo(RIG *rig, vfo_t *vfo); static int flrig_set_vfo(RIG *rig, vfo_t vfo); static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int flrig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int flrig_set_func(RIG *rig, vfo_t vfo, setting_t setting, int status); static int flrig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int flrig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int flrig_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int flrig_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int flrig_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int flrig_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static int flrig_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int flrig_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int flrig_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int flrig_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); static const char *flrig_get_info(RIG *rig); static int flrig_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int flrig_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); struct flrig_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set returned from flrig */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_set_bwA; /* True if this function is available */ int has_verify_cmds; // has the verify cmd in FLRig 1.3.54.1 or higher float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; int get_SWR; int has_get_modeB; /* True if this function is available */ int has_get_bwB; /* True if this function is available */ int has_set_bwB; /* True if this function is available */ }; /* level's and parm's tokens */ #define TOK_FLRIG_VERIFY_FREQ TOKEN_BACKEND(1) #define TOK_FLRIG_VERIFY_PTT TOKEN_BACKEND(2) static const struct confparams flrig_ext_parms[] = { { TOK_FLRIG_VERIFY_FREQ, "VERIFY_FREQ", "Verify set_freq", "If true will verify set_freq otherwise is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { TOK_FLRIG_VERIFY_PTT, "VERIFY_PTT", "Verify set_ptt", "If true will verify set_ptt otherwise set_ptt is fire and forget", "0", RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; struct rig_caps flrig_caps = { RIG_MODEL(RIG_MODEL_FLRIG), .model_name = "", .mfg_name = "FLRig", .version = "20250107.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 5000, .retry = 2, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_TUNER, .set_func = flrig_set_func, .has_get_level = FLRIG_LEVELS, .has_set_level = RIG_LEVEL_SET(FLRIG_LEVELS), .has_get_parm = FLRIG_PARM, .has_set_parm = RIG_PARM_SET(FLRIG_PARM), .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = FLRIG_MODES, .low_power = -1, .high_power = -1, FLRIG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = FLRIG_MODES, .low_power = -1, .high_power = -1, FLRIG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {FLRIG_MODES, 1}, {FLRIG_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .extparms = flrig_ext_parms, .rig_init = flrig_init, .rig_open = flrig_open, .rig_close = flrig_close, .rig_cleanup = flrig_cleanup, .set_freq = flrig_set_freq, .get_freq = flrig_get_freq, .set_mode = flrig_set_mode, .get_mode = flrig_get_mode, .set_vfo = flrig_set_vfo, .get_vfo = flrig_get_vfo, .get_info = flrig_get_info, .set_ptt = flrig_set_ptt, .get_ptt = flrig_get_ptt, .set_split_mode = flrig_set_split_mode, .set_split_freq = flrig_set_split_freq, .get_split_freq = flrig_get_split_freq, .set_split_vfo = flrig_set_split_vfo, .get_split_vfo = flrig_get_split_vfo, .set_split_freq_mode = flrig_set_split_freq_mode, .get_split_freq_mode = flrig_get_split_freq_mode, .set_level = flrig_set_level, .get_level = flrig_get_level, .set_ext_parm = flrig_set_ext_parm, .get_ext_parm = flrig_get_ext_parm, .power2mW = flrig_power2mW, .mW2power = flrig_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; //Structure for mapping flrig dynmamic modes to hamlib modes //flrig displays modes as the rig displays them struct s_modeMap { rmode_t mode_hamlib; char *mode_flrig; }; //FLRig will provide us the modes for the selected rig //We will then put them in this struct static struct s_modeMap modeMap[] = { {RIG_MODE_USB, NULL}, {RIG_MODE_LSB, NULL}, {RIG_MODE_PKTUSB, NULL}, {RIG_MODE_PKTLSB, NULL}, {RIG_MODE_AM, NULL}, {RIG_MODE_PKTAM, NULL}, {RIG_MODE_FM, NULL}, {RIG_MODE_PKTFM, NULL}, {RIG_MODE_FMN, NULL}, {RIG_MODE_WFM, NULL}, {RIG_MODE_CW, NULL}, {RIG_MODE_CWR, NULL}, {RIG_MODE_RTTY, NULL}, {RIG_MODE_RTTYR, NULL}, {RIG_MODE_C4FM, NULL}, {RIG_MODE_DSTAR, NULL}, {RIG_MODE_USBD1, NULL}, {RIG_MODE_USBD2, NULL}, {RIG_MODE_USBD3, NULL}, {RIG_MODE_LSBD1, NULL}, {RIG_MODE_LSBD2, NULL}, {RIG_MODE_LSBD3, NULL}, {0, NULL} }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /*Rather than use some huge XML library we only need a few things * So we'll hand craft them * xml_build takes a value and returns an xml string for FLRig */ // cppcheck-suppress constParameterPointer static char *xml_build(RIG *rig, char *cmd, char *value, char *xmlbuf, int xmlbuflen) { char xml[4096]; // we shouldn't need more the 4096 bytes for this char tmp[32]; char *header; // We want at least a 4K buf to play with if (xmlbuflen < 4096) { rig_debug(RIG_DEBUG_ERR, "%s: xmllen < 4096\n", __func__); return NULL; } header = "POST /RPC2 HTTP/1.1\r\n" "User-Agent: XMLRPC++ 0.8\r\n" "Host: 127.0.0.1:12345\r\n" "Content-type: text/xml\r\n"; SNPRINTF(xmlbuf, xmlbuflen, "%s", header); SNPRINTF(xml, sizeof(xml), "\r\n\r\n", RIGPORT(rig)->client_port); strncat(xml, "", sizeof(xml) - 1); strncat(xml, cmd, sizeof(xml) - strlen(xml) - 1); strncat(xml, "\r\n", sizeof(xml) - strlen(xml) - 1); if (value && strlen(value) > 0) { strncat(xml, value, sizeof(xml) - 1); } strncat(xml, "\r\n", sizeof(xml) - 1); strncat(xmlbuf, "Content-length: ", xmlbuflen - 1); SNPRINTF(tmp, sizeof(tmp), "%d\r\n\r\n", (int)strlen(xml)); strncat(xmlbuf, tmp, xmlbuflen - 1); strncat(xmlbuf, xml, xmlbuflen - 1); return xmlbuf; } /*This is a very crude xml parse specific to what we need from FLRig * This works for strings, doubles, I4-type values, and arrays * Arrays are returned pipe delimited */ static char *xml_parse2(char *xml, char *value, int valueLen) { char *delims = "<>\r\n"; char *xmltmp = strdup(xml); //rig_debug(RIG_DEBUG_TRACE, "%s: xml='%s'\n", __func__,xml); char *pr = xml; char *p = strtok_r(xmltmp, delims, &pr); value[0] = 0; while (p) { if (streq(p, "value")) { p = strtok_r(NULL, delims, &pr); if (streq(p, "array")) { continue; } if (streq(p, "/value")) { continue; } // empty value if (streq(p, "i4") || streq(p, "double") || streq(p, "int") || streq(p, "string")) { p = strtok_r(NULL, delims, &pr); } else if (streq(p, "array")) { strtok_r(NULL, delims, &pr); p = strtok_r(NULL, delims, &pr); } if (strlen(value) + strlen(p) + 1 < valueLen) { if (value[0] != 0) { strcat(value, "|"); } strcat(value, p); } else // we'll just stop adding stuff { rig_debug(RIG_DEBUG_ERR, "%s: max value length exceeded\n", __func__); } } else { p = strtok_r(NULL, delims, &pr); } } rig_debug(RIG_DEBUG_TRACE, "%s: value returned='%s'\n", __func__, value); if (rig_need_debug(RIG_DEBUG_WARN) && value != NULL && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: xml='%s'\n", __func__, xml); } free(xmltmp); return value; } /* * xml_parse * Assumes xml!=NULL, value!=NULL, value_len big enough * returns the string value contained in the xml string */ static char *xml_parse(char *xml, char *value, int value_len) { char *next; char *pxml; /* first off we should have an OK on the 1st line */ if (strstr(xml, " 200 OK") == NULL) { return (NULL); } rig_debug(RIG_DEBUG_TRACE, "%s XML:\n%s\n", __func__, xml); // find the xml skipping the other stuff above it pxml = strstr(xml, "=MAXXMLLEN */ static int read_transaction(RIG *rig, char *xml, int xml_len) { int retval; int retry; char *delims; char *terminator = ""; ENTERFUNC; retry = 2; delims = "\n"; xml[0] = 0; do { char tmp_buf[MAXXMLLEN]; // plenty big for expected flrig responses hopefully if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } rig_debug(RIG_DEBUG_TRACE, "%s: before read_string\n", __func__); int len = read_string(RIGPORT(rig), (unsigned char *) tmp_buf, sizeof(tmp_buf), delims, strlen(delims), 0, 1); // "", 17,0,1); rig_debug(RIG_DEBUG_TRACE, "%s: string='%s'\n", __func__, tmp_buf); // if our first response we should see the HTTP header if (strlen(xml) == 0 && strstr(tmp_buf, "HTTP/1.1 200 OK") == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Expected 'HTTP/1.1 200 OK', got '%s'\n", __func__, tmp_buf); continue; // we'll try again } if (len > 0) { retry = 3; } if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } if (strlen(xml) + strlen(tmp_buf) < xml_len - 1) { strncat(xml, tmp_buf, xml_len - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: xml buffer overflow!!\nTrying to add len=%d\nTo len=%d\n", __func__, (int)strlen(tmp_buf), (int)strlen(xml)); RETURNFUNC(-RIG_EPROTO); } } while (retry-- > 0 && strstr(xml, terminator) == NULL); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (strstr(xml, terminator)) { rig_debug(RIG_DEBUG_TRACE, "%s: got %s\n", __func__, terminator); // Slow down just a bit -- not sure this is needed anymore but not a big deal here // hl_usleep(2 * 1000); // try without this retval = RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: did not get %s\n", __func__, terminator); retval = -(101 + RIG_EPROTO); } RETURNFUNC(retval); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, char *xml, int xml_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (xml_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, (unsigned char *) xml, strlen(xml)); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int flrig_transaction(RIG *rig, char *cmd, char *cmd_arg, char *value, int value_len) { char xml[MAXXMLLEN]; int retry = 3; ENTERFUNC; ELAPSED1; set_transaction_active(rig); if (value) { value[0] = 0; } do { char *pxml; int retval; if (retry != 3) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } pxml = xml_build(rig, cmd, cmd_arg, xml, sizeof(xml)); retval = write_transaction(rig, pxml, strlen(pxml)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { set_transaction_inactive(rig); RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } read_transaction(rig, xml, sizeof(xml)); // this might time out -- that's OK // we get an unknown response if function does not exist if (strstr(xml, "unknown")) { set_transaction_inactive(rig); RETURNFUNC(RIG_ENAVAIL); } if (strstr(xml, "get_bw") && strstr(xml, "NONE")) { set_transaction_inactive(rig); RETURNFUNC(RIG_ENAVAIL); } if (value) { xml_parse(xml, value, value_len); } } while (((value && strlen(value) == 0) || (strlen(xml) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no value returned\n", __func__); set_transaction_inactive(rig); RETURNFUNC(RIG_EPROTO); } ELAPSED2; set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } /* * flrig_init * Assumes rig!=NULL */ static int flrig_init(RIG *rig) { struct flrig_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct flrig_priv_data *)calloc(1, sizeof( struct flrig_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct flrig_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; priv->get_SWR = 1; // we'll try getSWR once to see if it works if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); priv->ext_parms = alloc_init_ext(flrig_ext_parms); if (!priv->ext_parms) { RETURNFUNC(-RIG_ENOMEM); } RETURNFUNC(RIG_OK); } /* * modeMapGetFLRig * Assumes mode!=NULL * Return the string for FLRig for the given hamlib mode */ static const char *modeMapGetFLRig(rmode_t modeHamlib) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_flrig == NULL) { continue; } rig_debug(RIG_DEBUG_TRACE, "%s: checking modeMap[%d]=%.0f to modeHamlib=%.0f, mode_flrig='%s'\n", __func__, i, (double)modeMap[i].mode_hamlib, (double)modeHamlib, modeMap[i].mode_flrig); if (modeMap[i].mode_hamlib == modeHamlib && strlen(modeMap[i].mode_flrig) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s matched mode=%.0f, returning '%s'\n", __func__, (double)modeHamlib, modeMap[i].mode_flrig); return (modeMap[i].mode_flrig); } } rig_debug(RIG_DEBUG_ERR, "%s: FlRig does not have mode: %s\n", __func__, rig_strrmode(modeHamlib)); return ("ERROR"); } /* * modeMapGetHamlib * Assumes mode!=NULL * Return the hamlib mode from the given FLRig string */ static rmode_t modeMapGetHamlib(const char *modeFLRig) { int i; char modeFLRigCheck[64]; SNPRINTF(modeFLRigCheck, sizeof(modeFLRigCheck), "|%s|", modeFLRig); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { rig_debug(RIG_DEBUG_TRACE, "%s: find '%s' in '%s'\n", __func__, modeFLRigCheck, modeMap[i].mode_flrig); if (modeMap[i].mode_flrig && strstr(modeMap[i].mode_flrig, modeFLRigCheck)) { return (modeMap[i].mode_hamlib); } } rig_debug(RIG_DEBUG_TRACE, "%s: mode requested: %s, not in modeMap\n", __func__, modeFLRig); return (RIG_MODE_NONE); } /* * modeMapAdd * Assumes modes!=NULL */ static void modeMapAdd(rmode_t *modes, rmode_t mode_hamlib, char *mode_flrig) { int i; int len1; rig_debug(RIG_DEBUG_TRACE, "%s:mode_flrig=%s\n", __func__, mode_flrig); // if we already have it just return // We get ERROR if the mode is not known so non-ERROR is OK if (modeMapGetHamlib(mode_flrig) != RIG_MODE_NONE) { return; } len1 = strlen(mode_flrig) + 3; /* bytes needed for allocating */ for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_hamlib == mode_hamlib) { int len2; *modes |= modeMap[i].mode_hamlib; /* we will pipe delimit all the entries for easier matching */ /* all entries will have pipe symbol on both sides */ if (modeMap[i].mode_flrig == NULL) { modeMap[i].mode_flrig = calloc(1, len1); if (modeMap[i].mode_flrig == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: error allocating memory for modeMap\n", __func__); return; } } len2 = strlen(modeMap[i].mode_flrig); /* current len w/o null */ modeMap[i].mode_flrig = realloc(modeMap[i].mode_flrig, strlen(modeMap[i].mode_flrig) + len1); if (strlen(modeMap[i].mode_flrig) == 0) { modeMap[i].mode_flrig[0] = '|'; } strncat(modeMap[i].mode_flrig, mode_flrig, len1 + len2); strncat(modeMap[i].mode_flrig, "|", len1 + len2); rig_debug(RIG_DEBUG_TRACE, "%s: Adding mode=%s, index=%d, result=%s\n", __func__, mode_flrig, i, modeMap[i].mode_flrig); return; } } } /* * flrig_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int flrig_open(RIG *rig) { int retval; char value[MAXXMLLEN]; //char arg[MAXXMLLEN]; rmode_t modes; char *p; char *pr; split_t split; vfo_t tx_vfo; struct rig_state *rs = STATE(rig); struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); retval = flrig_transaction(rig, "main.get_version", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_version failed: %s\nAssuming version < 1.3.54", __func__, rigerror(retval)); // we fall through and assume old version } int v1 = 0, v2 = 0, v3 = 0, v4 = 0; sscanf(value, "%d.%d.%d.%d", &v1, &v2, &v3, &v4); char version[32]; sprintf(version, "%03d%03d%03d%03d", v1, v2, v3, v4); int iversion = 0; sscanf(version, "%d", &iversion); rig_debug(RIG_DEBUG_VERBOSE, "%s: version='%s'=%d\n", __func__, version, iversion); priv->has_verify_cmds = 0; if (iversion >= 1003054000) // 1.3.54 or greater { priv->has_verify_cmds = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_vfoA/ptt is available\n", __func__); } rig_debug(RIG_DEBUG_VERBOSE, "%s FlRig version %s\n", __func__, value); retval = flrig_transaction(rig, "rig.get_xcvr", NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_xcvr failed,,,not fatal: %s\n", __func__, rigerror(retval)); } strncpy(priv->info, value, sizeof(priv->info)); rig_debug(RIG_DEBUG_VERBOSE, "Transceiver=%s\n", value); char model_name[256]; snprintf(model_name,sizeof(model_name), "%.248s(%s)", value, "FLRig"); rig->caps->model_name = strdup(model_name); STATE(rig)->model_name = strdup(model_name); /* see if get_pwrmeter_scale is available */ retval = flrig_transaction(rig, "rig.get_pwrmeter_scale", NULL, value, sizeof(value)); priv->powermeter_scale = 1; // default if (retval == RIG_OK) { priv->powermeter_scale = atof(value); } /* see if get_modeA is available */ retval = flrig_transaction(rig, "rig.get_modeA", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_get_modeA = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeA is not available=%s\n", __func__, value); } else { priv->has_get_modeA = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeA is available\n", __func__); } /* see if get_modeB is available */ retval = flrig_transaction(rig, "rig.get_modeB", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_get_modeB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeB is not available=%s\n", __func__, value); } else { priv->has_get_modeB = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: getmodeB is available\n", __func__); } freq_t freq; retval = flrig_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: flrig_get_freq not working!!\n", __func__); RETURNFUNC(RIG_EPROTO); } /* see if get_bwA is available */ retval = flrig_transaction(rig, "rig.get_bwA", NULL, value, sizeof(value)); int dummy; if (retval == RIG_ENAVAIL || value[0] == 0 || sscanf(value, "%d", &dummy) <= 0) // must not have it { priv->has_get_bwA = 0; priv->has_get_bwB = 0; // if we don't have A then surely we don't have B either priv->has_set_bwA = 0; // and we don't have set functions either priv->has_set_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwA/B is not available=%s\n", __func__, value); } else { priv->has_get_bwA = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwA is available=%s\n", __func__, value); } /* see if set_bwA is available */ retval = flrig_transaction(rig, "rig.set_bwA", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_set_bwA = 0; priv->has_set_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwA is not available=%s\n", __func__, value); } else { priv->has_set_bwA = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwA is available=%s\n", __func__, value); } if (priv->has_get_bwA) { // see if get_bwB is available FLRig can return empty value too retval = flrig_transaction(rig, "rig.get_bwB", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL || strlen(value) == 0) // must not have it { priv->has_get_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwB is not available=%s\n", __func__, value); } else { priv->has_get_bwB = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_bwB is available=%s\n", __func__, value); } /* see if set_bwB is available */ retval = flrig_transaction(rig, "rig.set_bwB", NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL) // must not have it { priv->has_set_bwB = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwB is not available=%s\n", __func__, value); } else { priv->has_set_bwB = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: set_bwB is available=%s\n", __func__, value); } } retval = flrig_transaction(rig, "rig.get_AB", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } if (streq(value, "A")) { rs->current_vfo = RIG_VFO_A; } else { rs->current_vfo = RIG_VFO_B; } rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(rs->current_vfo), value); //vfo_t vfo=RIG_VFO_A; //vfo_t vfo_tx=RIG_VFO_B; // split is always VFOB //flrig_get_split_vfo(rig, vfo, &priv->split, &vfo_tx); /* find out available widths and modes */ retval = flrig_transaction(rig, "rig.get_modes", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: modes=%s\n", __func__, value); modes = 0; pr = value; /* The following modes in FLRig are not implemented yet A1A AM-2 AM6.0 AM-D1 -- doesn't appear to be read/set AM-D2 -- doesn't appear to be read/set AM-D3 -- doesn't appear to be read/set AMW -- don't have mode in rig.h CW2.4 -- could be CW CW500 -- could be CWN but CWN not in rig.h CW-N -- could be CWN but CWN not in rig.h CWN -- dcould be CWN but CWN not in rig.h CW-NR -- don't have mode in rig.h DATA2-LSB DV DV-R F1B FM-D1 -- doesn't appear to be read/set FM-D2 -- doesn't appear to be read/set FM-D3 -- doesn't appear to be read/set H3E M11 USB-D -- doesn't appear to be read/set USER-L -- doesn't appear to be read/set USER-U -- doesn't appear to be read/set */ for (p = strtok_r(value, "|", &pr); p != NULL; p = strtok_r(NULL, "|", &pr)) { if (streq(p, "AM-D")) { modeMapAdd(&modes, RIG_MODE_PKTAM, p); } else if (streq(p, "AM")) { modeMapAdd(&modes, RIG_MODE_AM, p); } else if (streq(p, "AM-N")) { modeMapAdd(&modes, RIG_MODE_AMN, p); } else if (streq(p, "AMN")) { modeMapAdd(&modes, RIG_MODE_AMN, p); } else if (streq(p, "CW")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CW-L")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-LSB")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-R")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CW-U")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CW-USB")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "CWL")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "CWU")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "D-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "D-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA-FM")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } else if (streq(p, "DATA-FMN")) { modeMapAdd(&modes, RIG_MODE_PKTFMN, p); } else if (streq(p, "DATA-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-R")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-LSB")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DATA-USB")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DATA-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIG")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIGI")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIGL")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DIGI-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "DIGU")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DIGI-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "DSB")) { modeMapAdd(&modes, RIG_MODE_DSB, p); } else if (streq(p, "FM")) { modeMapAdd(&modes, RIG_MODE_FM, p); } else if (streq(p, "FM-D")) { modeMapAdd(&modes, RIG_MODE_PKTFM, p); } else if (streq(p, "FMN")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } else if (streq(p, "FM-N")) { modeMapAdd(&modes, RIG_MODE_FMN, p); } else if (streq(p, "FMW")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "FSK")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "FSK-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "LCW")) { modeMapAdd(&modes, RIG_MODE_CWR, p); } else if (streq(p, "LSB")) { modeMapAdd(&modes, RIG_MODE_LSB, p); } else if (streq(p, "LSB-D")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "LSB-D1")) { modeMapAdd(&modes, RIG_MODE_LSBD1, p); } else if (streq(p, "LSB-D2")) { modeMapAdd(&modes, RIG_MODE_LSBD2, p); } else if (streq(p, "LSB-D3")) { modeMapAdd(&modes, RIG_MODE_LSBD3, p); } else if (streq(p, "NFM")) { modeMapAdd(&modes, RIG_MODE_FMN, 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_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); } else if (streq(p, "PSK-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY-L")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "RTTY-R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "RTTY-U")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY(U)")) { modeMapAdd(&modes, RIG_MODE_RTTY, p); } else if (streq(p, "RTTY(R")) { modeMapAdd(&modes, RIG_MODE_RTTYR, p); } else if (streq(p, "SAH")) { modeMapAdd(&modes, RIG_MODE_SAH, p); } else if (streq(p, "SAL")) { modeMapAdd(&modes, RIG_MODE_SAL, p); } else if (streq(p, "SAM")) { modeMapAdd(&modes, RIG_MODE_SAM, p); } else if (streq(p, "USB")) { modeMapAdd(&modes, RIG_MODE_USB, p); } else if (streq(p, "USB-D")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USB-D1")) { modeMapAdd(&modes, RIG_MODE_USBD1, p); } else if (streq(p, "USB-D2")) { modeMapAdd(&modes, RIG_MODE_USBD2, p); } else if (streq(p, "USB-D3")) { modeMapAdd(&modes, RIG_MODE_USBD3, p); } else if (streq(p, "USER-U")) { modeMapAdd(&modes, RIG_MODE_PKTUSB, p); } else if (streq(p, "USER-L")) { modeMapAdd(&modes, RIG_MODE_PKTLSB, p); } else if (streq(p, "W-FM")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "WFM")) { modeMapAdd(&modes, RIG_MODE_WFM, p); } else if (streq(p, "UCW")) { modeMapAdd(&modes, RIG_MODE_CW, p); } else if (streq(p, "C4FM")) { modeMapAdd(&modes, RIG_MODE_C4FM, p); } else if (streq(p, "SPEC")) { modeMapAdd(&modes, RIG_MODE_SPEC, p); } else if (streq(p, "DV")) { modeMapAdd(&modes, RIG_MODE_DSTAR, p); } else if (streq(p, "DRM")) // we don't support DRM yet (or maybe ever) { rig_debug(RIG_DEBUG_VERBOSE, "%s: no mapping for mode %s\n", __func__, p); } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode (new?) for this rig='%s'\n", __func__, p); } } rs->mode_list = modes; retval = rig_strrmodes(modes, value, sizeof(value)); if (retval != RIG_OK) // we might get TRUNC but we can still print the debug { rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_VERBOSE, "%s: hamlib modes=%s\n", __func__, value); rig_get_split_vfo(rig, RIG_VFO_A, &split, &tx_vfo); #if 0 retval = flrig_transaction(rig, "rig.get_agc_labels", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_ERR, "%s: agc_labels=%s\n", __func__, value); #endif RETURNFUNC(retval); } /* * flrig_close * Assumes rig!=NULL */ static int flrig_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * flrig_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int flrig_cleanup(RIG *rig) { struct flrig_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (!rig) { RETURNFUNC2(-RIG_EINVAL); } priv = (struct flrig_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; // we really don't need to free this up as it's only done once // was causing problem when cleanup was followed by rig_open // model_flrig was not getting refilled // if we can figure out that one we can re-enable this #if 0 int i; for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_flrig) { free(modeMap[i].mode_flrig); modeMap[i].mode_flrig = NULL; modeMap[i].mode_hamlib = 0; } } #endif RETURNFUNC2(RIG_OK); } /* * flrig_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int flrig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char value[MAXARGLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = vfo == RIG_VFO_A ? "rig.get_vfoA" : "rig.get_vfoB"; int retval; retval = flrig_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: flrig_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } *freq = atof(value); #if 0 // zero is actually valid for PowerSDR if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else #endif { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * flrig_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int flrig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } else if (vfo == RIG_VFO_TX && priv->split) { vfo = RIG_VFO_B; // if split always TX on VFOB } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.0f", freq); value_t val; rig_get_ext_parm(rig, TOK_FLRIG_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set_verify_vfoA/B=%d\n", __func__, val.i); if (vfo == RIG_VFO_A) { cmd = "rig.set_vfoA"; if (val.i) { cmd = "rig.set_verify_vfoA"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqA = freq; } else { cmd = "rig.set_vfoB"; if (val.i) { cmd = "rig.set_verify_vfoB"; } rig_debug(RIG_DEBUG_TRACE, "%s %.0f\n", cmd, freq); priv->curr_freqB = freq; } retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); hl_usleep(100 * 1000); // FLRig needs a moment to update the active VFO if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } /* * flrig_set_ptt * Assumes rig!=NULL */ static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_arg[MAXARGLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", ptt); value_t val; char *cmd = "rig.set_ptt"; rig_get_ext_parm(rig, TOK_FLRIG_VERIFY_FREQ, &val); rig_debug(RIG_DEBUG_VERBOSE, "%s: fast_set_ptt=%d\n", __func__, val.i); if (val.i) { cmd = "rig.set_ptt_fast"; } retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->ptt = ptt; RETURNFUNC(RIG_OK); } /* * flrig_get_ptt * Assumes rig!=NUL, ptt!=NULL */ static int flrig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char value[MAXCMDLEN]; char xml[MAXXMLLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; xml[0] = 0; value[0] = 0; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); int retval; retval = flrig_transaction(rig, "rig.get_ptt", NULL, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC(retval); } if (strlen(value) > 0) { xml_parse(xml, value, sizeof(value)); *ptt = atoi(value); rig_debug(RIG_DEBUG_TRACE, "%s: '%s'\n", __func__, value); priv->ptt = *ptt; } RETURNFUNC(RIG_OK); } /* * flrig_set_split_mode * Assumes rig!=NULL */ static int flrig_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (vfo) { case RIG_VFO_CURR: vfo = STATE(rig)->current_vfo; break; case RIG_VFO_TX: vfo = RIG_VFO_B; break; } // If no change don't do it...modes are kept up to date by client calls // to get_mode and set_mode so should be current here rig_debug(RIG_DEBUG_TRACE, "%s: vfoa privmode=%s\n", __func__, rig_strrmode(priv->curr_modeA)); rig_debug(RIG_DEBUG_TRACE, "%s: vfob privmode=%s\n", __func__, rig_strrmode(priv->curr_modeB)); // save some VFO swapping .. may replace with VFO specific calls that won't cause VFO change if (vfo == RIG_VFO_A && mode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_B && mode == priv->curr_modeB) { RETURNFUNC(RIG_OK); } retval = flrig_set_mode(rig, vfo, mode, width); rig_debug(RIG_DEBUG_TRACE, "%s: set mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(retval); } /* * flrig_set_mode * Assumes rig!=NULL */ static int flrig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; int needBW; int vfoSwitched; char cmd_arg[MAXCMDLEN]; char *p; char *pttmode; char *ttmode = NULL; struct rig_state *rs = STATE(rig); struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); // if ptt is on do not set mode if (priv->ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: returning because priv->ptt=%d\n", __func__, (int)priv->ptt); RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate since we can't set mode directly // MDB vfoSwitched = 0; rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo = %s\n", __func__, rig_strvfo(rs->current_vfo)); // If we don't have the get_bwA call we have to switch VFOs ourself if (!priv->has_get_bwA && vfo == RIG_VFO_B && rs->current_vfo != RIG_VFO_B) { vfoSwitched = 1; rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOB = %d\n", __func__, vfoSwitched); } if (vfoSwitched) // swap to B and we'll swap back later { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOB = %d\n", __func__, vfoSwitched); retval = flrig_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } // Set the mode if (modeMapGetFLRig(mode)) { ttmode = strdup(modeMapGetFLRig(mode)); } else { rig_debug(RIG_DEBUG_ERR, "%s: modeMapGetFlRig failed on mode=%d\n", __func__, (int)mode); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: got ttmode = %s\n", __func__, ttmode == NULL ? "NULL" : ttmode); if (ttmode == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: strdup failed\n", __func__); RETURNFUNC(-RIG_EINTERNAL); } // if (strncmp(ttmode,"ERROR",5)==0) RETURNFUNC(-RIG_EINTERN); pttmode = ttmode; if (ttmode[0] == '|') { pttmode = &ttmode[1]; } // remove first pipe symbol p = strchr(pttmode, '|'); if (p) { *p = 0; } // remove any other pipe SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", pttmode); free(ttmode); if (!priv->has_get_modeA) { retval = flrig_transaction(rig, "rig.set_mode", cmd_arg, NULL, 0); } else { char *cmd = "rig.set_modeA"; if (vfo == RIG_VFO_B) { cmd = "rig.set_modeB"; } else { // we make VFO_B mode unknown so it expires the cache priv->curr_modeB = RIG_MODE_NONE; } retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // Determine if we need to update the bandwidth needBW = 0; if (vfo == RIG_VFO_A) { needBW = priv->curr_widthA != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOA, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else if (vfo == RIG_VFO_B) { needBW = priv->curr_widthB != width; rig_debug(RIG_DEBUG_TRACE, "%s: bw change on VFOB, curr width=%d needBW=%d\n", __func__, (int)width, needBW); } else { rig_debug(RIG_DEBUG_TRACE, "%s: needBW unknown vfo=%s\n", __func__, rig_strvfo(vfo)); } // Need to update the bandwidth if (width > 0 && needBW) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%ld", width); if (priv->has_set_bwA && vfo == RIG_VFO_A) { retval = flrig_transaction(rig, "rig.set_bwA", cmd_arg, NULL, 0); } else if (priv->has_set_bwB && vfo == RIG_VFO_B) { retval = flrig_transaction(rig, "rig.set_bwB", cmd_arg, NULL, 0); } else { retval = flrig_transaction(rig, "rig.set_bandwidth", cmd_arg, NULL, 0); } if (retval < 0) { RETURNFUNC(retval); } } // Return to VFOA if needed rig_debug(RIG_DEBUG_TRACE, "%s: switch to VFOA? = %d\n", __func__, vfoSwitched); if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s: switching to VFOA\n", __func__); retval = flrig_set_vfo(rig, RIG_VFO_A); if (retval < 0) { RETURNFUNC(retval); } } if (vfo == RIG_VFO_A) { priv->curr_modeA = mode; priv->curr_widthA = width; } else { priv->curr_modeB = mode; priv->curr_widthB = width; } rig_debug(RIG_DEBUG_TRACE, "%s: Return modeA=%s, widthA=%d\n,modeB=%s, widthB=%d\n", __func__, rig_strrmode(priv->curr_modeA), (int)priv->curr_widthA, rig_strrmode(priv->curr_modeB), (int)priv->curr_widthB); RETURNFUNC(RIG_OK); } /* * flrig_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int flrig_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int vfoSwitched; char value[MAXCMDLEN]; char *cmdp; vfo_t curr_vfo; rmode_t my_mode; struct rig_state *rs = STATE(rig); struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *width = 0; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } curr_vfo = rs->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->ptt) { if (vfo == RIG_VFO_A) { *mode = priv->curr_modeA; } else { *mode = priv->curr_modeB; } rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate vfoSwitched = 0; if (priv->has_get_modeA == 0 && vfo == RIG_VFO_B && curr_vfo != RIG_VFO_B) { vfoSwitched = 1; } if (vfoSwitched) { rig_debug(RIG_DEBUG_TRACE, "%s switch to VFOB=%d\n", __func__, priv->has_get_modeA); retval = flrig_set_vfo(rig, RIG_VFO_B); if (retval < 0) { RETURNFUNC(retval); } } cmdp = "rig.get_mode"; /* default to old way */ if (priv->has_get_modeA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in flrig */ /* vfo B may not be getting polled though in FLRig */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_modeA"; if (priv->has_get_modeB && vfo == RIG_VFO_B) { cmdp = "rig.get_modeB"; } } retval = flrig_transaction(rig, cmdp, NULL, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, cmdp, rigerror(retval)); RETURNFUNC(retval); } my_mode = modeMapGetHamlib(value); *mode = my_mode; rig_debug(RIG_DEBUG_TRACE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); if (vfo == RIG_VFO_A) { priv->curr_modeA = *mode; } else { priv->curr_modeB = *mode; } /* Get the bandwidth */ cmdp = "rig.get_bw"; /* default to old way */ if (priv->has_get_bwA) /* change to new way if we can */ { /* calling this way reduces VFO swapping */ /* we get the cached value in flrig */ /* vfo B may not be getting polled though in FLRig */ /* so we may not be 100% accurate if op is twiddling knobs */ cmdp = "rig.get_bwA"; retval = flrig_transaction(rig, cmdp, NULL, value, sizeof(value)); if (strlen(value) == 0) // sometimes we get a null reply here -- OK...deal with it { rig_debug(RIG_DEBUG_WARN, "%s: empty value, returning cached bandwidth\n", __func__); *width = CACHE(rig)->widthMainA; RETURNFUNC(RIG_OK); } if (retval == RIG_OK && strstr(value, "NONE")) { priv->has_get_bwA = priv->has_get_bwB = 0; *width = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: does not have rig.get_bwA/B\n", __func__); RETURNFUNC(RIG_OK); } if (retval != RIG_OK || strstr(value, "NONE")) { RETURNFUNC(retval); } if (priv->has_get_bwB && vfo == RIG_VFO_B) { cmdp = "rig.get_bwB"; retval = flrig_transaction(rig, cmdp, NULL, value, sizeof(value)); if (strlen(value) == 0) { rig_debug(RIG_DEBUG_WARN, "%s: empty value, returning cached bandwidth\n", __func__); *width = CACHE(rig)->widthMainA; RETURNFUNC(RIG_OK); } if (retval == RIG_OK && strlen(value) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: does not have rig.get_bwB\n", __func__); priv->has_get_bwB = 0; *width = 0; } if (retval != RIG_OK) { RETURNFUNC(retval); } } } rig_debug(RIG_DEBUG_TRACE, "%s: mode=%s width='%s'\n", __func__, rig_strrmode(*mode), value); // we get 2 entries pipe separated for bandwidth, lower and upper if (strlen(value) > 0) { char *p = value; /* we might get two values and then we want the 2nd one */ if (strchr(value, '|') != NULL) { p = strchr(value, '|') + 1; } *width = atoi(p); if (strstr(p, "k")) { *width = *width * 1000; } rig_debug(RIG_DEBUG_TRACE, "%s: p=%s, *width=%d\n", __func__, p, (int)(*width)); if (strcmp(p, "FIXED") == 0) { switch (*mode) { case RIG_MODE_PKTAM: case RIG_MODE_AM: case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = 10000; break; } } } if (vfo == RIG_VFO_A) { priv->curr_widthA = *width; } else { priv->curr_widthB = *width; } // Return to VFOA if needed if (vfoSwitched) { retval = flrig_set_vfo(rig, RIG_VFO_A); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * flrig_set_vfo * assumes rig!=NULL */ static int flrig_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd_arg[MAXXMLLEN]; struct rig_state *rs = STATE(rig); const struct flrig_priv_data *priv = (struct flrig_priv_data *) rs->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX used\n", __func__); vfo = RIG_VFO_B; // always TX on VFOB } if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", vfo == RIG_VFO_A ? "A" : "B"); retval = flrig_transaction(rig, "rig.set_AB", cmd_arg, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig.set_AB failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } rs->current_vfo = vfo; rs->tx_vfo = RIG_VFO_B; // always VFOB /* for some rigs FLRig turns off split when VFOA is selected */ /* so if we are in split and asked for A we have to turn split back on */ if (priv->split && vfo == RIG_VFO_A) { SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", priv->split); retval = flrig_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * flrig_get_vfo * assumes rig!=NULL, vfo != NULL */ static int flrig_get_vfo(RIG *rig, vfo_t *vfo) { char value[MAXCMDLEN]; ENTERFUNC; int retval; retval = flrig_transaction(rig, "rig.get_AB", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo value=%s\n", __func__, value); switch (value[0]) { case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; default: *vfo = RIG_VFO_CURR; RETURNFUNC(-RIG_EINVAL); } if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(-RIG_EINVAL); } STATE(rig)->current_vfo = *vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(RIG_OK); } /* * flrig_set_split_freq * assumes rig!=NULL */ static int flrig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int retval; char cmd_arg[MAXXMLLEN]; freq_t qtx_freq; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), tx_freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } // we always split on VFOB so if no change just return retval = flrig_get_freq(rig, RIG_VFO_B, &qtx_freq); if (retval != RIG_OK) { RETURNFUNC(retval); } if (tx_freq == qtx_freq) { RETURNFUNC(RIG_OK); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%.6f", tx_freq); retval = flrig_transaction(rig, "rig.set_vfoB", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->curr_freqB = tx_freq; RETURNFUNC(RIG_OK); } /* * flrig_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ static int flrig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = flrig_get_freq(rig, RIG_VFO_B, tx_freq); priv->curr_freqB = *tx_freq; RETURNFUNC(retval); } /* * flrig_set_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int flrig_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; vfo_t qtx_vfo; split_t qsplit; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; char cmd_arg[MAXXMLLEN]; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__, rig_strvfo(tx_vfo)); retval = flrig_get_split_vfo(rig, RIG_VFO_A, &qsplit, &qtx_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } if (split == qsplit) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", split); retval = flrig_transaction(rig, "rig.set_split", cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } priv->split = split; RETURNFUNC(RIG_OK); } /* * flrig_get_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int flrig_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { char value[MAXCMDLEN]; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; int retval; retval = flrig_transaction(rig, "rig.get_split", NULL, value, sizeof(value)); if (retval < 0) { RETURNFUNC(retval); } *split = atoi(value); priv->split = *split; *tx_vfo = *split ? RIG_VFO_B : RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s tx_vfo=%s, split=%d\n", __func__, rig_strvfo(*tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * flrig_set_split_freq_mode * assumes rig!=NULL */ static int flrig_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; rmode_t qmode; pbwidth_t qwidth; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; // we always do split on VFOB retval = flrig_set_freq(rig, RIG_VFO_B, freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s flrig_set_freq failed\n", __func__); RETURNFUNC(retval); } // Make VFOB mode match VFOA mode, keep VFOB width retval = flrig_get_mode(rig, RIG_VFO_B, &qmode, &qwidth); if (retval != RIG_OK) { RETURNFUNC(retval); } if (qmode == priv->curr_modeA) { RETURNFUNC(RIG_OK); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } retval = flrig_set_mode(rig, RIG_VFO_B, priv->curr_modeA, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s flrig_set_mode failed\n", __func__); RETURNFUNC(retval); } retval = flrig_set_vfo(rig, RIG_VFO_A); RETURNFUNC(retval); } /* * flrig_get_split_freq_mode * assumes rig!=NULL, freq!=NULL, mode!=NULL, width!=NULL */ static int flrig_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; ENTERFUNC; if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX) { RETURNFUNC(-RIG_ENTARGET); } retval = flrig_get_freq(rig, RIG_VFO_B, freq); if (RIG_OK == retval) { retval = flrig_get_mode(rig, vfo, mode, width); } RETURNFUNC(retval); } static int flrig_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval; char cmd_arg[MAXARGLEN]; char *cmd; char *param_type = "i4"; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s level=%d, val=%f\n", __func__, rig_strvfo(vfo), (int)level, val.f); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } switch (level) { case RIG_LEVEL_RF: cmd = "rig.set_rfgain"; val.f *= 100; break; case RIG_LEVEL_AF: cmd = "rig.set_volume"; val.f *= 100; break; case RIG_LEVEL_MICGAIN: cmd = "rig.set_micgain"; val.f *= 100; break; case RIG_LEVEL_RFPOWER: cmd = "rig.set_power"; val.f *= 100; break; default: rig_debug(RIG_DEBUG_ERR, "%s: invalid level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd_arg, sizeof(cmd_arg), "<%s>%d", param_type, (int)val.f, param_type); retval = flrig_transaction(rig, cmd, cmd_arg, NULL, 0); if (retval < 0) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } typedef struct { float mtr; float swr; } swrpair; static swrpair swrtbl[] = { {0.0, 1.0}, {10.5, 1.5}, {23.0, 2.0}, {35.0, 2.5}, {48.0, 3.0}, {100.0, 10.0 } // assuming 10.0 is infinity for FLRig }; // Function to interpolate SWR from MTR float interpolateSWR(float mtr) { int i; for (i = 0; i < sizeof(swrtbl) / sizeof(swrpair) - 1; i++) { if (mtr == swrtbl[i].mtr) { // Exact match return swrtbl[i].swr; } if (mtr < swrtbl[i + 1].mtr) { // Perform linear interpolation float slope = (swrtbl[i + 1].swr - swrtbl[i].swr) / (swrtbl[i + 1].mtr - swrtbl[i].mtr); float swr = round((swrtbl[i].swr + slope * (mtr - swrtbl[i].mtr)) * 10) / 10.0; rig_debug(RIG_DEBUG_VERBOSE, "%s: swr=%f\n", __func__, swr); return swr; } } // If mtr is not within the range of values in the table, you could choose to return an error or extrapolate return 10; // Example er } /* * flrig_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ static int flrig_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char value[MAXARGLEN]; char *cmd; int retval; struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: cmd = "rig.get_volume"; break; case RIG_LEVEL_RF: cmd = "rig.get_rfgain"; break; case RIG_LEVEL_MICGAIN: cmd = "rig.get_micgain"; break; case RIG_LEVEL_STRENGTH: cmd = "rig.get_DBM"; break; case RIG_LEVEL_SWR: cmd = "rig.get_swrmeter"; // we'll try get_SWR at least once to see if it works if (priv->get_SWR) { cmd = "rig.get_SWR"; } break; case RIG_LEVEL_RFPOWER: cmd = "rig.get_power"; break; case RIG_LEVEL_RFPOWER_METER_WATTS: case RIG_LEVEL_RFPOWER_METER: cmd = "rig.get_pwrmeter"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%d\n", __func__, (int)level); RETURNFUNC(-RIG_EINVAL); } retval = flrig_transaction(rig, cmd, NULL, value, sizeof(value)); if (retval == RIG_ENAVAIL && strcmp(cmd, "rig.get_SWR") == 0) { priv->get_SWR = 0; cmd = "rig.get_swrmeter"; // revert to old flrig method retval = flrig_transaction(rig, cmd, NULL, value, sizeof(value)); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: flrig_transaction failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } // most levels are 0-100 -- may have to allow for different ranges switch (level) { case RIG_LEVEL_SWR: { if (priv->get_SWR) { val->f = atof(value); } else { val->f = interpolateSWR(atoi(value)); } break; } case RIG_LEVEL_STRENGTH: val->i = atoi(value) + 73; rig_debug(RIG_DEBUG_TRACE, "%s: val.i='%s'(%d)\n", __func__, value, val->i); break; case RIG_LEVEL_RFPOWER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER: val->f = atof(value) / 100.0 * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; case RIG_LEVEL_RFPOWER_METER_WATTS: val->f = atof(value) * priv->powermeter_scale; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%g)\n", __func__, value, val->f); break; default: val->f = atof(value) / 100; rig_debug(RIG_DEBUG_TRACE, "%s: val.f='%s'(%f)\n", __func__, value, val->f); } RETURNFUNC(RIG_OK); } /* * flrig_get_info * assumes rig!=NULL */ static const char *flrig_get_info(RIG *rig) { const struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE( rig)->priv; return (priv->info); } static int flrig_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const struct flrig_priv_data *priv = (struct flrig_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); power *= priv->powermeter_scale; *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int flrig_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } static int flrig_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_FLRIG_VERIFY_FREQ: case TOK_FLRIG_VERIFY_PTT: if (val.i && !priv->has_verify_cmds) { rig_debug(RIG_DEBUG_ERR, "%s: FLRig version 1.3.54.18 or higher needed to support fast functions\n", __func__); RETURNFUNC(-RIG_EINVAL); } break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int flrig_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; /* TODO: load value from priv->ext_parms */ cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_FLRIG_VERIFY_FREQ: case TOK_FLRIG_VERIFY_PTT: break; default: RETURNFUNC(-RIG_EINVAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } HAMLIB_EXPORT(int) flrig_cat_string2(RIG *rig, const char *arg, char *value, int value_size) { int retval; char cmd_arg[MAXARGLEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, arg); SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", arg); retval = flrig_transaction(rig, "rig.cat_string", cmd_arg, value, value_size); rig_debug(RIG_DEBUG_VERBOSE, "%s: returned '%s'\n", __func__, value); return retval; } HAMLIB_EXPORT(int) flrig_cat_string(RIG *rig, const char *arg) { int retval; char cmd_arg[MAXARGLEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, arg); SNPRINTF(cmd_arg, sizeof(cmd_arg), "%s", arg); retval = flrig_transaction(rig, "rig.cat_string", cmd_arg, NULL, 0); return retval; } int flrig_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; char cmd_arg[MAXARGLEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: level=%s, status=%d\n", __func__, rig_strfunc(func), status); switch (func) { case RIG_FUNC_TUNER: SNPRINTF(cmd_arg, sizeof(cmd_arg), "%d", status); retval = flrig_transaction(rig, "rig.tune", cmd_arg, NULL, 0); break; default: retval = -RIG_ENIMPL; } return retval; } #if 0 static int flrig_set_ext_parm(RIG *rig, setting_t parm, value_t val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; int idx; char pstr[32]; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; RETURNFUNC(RIG_OK); } static int flrig_get_ext_parm(RIG *rig, setting_t parm, value_t *val) { struct flrig_priv_data *priv = (struct flrig_priv_data *)STATE(rig)->priv; int idx; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); RETURNFUNC(RIG_OK); } #endif hamlib-4.6.2/rigs/dummy/rot_pstrotator.h0000644000175000017500000000361614752216205015267 00000000000000/* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_PSTROTATOR_H #define _ROT_PSTROTATOR_H 1 #include "rotator.h" #include "token.h" /* backend conf */ #define TOK_CFG_ROT_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_ROT_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_ROT_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_ROT_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_ROT_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_ROT_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_ROT_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_ROT_MAGICEXTFUNC TOKEN_BACKEND(6) extern struct rot_caps pstrotator_caps; extern struct rot_caps netrotctl_caps; #if defined(HAVE_PTHREAD) typedef struct pstrotator_handler_args_sw { ROT *rot; int port; // port for reading PstRotator messages -- always +1 from base port } pstrotator_handler_args; typedef struct pstrotator_handler_priv_data_s { pthread_t thread_id; pstrotator_handler_args args; int pstrotator_handler_thread_run; int sockfd2; } pstrotator_handler_priv_data; #endif #endif /* _ROT_PSTROTATOR_H */ hamlib-4.6.2/rigs/dummy/dummy.c0000644000175000017500000021335214752216205013310 00000000000000/* * Hamlib Dummy backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (c) 2010 by Nate Bargmann * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include // cppcheck-suppress * #include /* String function definitions */ // cppcheck-suppress * #include /* UNIX standard function definitions */ // cppcheck-suppress * #include #include "hamlib/rig.h" #include "dummy_common.h" #include "serial.h" #include "parallel.h" #include "cm108.h" #include "gpio.h" #include "misc.h" #include "tones.h" #include "idx_builtin.h" #include "register.h" #include "dummy.h" #define NB_CHAN 22 /* see caps->chan_list */ #define CMDSLEEP 20*1000 /* ms for each command */ struct dummy_priv_data { /* current vfo already in rig_state ? */ vfo_t curr_vfo; vfo_t last_vfo; /* VFO A or VFO B, when in MEM mode */ split_t split; vfo_t tx_vfo; ptt_t ptt; powerstat_t powerstat; int bank; value_t parms[RIG_SETTING_MAX]; int ant_option[4]; /* simulate 4 antennas */ int trn; /* transceive */ channel_t *curr; /* points to vfo_a, vfo_b or mem[] */ // we're trying to emulate all sorts of vfo possibilities so this looks redundant channel_t vfo_maina; channel_t vfo_mainb; channel_t vfo_suba; channel_t vfo_subb; channel_t vfo_c; channel_t mem[NB_CHAN]; struct ext_list *ext_funcs; struct ext_list *ext_parms; char *magic_conf; int static_data; //freq_t freq_vfoa; //freq_t freq_vfob; }; /* levels pertain to each VFO */ static const struct confparams dummy_ext_levels[] = { { TOK_EL_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { TOK_EL_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { TOK_EL_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", NULL, RIG_CONF_BUTTON }, { TOK_EL_MAGICCOMBO, "MGC", "Magic combo", "Magic combo, as an example", "VALUE1", RIG_CONF_COMBO, { .c = { .combostr = { "VALUE1", "VALUE2", "NONE", NULL } } } }, { RIG_CONF_END, NULL, } }; static const struct confparams dummy_ext_funcs[] = { { TOK_EL_MAGICEXTFUNC, "MGEF", "Magic ext func", "Magic ext function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; /* parms pertain to the whole rig */ static const struct confparams dummy_ext_parms[] = { { TOK_EP_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { RIG_CONF_END, NULL, } }; /* cfgparams are configuration item generally used by the backend's open() method */ static const struct confparams dummy_cfg_params[] = { { TOK_CFG_MAGICCONF, "mcfg", "Magic conf", "Magic parameter, as an example", "DX", RIG_CONF_STRING, { } }, { TOK_CFG_STATIC_DATA, "static_data", "Static data", "Output only static data, no randomization of meter values", "0", RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /********************************************************************/ static void init_chan(RIG *rig, vfo_t vfo, channel_t *chan) { chan->channel_num = 0; chan->vfo = vfo; strcpy(chan->channel_desc, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN_A: chan->freq = MHz(145); break; case RIG_VFO_B: case RIG_VFO_MAIN_B: chan->freq = MHz(146); break; case RIG_VFO_SUB_A: chan->freq = MHz(147); break; case RIG_VFO_SUB_B: chan->freq = MHz(148); break; case RIG_VFO_C: chan->freq = MHz(149); break; default: rig_debug(RIG_DEBUG_ERR, "%s(%d) unknown vfo=%s\n", __FILE__, __LINE__, rig_strvfo(vfo)); } chan->mode = RIG_MODE_FM; chan->width = rig_passband_normal(rig, RIG_MODE_FM); chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = vfo; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->ctcss_tone = 0; chan->dcs_code = 0; chan->ctcss_sql = 0; chan->dcs_sql = 0; chan->rit = 0; chan->xit = 0; chan->tuning_step = 0; chan->ant = 0; chan->funcs = (setting_t)0; memset(chan->levels, 0, RIG_SETTING_MAX * sizeof(value_t)); } static void copy_chan(channel_t *dest, const channel_t *src) { struct ext_list *saved_ext_levels; int i; /* TODO: ext_levels[] of different sizes */ for (i = 0; !RIG_IS_EXT_END(src->ext_levels[i]) && !RIG_IS_EXT_END(dest->ext_levels[i]); i++) { dest->ext_levels[i] = src->ext_levels[i]; } saved_ext_levels = dest->ext_levels; memcpy(dest, src, sizeof(channel_t)); dest->ext_levels = saved_ext_levels; } static int dummy_init(RIG *rig) { struct dummy_priv_data *priv; int i; ENTERFUNC; priv = (struct dummy_priv_data *)calloc(1, sizeof(struct dummy_priv_data)); if (!priv) { RETURNFUNC(-RIG_ENOMEM); } STATE(rig)->priv = (void *)priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); RIGPORT(rig)->type.rig = RIG_PORT_NONE; priv->split = RIG_SPLIT_OFF; priv->ptt = RIG_PTT_OFF; priv->powerstat = RIG_POWER_ON; STATE(rig)->powerstat = priv->powerstat; priv->bank = 0; memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); memset(priv->mem, 0, sizeof(priv->mem)); for (i = 0; i < NB_CHAN; i++) { priv->mem[i].channel_num = i; priv->mem[i].vfo = RIG_VFO_MEM; priv->mem[i].ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->mem[i].ext_levels) { RETURNFUNC(-RIG_ENOMEM); } } priv->vfo_maina.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_maina.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_mainb.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_mainb.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_suba.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_suba.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_subb.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_subb.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->vfo_c.ext_levels = alloc_init_ext(dummy_ext_levels); if (!priv->vfo_c.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } priv->ext_funcs = alloc_init_ext(dummy_ext_funcs); if (!priv->ext_funcs) { RETURNFUNC(-RIG_ENOMEM); } priv->ext_parms = alloc_init_ext(dummy_ext_parms); if (!priv->ext_parms) { RETURNFUNC(-RIG_ENOMEM); } init_chan(rig, RIG_VFO_MAIN_A, &priv->vfo_maina); init_chan(rig, RIG_VFO_MAIN_B, &priv->vfo_mainb); init_chan(rig, RIG_VFO_SUB_A, &priv->vfo_suba); init_chan(rig, RIG_VFO_SUB_B, &priv->vfo_subb); init_chan(rig, RIG_VFO_C, &priv->vfo_c); priv->curr = &priv->vfo_maina; if (rig->caps->rig_model == RIG_MODEL_DUMMY_NOVFO) { priv->curr_vfo = priv->last_vfo = RIG_VFO_CURR; } else { priv->curr_vfo = priv->last_vfo = RIG_VFO_A; } priv->magic_conf = strdup("DX"); RETURNFUNC(RIG_OK); } static int dummy_cleanup(RIG *rig) { struct rig_state *rs = STATE(rig); struct dummy_priv_data *priv = (struct dummy_priv_data *)rs->priv; int i; ENTERFUNC; for (i = 0; i < NB_CHAN; i++) { free(priv->mem[i].ext_levels); } free(priv->vfo_maina.ext_levels); free(priv->vfo_mainb.ext_levels); free(priv->vfo_suba.ext_levels); free(priv->vfo_subb.ext_levels); free(priv->vfo_c.ext_levels); free(priv->ext_funcs); free(priv->ext_parms); free(priv->magic_conf); if (rs->priv) { free(rs->priv); } rs->priv = NULL; RETURNFUNC(RIG_OK); } static int dummy_open(RIG *rig) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_DUMMY_NOVFO) { // then we emulate a rig without set_vfo or get_vfo rig_debug(RIG_DEBUG_VERBOSE, "%s: Emulating rig without get_vfo or set_vfo\n", __func__); rig->caps->set_vfo = NULL; rig->caps->get_vfo = NULL; } usleep(CMDSLEEP); RETURNFUNC(RIG_OK); } static int dummy_close(RIG *rig) { ENTERFUNC; usleep(CMDSLEEP); RETURNFUNC(RIG_OK); } static int dummy_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct dummy_priv_data *priv; ENTERFUNC; priv = (struct dummy_priv_data *)STATE(rig)->priv; switch (token) { case TOK_CFG_MAGICCONF: if (val) { free(priv->magic_conf); priv->magic_conf = strdup(val); } break; case TOK_CFG_STATIC_DATA: priv->static_data = atoi(val) ? 1 : 0; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_get_conf(RIG *rig, hamlib_token_t token, char *val) { struct dummy_priv_data *priv; ENTERFUNC; priv = (struct dummy_priv_data *)STATE(rig)->priv; switch (token) { case TOK_CFG_MAGICCONF: strcpy(val, priv->magic_conf); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dummy_priv_data *priv; char fstr[20]; ENTERFUNC; if (rig == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: rig is NULL!!!\n", __func__); RETURNFUNC(-RIG_EINVAL); } priv = (struct dummy_priv_data *)STATE(rig)->priv; if (priv == NULL) { RETURNFUNC(-RIG_EINTERNAL); } if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } if (vfo == RIG_VFO_CURR || vfo == RIG_VFO_TX) { vfo = vfo_fixup(rig, vfo, CACHE(rig)->split); } // if needed for testing enable this to emulate a rig with 100hz resolution #if 0 // we emulate a rig with 100Hz set freq interval limits -- truncation freq = freq - fmod(freq, 100); #endif usleep(CMDSLEEP); sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->vfo_maina.freq = freq; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->vfo_mainb.freq = freq; break; case RIG_VFO_SUB_A: priv->vfo_suba.freq = freq; break; case RIG_VFO_SUB_B: priv->vfo_subb.freq = freq; break; case RIG_VFO_C: priv->vfo_c.freq = freq; break; } if (!priv->split) { priv->curr->tx_freq = freq; } rig_debug(RIG_DEBUG_TRACE, "%s: curr->freq=%.0f, curr->tx_freq=%.0f\n", __func__, priv->curr->freq, priv->curr->tx_freq); RETURNFUNC(RIG_OK); } static int dummy_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_state *rs = STATE(rig); struct dummy_priv_data *priv = (struct dummy_priv_data *)rs->priv; ENTERFUNC; if (vfo == RIG_VFO_CURR && rig->caps->rig_model != RIG_MODEL_DUMMY_NOVFO) { vfo = priv->curr_vfo; } if ((vfo == RIG_VFO_SUB && rs->uplink == 1) || (vfo == RIG_VFO_MAIN && rs->uplink == 2)) { rig_debug(RIG_DEBUG_TRACE, "%s: uplink=%d, ignoring get_freq\n", __func__, rs->uplink); RETURNFUNC(RIG_OK); } usleep(CMDSLEEP); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: *freq = priv->vfo_maina.freq; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: *freq = priv->vfo_mainb.freq; break; case RIG_VFO_SUB_A: *freq = priv->vfo_suba.freq; break; case RIG_VFO_SUB_B: *freq = priv->vfo_subb.freq; break; case RIG_VFO_C: *freq = priv->vfo_c.freq; break; default: RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); RETURNFUNC(RIG_OK); } static int dummy_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; struct rig_cache *cachep = CACHE(rig); char buf[16]; ENTERFUNC; usleep(CMDSLEEP); sprintf_freq(buf, sizeof(buf), width); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s %s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), buf); vfo = vfo_fixup(rig, vfo, cachep->split); if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } if (width == RIG_PASSBAND_NOCHANGE) { switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: width = priv->vfo_maina.width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: width = priv->vfo_mainb.width; break; case RIG_VFO_SUB_A: width = priv->vfo_suba.width; break; case RIG_VFO_SUB_B: width = priv->vfo_subb.width; break; case RIG_VFO_C: width = priv->vfo_c.width; break; } } switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->vfo_maina.mode = mode; priv->vfo_maina.width = width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->vfo_mainb.mode = mode; priv->vfo_mainb.width = width; break; case RIG_VFO_SUB_A: priv->vfo_suba.mode = mode; priv->vfo_suba.width = width; break; case RIG_VFO_SUB_B: priv->vfo_subb.mode = mode; priv->vfo_subb.width = width; break; case RIG_VFO_C: priv->vfo_c.mode = mode; priv->vfo_c.width = width; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown VFO=%s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } vfo = vfo_fixup(rig, vfo, cachep->split); if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC(RIG_OK); } if (width == RIG_PASSBAND_NORMAL) { width = curr->width = rig_passband_normal(rig, mode); } switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->vfo_maina.width = width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->vfo_mainb.width = width; break; case RIG_VFO_SUB_A: priv->vfo_suba.width = width; break; case RIG_VFO_SUB_B: priv->vfo_subb.width = width; break; case RIG_VFO_C: priv->vfo_c.width = width; break; } RETURNFUNC(RIG_OK); } static int dummy_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; usleep(CMDSLEEP); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: *mode = priv->vfo_maina.mode; *width = priv->vfo_maina.width; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: *mode = priv->vfo_mainb.mode; *width = priv->vfo_mainb.width; break; case RIG_VFO_SUB_A: *mode = priv->vfo_suba.mode; *width = priv->vfo_suba.width; break; case RIG_VFO_SUB_B: *mode = priv->vfo_subb.mode; *width = priv->vfo_subb.width; break; case RIG_VFO_C: *mode = priv->vfo_c.mode; *width = priv->vfo_c.width; break; } RETURNFUNC(RIG_OK); } static int dummy_set_vfo(RIG *rig, vfo_t vfo) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } switch (vfo) { case RIG_VFO_VFO: /* FIXME */ case RIG_VFO_RX: case RIG_VFO_MAIN: case RIG_VFO_A: case RIG_VFO_MAIN_A: priv->curr = &priv->vfo_maina; break; case RIG_VFO_SUB: case RIG_VFO_B: case RIG_VFO_MAIN_B: priv->curr = &priv->vfo_mainb; break; case RIG_VFO_SUB_A: priv->curr = &priv->vfo_suba; break; case RIG_VFO_SUB_B: priv->curr = &priv->vfo_subb; break; case RIG_VFO_C: priv->curr = &priv->vfo_c; break; case RIG_VFO_MEM: if (curr->channel_num >= 0 && curr->channel_num < NB_CHAN) { priv->curr = &priv->mem[curr->channel_num]; break; } case RIG_VFO_TX: if (priv->tx_vfo == RIG_VFO_A) { priv->curr = &priv->vfo_maina; } else if (priv->tx_vfo == RIG_VFO_B) { priv->curr = &priv->vfo_mainb; } else if (priv->tx_vfo == RIG_VFO_MEM) { priv->curr = &priv->mem[curr->channel_num]; } else { priv->curr = &priv->vfo_maina; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s unknown vfo: %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } priv->last_vfo = priv->curr_vfo; priv->curr_vfo = vfo; STATE(rig)->current_vfo = vfo; RETURNFUNC(RIG_OK); } static int dummy_get_vfo(RIG *rig, vfo_t *vfo) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; usleep(CMDSLEEP); *vfo = priv->curr_vfo; RETURNFUNC(RIG_OK); } static int dummy_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; priv->ptt = ptt; RETURNFUNC(RIG_OK); } static int dummy_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; hamlib_port_t *pttp = PTTPORT(rig); int rc; int status = 0; ENTERFUNC; usleep(CMDSLEEP); // sneak a look at the hardware PTT and OR that in with our result // as if it had keyed us switch (pttp->type.ptt) { case RIG_PTT_SERIAL_DTR: if (pttp->fd >= 0) { if (RIG_OK != (rc = ser_get_dtr(pttp, &status))) { RETURNFUNC(rc); } *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } else { *ptt = RIG_PTT_OFF; } break; case RIG_PTT_SERIAL_RTS: if (pttp->fd >= 0) { if (RIG_OK != (rc = ser_get_rts(pttp, &status))) { RETURNFUNC(rc); } *ptt = status ? RIG_PTT_ON : RIG_PTT_OFF; } else { *ptt = RIG_PTT_OFF; } break; case RIG_PTT_PARALLEL: if (pttp->fd >= 0) { if (RIG_OK != (rc = par_ptt_get(pttp, ptt))) { RETURNFUNC(rc); } } break; case RIG_PTT_CM108: if (pttp->fd >= 0) { if (RIG_OK != (rc = cm108_ptt_get(pttp, ptt))) { RETURNFUNC(rc); } } break; case RIG_PTT_GPIO: case RIG_PTT_GPION: if (pttp->fd >= 0) { if (RIG_OK != (rc = gpio_ptt_get(pttp, ptt))) { RETURNFUNC(rc); } } break; default: *ptt = priv->ptt; break; } RETURNFUNC(RIG_OK); } static int dummy_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { static int twiddle = 0; ENTERFUNC; usleep(CMDSLEEP); *dcd = (twiddle++ & 1) ? RIG_DCD_ON : RIG_DCD_OFF; RETURNFUNC(RIG_OK); } static int dummy_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->rptr_shift = rptr_shift; RETURNFUNC(RIG_OK); } static int dummy_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); *rptr_shift = curr->rptr_shift; RETURNFUNC(RIG_OK); } static int dummy_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->rptr_offs = rptr_offs; RETURNFUNC(RIG_OK); } static int dummy_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *rptr_offs = curr->rptr_offs; RETURNFUNC(RIG_OK); } static int dummy_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->ctcss_tone = tone; RETURNFUNC(RIG_OK); } static int dummy_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); *tone = curr->ctcss_tone; RETURNFUNC(RIG_OK); } static int dummy_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->dcs_code = code; RETURNFUNC(RIG_OK); } static int dummy_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); *code = curr->dcs_code; RETURNFUNC(RIG_OK); } static int dummy_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; usleep(CMDSLEEP); curr->ctcss_sql = tone; RETURNFUNC(RIG_OK); } static int dummy_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *tone = curr->ctcss_sql; RETURNFUNC(RIG_OK); } static int dummy_set_dcs_sql(RIG *rig, vfo_t vfo, unsigned int code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->dcs_sql = code; RETURNFUNC(RIG_OK); } static int dummy_get_dcs_sql(RIG *rig, vfo_t vfo, unsigned int *code) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *code = curr->dcs_sql; RETURNFUNC(RIG_OK); } static int dummy_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), tx_freq); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but set_split_freq() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_set_freq(rig, priv->tx_vfo, tx_freq); priv->curr->tx_freq = tx_freq; rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f\n", __func__, tx_freq); RETURNFUNC(retval); } static int dummy_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but get_split_freq() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_get_freq(rig, priv->tx_vfo, tx_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: freq=%.0f\n", __func__, *tx_freq); RETURNFUNC(retval); } static int dummy_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s tx_mode=%s tx_width=%ld\n", __func__, rig_strvfo(vfo), rig_strrmode(tx_mode), tx_width); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but set_split_mode() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_set_mode(rig, priv->tx_vfo, tx_mode, tx_width); curr->tx_mode = tx_mode; if (RIG_PASSBAND_NOCHANGE == tx_width) { RETURNFUNC(retval); } curr->tx_width = tx_width; RETURNFUNC(retval); } static int dummy_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (priv->split == RIG_SPLIT_OFF || priv->tx_vfo == RIG_VFO_NONE || priv->tx_vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_WARN, "%s: split not enabled, but get_split_mode() called? ignoring\n", __func__); RETURNFUNC(RIG_OK); } retval = dummy_get_mode(rig, priv->tx_vfo, tx_mode, tx_width); rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s tx_mode=%s tx_width=%ld\n", __func__, rig_strvfo(vfo), rig_strrmode(*tx_mode), *tx_width); RETURNFUNC(retval); } static int dummy_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d, vfo=%s, tx_vfo=%s\n", __func__, split, rig_strvfo(vfo), rig_strvfo(tx_vfo)); if (tx_vfo == RIG_VFO_NONE || tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->curr_vfo; } if (tx_vfo == RIG_VFO_CURR || tx_vfo == RIG_VFO_TX) { tx_vfo = vfo_fixup(rig, vfo, CACHE(rig)->split); } priv->split = split; priv->tx_vfo = tx_vfo; RETURNFUNC(RIG_OK); } static int dummy_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; *split = priv->split; *tx_vfo = priv->tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d, vfo=%s, tx_vfo=%s\n", __func__, *split, rig_strvfo(vfo), rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } static int dummy_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->rit = rit; RETURNFUNC(RIG_OK); } static int dummy_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *rit = curr->rit; RETURNFUNC(RIG_OK); } static int dummy_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->xit = xit; RETURNFUNC(RIG_OK); } static int dummy_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *xit = curr->xit; RETURNFUNC(RIG_OK); } static int dummy_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; curr->tuning_step = ts; RETURNFUNC(RIG_OK); } static int dummy_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *ts = curr->tuning_step; RETURNFUNC(RIG_OK); } static int dummy_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, rig_strfunc(func), status); if (status) { curr->funcs |= func; } else { curr->funcs &= ~func; } RETURNFUNC(RIG_OK); } static int dummy_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *status = (curr->funcs & func) ? 1 : 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strfunc(func)); RETURNFUNC(RIG_OK); } static int dummy_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int idx; char lstr[32]; ENTERFUNC; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } curr->levels[idx] = val; if (RIG_LEVEL_IS_FLOAT(level)) { SNPRINTF(lstr, sizeof(lstr), "%f", val.f); } else { SNPRINTF(lstr, sizeof(lstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strlevel(level), lstr); RETURNFUNC(RIG_OK); } static int dummy_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int idx; static float rfpower = 0; ENTERFUNC; idx = rig_setting2idx(level); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } switch (level) { case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RAWSTR: if (priv->static_data) { curr->levels[idx].i = -12; } else { uint64_t level1, level2; /* make S-Meter jiggle */ int qrm = -56; if (curr->freq < MHz(7)) { qrm = -20; } else if (curr->freq < MHz(21)) { qrm = -30; } else if (curr->freq < MHz(50)) { qrm = -50; } level1 = LVL_ATT; level2 = LVL_PREAMP; curr->levels[idx].i = qrm + (time(NULL) % 32) + (rand() % 4) - curr->levels[level1].i + curr->levels[level2].i; } break; case RIG_LEVEL_RFPOWER_METER: if (priv->static_data) { curr->levels[idx].f = 0.5f; } else { curr->levels[idx].f = (float)(time(NULL) % 32) / 64.0f + (float)( rand() % 4) / 8.0f; rfpower = curr->levels[idx].f; } break; case RIG_LEVEL_RFPOWER_METER_WATTS: if (priv->static_data) { curr->levels[idx].f = 50.0f; } else { #if 0 curr->levels[idx].f = (float)(time(NULL) % 32) / 64.0f + (float)( rand() % 4) / 8.0f; #endif curr->levels[idx].f = 100.0f * rfpower; } break; case RIG_LEVEL_COMP_METER: if (priv->static_data) { curr->levels[idx].f = 3.5f; } else { curr->levels[idx].f = 0.5f + (float)(time(NULL) % 32) / 16.0f + (float)( rand() % 200) / 20.0f; } break; case RIG_LEVEL_VD_METER: if (priv->static_data) { curr->levels[idx].f = 13.82f; } else { curr->levels[idx].f = 13.82f + (float)(time(NULL) % 10) / 50.0f - (float)( rand() % 10) / 40.0f; } break; case RIG_LEVEL_ID_METER: if (priv->static_data) { curr->levels[idx].f = 0.85f; } else { curr->levels[idx].f = 2.0f + (float)(time(NULL) % 320) / 16.0f - (float)( rand() % 40) / 20.0f; } break; } memcpy(val, &curr->levels[idx], sizeof(value_t)); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strlevel(level)); RETURNFUNC(RIG_OK); } static int dummy_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; char lstr[64]; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICLEVEL: case TOK_EL_MAGICFUNC: case TOK_EL_MAGICOP: case TOK_EL_MAGICCOMBO: break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } elp = find_ext(curr->ext_levels, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ elp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int dummy_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICLEVEL: case TOK_EL_MAGICFUNC: case TOK_EL_MAGICOP: case TOK_EL_MAGICCOMBO: break; default: RETURNFUNC(-RIG_EINVAL); } elp = find_ext(curr->ext_levels, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = elp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int dummy_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICEXTFUNC: break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_CHECKBUTTON: break; case RIG_CONF_BUTTON: break; default: RETURNFUNC(-RIG_EINTERNAL); } elp = find_ext(priv->ext_funcs, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ elp->val.i = status; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, cfp->name, status); RETURNFUNC(RIG_OK); } static int dummy_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *elp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EL_MAGICEXTFUNC: break; default: RETURNFUNC(-RIG_EINVAL); } elp = find_ext(priv->ext_funcs, token); if (!elp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *status = elp->val.i; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int dummy_set_powerstat(RIG *rig, powerstat_t status) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; priv->powerstat = status; RETURNFUNC(RIG_OK); } static int dummy_get_powerstat(RIG *rig, powerstat_t *status) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; *status = priv->powerstat; RETURNFUNC(RIG_OK); } static int dummy_set_parm(RIG *rig, setting_t parm, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int idx; char pstr[32]; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } if (RIG_PARM_IS_FLOAT(parm)) { SNPRINTF(pstr, sizeof(pstr), "%f", val.f); } if (RIG_PARM_IS_STRING(parm)) { strcpy(pstr, val.cs); } else { SNPRINTF(pstr, sizeof(pstr), "%d", val.i); } rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strparm(parm), pstr); priv->parms[idx] = val; RETURNFUNC(RIG_OK); } static int dummy_get_parm(RIG *rig, setting_t parm, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; int idx; ENTERFUNC; idx = rig_setting2idx(parm); if (idx >= RIG_SETTING_MAX) { RETURNFUNC(-RIG_EINVAL); } *val = priv->parms[idx]; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strparm(parm)); RETURNFUNC(RIG_OK); } static int dummy_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; char lstr[64]; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EP_MAGICPARM: break; default: RETURNFUNC(-RIG_EINVAL); } switch (cfp->type) { case RIG_CONF_STRING: strcpy(lstr, val.s); break; case RIG_CONF_COMBO: SNPRINTF(lstr, sizeof(lstr), "%d", val.i); break; case RIG_CONF_NUMERIC: SNPRINTF(lstr, sizeof(lstr), "%f", val.f); break; case RIG_CONF_CHECKBUTTON: SNPRINTF(lstr, sizeof(lstr), "%s", val.i ? "ON" : "OFF"); break; case RIG_CONF_BUTTON: lstr[0] = '\0'; break; default: RETURNFUNC(-RIG_EINTERNAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* store value */ epp->val = val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, cfp->name, lstr); RETURNFUNC(RIG_OK); } static int dummy_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const struct confparams *cfp; struct ext_list *epp; ENTERFUNC; /* TODO: load value from priv->ext_parms */ cfp = rig_ext_lookup_tok(rig, token); if (!cfp) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_EP_MAGICPARM: break; default: RETURNFUNC(-RIG_EINVAL); } epp = find_ext(priv->ext_parms, token); if (!epp) { RETURNFUNC(-RIG_EINTERNAL); } /* load value */ *val = epp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); RETURNFUNC(RIG_OK); } static int dummy_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; ENTERFUNC; switch (ant) { case RIG_ANT_CURR: break; case RIG_ANT_1: case RIG_ANT_2: case RIG_ANT_3: case RIG_ANT_4: curr->ant = ant; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown antenna requested=0x%02x\n", __func__, ant); RETURNFUNC(-RIG_EINVAL); } priv->ant_option[rig_setting2idx(curr->ant)] = option.i; rig_debug(RIG_DEBUG_VERBOSE, "%s called ant=0x%02x, option=%d, curr->ant=0x%02x\n", __func__, ant, option.i, curr->ant); RETURNFUNC(RIG_OK); } static int dummy_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x\n", __func__, ant); switch (ant) { case RIG_ANT_CURR: *ant_curr = curr->ant; break; case RIG_ANT_1: case RIG_ANT_2: case RIG_ANT_3: case RIG_ANT_4: *ant_curr = ant; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown antenna requested=0x%02x\n", __func__, ant); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: ant_curr=0x%02x, idx=%d\n", __func__, *ant_curr, rig_setting2idx(*ant_curr)); option->i = priv->ant_option[rig_setting2idx(*ant_curr)]; RETURNFUNC(RIG_OK); } static int dummy_set_bank(RIG *rig, vfo_t vfo, int bank) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; priv->bank = bank; RETURNFUNC(RIG_OK); } static int dummy_set_mem(RIG *rig, vfo_t vfo, int ch) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; if (ch < 0 || ch >= NB_CHAN) { RETURNFUNC(-RIG_EINVAL); } if (priv->curr_vfo == RIG_VFO_MEM) { priv->curr = &priv->mem[ch]; } else { priv->curr->channel_num = ch; } RETURNFUNC(RIG_OK); } static int dummy_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; const channel_t *curr = priv->curr; ENTERFUNC; *ch = curr->channel_num; RETURNFUNC(RIG_OK); } static int dummy_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %d\n", __func__, rig_strscan(scan), ch); /* TODO: change freq, etc. */ RETURNFUNC(RIG_OK); } static void chan_vfo(channel_t *chan, vfo_t vfo) { chan->vfo = vfo; strcpy(chan->channel_desc, rig_strvfo(vfo)); } static int dummy_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; channel_t *curr = priv->curr; int ret; freq_t freq; shortfreq_t ts; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strvfop(op)); switch (op) { case RIG_OP_FROM_VFO: /* VFO->MEM */ if (priv->curr_vfo == RIG_VFO_MEM) { int ch = curr->channel_num; copy_chan(curr, priv->last_vfo == RIG_VFO_A ? &priv->vfo_maina : &priv->vfo_mainb); curr->channel_num = ch; curr->channel_desc[0] = '\0'; curr->vfo = RIG_VFO_MEM; } else { channel_t *mem_chan = &priv->mem[curr->channel_num]; copy_chan(mem_chan, curr); mem_chan->channel_num = curr->channel_num; mem_chan->channel_desc[0] = '\0'; mem_chan->vfo = RIG_VFO_MEM; } break; case RIG_OP_TO_VFO: /* MEM->VFO */ if (priv->curr_vfo == RIG_VFO_MEM) { channel_t *vfo_chan = (priv->last_vfo == RIG_VFO_A) ? &priv->vfo_maina : &priv->vfo_mainb; copy_chan(vfo_chan, curr); chan_vfo(vfo_chan, priv->last_vfo); } else { copy_chan(&priv->mem[curr->channel_num], curr); chan_vfo(curr, priv->curr_vfo); } break; case RIG_OP_CPY: /* VFO A = VFO B or VFO B = VFO A */ if (priv->curr_vfo == RIG_VFO_A) { copy_chan(&priv->vfo_mainb, &priv->vfo_maina); chan_vfo(&priv->vfo_mainb, RIG_VFO_B); break; } else if (priv->curr_vfo == RIG_VFO_B) { copy_chan(&priv->vfo_maina, &priv->vfo_mainb); chan_vfo(&priv->vfo_maina, RIG_VFO_A); break; } rig_debug(RIG_DEBUG_VERBOSE, "%s beep!\n", __func__); break; case RIG_OP_XCHG: /* Exchange VFO A/B */ { channel_t chan; chan.ext_levels = alloc_init_ext(dummy_ext_levels); if (!chan.ext_levels) { RETURNFUNC(-RIG_ENOMEM); } copy_chan(&chan, &priv->vfo_mainb); copy_chan(&priv->vfo_mainb, &priv->vfo_maina); copy_chan(&priv->vfo_maina, &chan); chan_vfo(&priv->vfo_maina, RIG_VFO_A); chan_vfo(&priv->vfo_mainb, RIG_VFO_B); free(chan.ext_levels); break; } case RIG_OP_MCL: /* Memory clear */ if (priv->curr_vfo == RIG_VFO_MEM) { struct ext_list *saved_ext_levels = curr->ext_levels; int saved_ch = curr->channel_num; int i; for (i = 0; !RIG_IS_EXT_END(curr->ext_levels[i]); i++) { curr->ext_levels[i].val.i = 0; } memset(curr, 0, sizeof(channel_t)); curr->ext_levels = saved_ext_levels; curr->channel_num = saved_ch; curr->vfo = RIG_VFO_MEM; } else { struct ext_list *saved_ext_levels = curr->ext_levels; channel_t *mem_chan = &priv->mem[curr->channel_num]; int i; for (i = 0; !RIG_IS_EXT_END(mem_chan->ext_levels[i]); i++) { mem_chan->ext_levels[i].val.i = 0; } memset(mem_chan, 0, sizeof(channel_t)); mem_chan->ext_levels = saved_ext_levels; mem_chan->channel_num = curr->channel_num; mem_chan->vfo = RIG_VFO_MEM; } break; case RIG_OP_TOGGLE: if (priv->curr_vfo == RIG_VFO_A) { RETURNFUNC(dummy_set_vfo(rig, RIG_VFO_B)); } else if (priv->curr_vfo == RIG_VFO_B) { RETURNFUNC(dummy_set_vfo(rig, RIG_VFO_A)); } else { RETURNFUNC(-RIG_EVFO); } case RIG_OP_RIGHT: case RIG_OP_LEFT: case RIG_OP_TUNE: /* NOP */ break; case RIG_OP_BAND_UP: case RIG_OP_BAND_DOWN: RETURNFUNC(-RIG_ENIMPL); case RIG_OP_UP: ret = dummy_get_freq(rig, vfo, &freq); if (!ret) { break; } ret = dummy_get_ts(rig, vfo, &ts); if (!ret) { break; } dummy_set_freq(rig, vfo, freq + ts); /* up */ break; case RIG_OP_DOWN: ret = dummy_get_freq(rig, vfo, &freq); if (!ret) { break; } ret = dummy_get_ts(rig, vfo, &ts); if (!ret) { break; } dummy_set_freq(rig, vfo, freq - ts); /* down */ break; default: break; } RETURNFUNC(RIG_OK); } static int dummy_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; if (!chan->ext_levels) { RETURNFUNC(-RIG_EINVAL); } if (chan->channel_num < 0 || chan->channel_num >= NB_CHAN) { RETURNFUNC(-RIG_EINVAL); } /* TODO: * - check ext_levels is the right length */ switch (chan->vfo) { case RIG_VFO_MEM: copy_chan(&priv->mem[chan->channel_num], chan); break; case RIG_VFO_A: copy_chan(&priv->vfo_maina, chan); break; case RIG_VFO_B: copy_chan(&priv->vfo_mainb, chan); break; case RIG_VFO_CURR: copy_chan(priv->curr, chan); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; ENTERFUNC; if (chan->channel_num < 0 || chan->channel_num >= NB_CHAN) { RETURNFUNC(-RIG_EINVAL); } if (!chan->ext_levels) { chan->ext_levels = alloc_init_ext(dummy_ext_levels); if (!chan->ext_levels) { RETURNFUNC(-RIG_ENOMEM); } } /* TODO: * - check ext_levels is the right length */ switch (chan->vfo) { case RIG_VFO_MEM: copy_chan(chan, &priv->mem[chan->channel_num]); break; case RIG_VFO_A: copy_chan(chan, &priv->vfo_maina); break; case RIG_VFO_B: copy_chan(chan, &priv->vfo_mainb); break; case RIG_VFO_CURR: copy_chan(chan, priv->curr); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } static int dummy_set_trn(RIG *rig, int trn) { struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; priv->trn = trn; RETURNFUNC2(RIG_OK); } static int dummy_get_trn(RIG *rig, int *trn) { const struct dummy_priv_data *priv = (struct dummy_priv_data *)STATE(rig)->priv; *trn = priv->trn; RETURNFUNC2(RIG_OK); } static const char *dummy_get_info(RIG *rig) { return "Nothing much (dummy)"; } static int dummy_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, digits); RETURNFUNC(RIG_OK); } static int dummy_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { ENTERFUNC; strcpy(digits, "0123456789ABCDEF"); *length = 16; RETURNFUNC(RIG_OK); } static int dummy_send_morse(RIG *rig, vfo_t vfo, const char *msg) { ENTERFUNC; RETURNFUNC(RIG_OK); } static int dummy_stop_morse(RIG *rig, vfo_t vfo) { ENTERFUNC; RETURNFUNC(RIG_OK); } static int dummy_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { ENTERFUNC; RETURNFUNC(RIG_OK); } static int dummy_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); /* Pretend this is a 100W radio */ *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int dummy_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); /* Pretend this is a 100W radio */ if (mwpower > 100000) { RETURNFUNC(-RIG_EINVAL); } *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } static int m_year, m_month, m_day, m_hour, m_min, m_sec, m_utc_offset; static double m_msec; int dummy_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int retval = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: %04d-%02d-%02dT%02d:%02d:%02d.%.03f%s%02u\n", __func__, year, month, day, hour, min, sec, msec, utc_offset >= 0 ? "+" : "-", (unsigned)(abs(utc_offset))); m_year = year; m_month = month; m_day = day; if (hour >= 0) { m_hour = hour; m_min = min; m_sec = sec; m_msec = msec; m_utc_offset = utc_offset; } return retval; } int dummy_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int retval = RIG_OK; *year = m_year; *month = m_month; *day = m_day; *hour = m_hour; *min = m_min; *sec = m_sec; *msec = m_msec; *utc_offset = m_utc_offset; rig_debug(RIG_DEBUG_VERBOSE, "%s: %02d-%02d-%02dT%02d:%02d:%02d:%0.3lf%s%02u\n'", __func__, *year, *month, *day, *hour, *min, *sec, *msec, *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); return retval; } /* * Dummy rig capabilities. */ /* * The following macros set bitmasks for the various funcs, levels, parms, * etc. This dummy backend claims support for almost all of them. */ #define DUMMY_FUNC ((setting_t)-1ULL) /* All possible functions */ #define DUMMY_LEVEL (((setting_t)-1ULL)&~(1ULL<<27)) /* All levels except SQLSTAT */ #define DUMMY_PARM ((setting_t)-1ULL) /* All possible parms */ #define DUMMY_VFO_OP 0x7ffffffUL /* All possible VFO OPs */ #define DUMMY_SCAN 0x7ffffffUL /* All possible scan OPs */ #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 | \ RIG_MODE_CWR | RIG_MODE_RTTYR) #define DUMMY_MEM_CAP { \ .bank_num = 1, \ .vfo = 1, \ .ant = 1, \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .split = 1, \ .rptr_shift = 1, \ .rptr_offs = 1, \ .tuning_step = 1, \ .rit = 1, \ .xit = 1, \ .funcs = DUMMY_FUNC, \ .levels = RIG_LEVEL_SET(DUMMY_LEVEL), \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .dcs_code = 1, \ .dcs_sql = 1, \ .scan_group = 1, \ .flags = 1, \ .channel_desc = 1, \ .ext_levels = 1, \ } struct rig_caps dummy_caps = { RIG_MODEL(RIG_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", .version = "20240709.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = RIG_TARGETABLE_PTT | RIG_TARGETABLE_RITXIT | RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NONE, .has_get_func = DUMMY_FUNC, .has_set_func = DUMMY_FUNC, .has_get_level = DUMMY_LEVEL, .has_set_level = RIG_LEVEL_SET(DUMMY_LEVEL), .has_get_parm = DUMMY_PARM, .has_set_parm = RIG_PARM_SET(DUMMY_PARM), .level_gran = { [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0f / 255.0f } }, [LVL_RFPOWER] = { .min = { .f = .05f }, .max = { .f = 1 }, .step = { .f = 1.0f / 511.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0f }, .max = { .f = 1 }, .step = { .f = 1.0f / 255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0f }, .max = { .f = 100 }, .step = { .f = 1.0f / 255.0f } }, [LVL_CWPITCH] = { .step = { .i = 10 } }, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -30.0f}, .max = {.f = 10.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .chan_list = { { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, { 19, 19, RIG_MTYPE_CALL }, { 20, NB_CHAN - 1, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .scan_ops = DUMMY_SCAN, .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .preamp = { 10, RIG_DBLST_END, }, .agc_level_count = 7, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SUPERFAST, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO, RIG_AGC_USER }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = W(5), .high_power = W(100), DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#2" }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DUMMY_MODES, 1}, {DUMMY_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_RTTY, Hz(300)}, {RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_RTTY, Hz(50)}, {RIG_MODE_RTTY, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .max_rit = 9990, .max_xit = 9990, .max_ifshift = 10000, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .spectrum_attenuator = { 10, 20, 30, RIG_DBLST_END, }, .priv = NULL, /* priv */ .extlevels = dummy_ext_levels, .extfuncs = dummy_ext_funcs, .extparms = dummy_ext_parms, .cfgparams = dummy_cfg_params, .rig_init = dummy_init, .rig_cleanup = dummy_cleanup, .rig_open = dummy_open, .rig_close = dummy_close, .set_conf = dummy_set_conf, .get_conf = dummy_get_conf, .set_freq = dummy_set_freq, .get_freq = dummy_get_freq, .set_mode = dummy_set_mode, .get_mode = dummy_get_mode, .set_vfo = dummy_set_vfo, .get_vfo = dummy_get_vfo, .set_powerstat = dummy_set_powerstat, .get_powerstat = dummy_get_powerstat, .set_level = dummy_set_level, .get_level = dummy_get_level, .set_func = dummy_set_func, .get_func = dummy_get_func, .set_parm = dummy_set_parm, .get_parm = dummy_get_parm, .set_ext_level = dummy_set_ext_level, .get_ext_level = dummy_get_ext_level, .set_ext_func = dummy_set_ext_func, .get_ext_func = dummy_get_ext_func, .set_ext_parm = dummy_set_ext_parm, .get_ext_parm = dummy_get_ext_parm, .get_info = dummy_get_info, .set_ptt = dummy_set_ptt, .get_ptt = dummy_get_ptt, .get_dcd = dummy_get_dcd, .set_rptr_shift = dummy_set_rptr_shift, .get_rptr_shift = dummy_get_rptr_shift, .set_rptr_offs = dummy_set_rptr_offs, .get_rptr_offs = dummy_get_rptr_offs, .set_ctcss_tone = dummy_set_ctcss_tone, .get_ctcss_tone = dummy_get_ctcss_tone, .set_dcs_code = dummy_set_dcs_code, .get_dcs_code = dummy_get_dcs_code, .set_ctcss_sql = dummy_set_ctcss_sql, .get_ctcss_sql = dummy_get_ctcss_sql, .set_dcs_sql = dummy_set_dcs_sql, .get_dcs_sql = dummy_get_dcs_sql, .set_split_freq = dummy_set_split_freq, .get_split_freq = dummy_get_split_freq, .set_split_mode = dummy_set_split_mode, .get_split_mode = dummy_get_split_mode, .set_split_vfo = dummy_set_split_vfo, .get_split_vfo = dummy_get_split_vfo, .set_rit = dummy_set_rit, .get_rit = dummy_get_rit, .set_xit = dummy_set_xit, .get_xit = dummy_get_xit, .set_ts = dummy_set_ts, .get_ts = dummy_get_ts, .set_ant = dummy_set_ant, .get_ant = dummy_get_ant, .set_bank = dummy_set_bank, .set_mem = dummy_set_mem, .get_mem = dummy_get_mem, .vfo_op = dummy_vfo_op, .scan = dummy_scan, .send_dtmf = dummy_send_dtmf, .recv_dtmf = dummy_recv_dtmf, .send_morse = dummy_send_morse, .stop_morse = dummy_stop_morse, .send_voice_mem = dummy_send_voice_mem, .set_channel = dummy_set_channel, .get_channel = dummy_get_channel, .set_trn = dummy_set_trn, .get_trn = dummy_get_trn, .power2mW = dummy_power2mW, .mW2power = dummy_mW2power, .set_clock = dummy_set_clock, .get_clock = dummy_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps dummy_no_vfo_caps = { RIG_MODEL(RIG_MODEL_DUMMY_NOVFO), .model_name = "Dummy No VFO", .mfg_name = "Hamlib", .version = "20240409.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = RIG_TARGETABLE_PTT | RIG_TARGETABLE_RITXIT | RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NONE, .has_get_func = DUMMY_FUNC, .has_set_func = DUMMY_FUNC, .has_get_level = DUMMY_LEVEL, .has_set_level = RIG_LEVEL_SET(DUMMY_LEVEL), .has_get_parm = DUMMY_PARM, .has_set_parm = RIG_PARM_SET(DUMMY_PARM), .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .chan_list = { { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, { 19, 19, RIG_MTYPE_CALL }, { 20, NB_CHAN - 1, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .scan_ops = DUMMY_SCAN, .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .preamp = { 10, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = W(5), .high_power = W(100), DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#1" }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DUMMY_MODES, .low_power = -1, .high_power = -1, DUMMY_VFOS, RIG_ANT_1 | RIG_ANT_2 | RIG_ANT_3 | RIG_ANT_4, .label = "Dummy#2" }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DUMMY_MODES, 1}, {DUMMY_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_RTTY, Hz(300)}, {RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_RTTY, Hz(50)}, {RIG_MODE_RTTY, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .max_rit = 9990, .max_xit = 9990, .max_ifshift = 10000, .priv = NULL, /* priv */ .extlevels = dummy_ext_levels, .extfuncs = dummy_ext_funcs, .extparms = dummy_ext_parms, .cfgparams = dummy_cfg_params, .rig_init = dummy_init, .rig_cleanup = dummy_cleanup, .rig_open = dummy_open, .rig_close = dummy_close, .set_conf = dummy_set_conf, .get_conf = dummy_get_conf, .set_freq = dummy_set_freq, .get_freq = dummy_get_freq, .set_mode = dummy_set_mode, .get_mode = dummy_get_mode, .set_vfo = dummy_set_vfo, .get_vfo = dummy_get_vfo, .set_powerstat = dummy_set_powerstat, .get_powerstat = dummy_get_powerstat, .set_level = dummy_set_level, .get_level = dummy_get_level, .set_func = dummy_set_func, .get_func = dummy_get_func, .set_parm = dummy_set_parm, .get_parm = dummy_get_parm, .set_ext_level = dummy_set_ext_level, .get_ext_level = dummy_get_ext_level, .set_ext_func = dummy_set_ext_func, .get_ext_func = dummy_get_ext_func, .set_ext_parm = dummy_set_ext_parm, .get_ext_parm = dummy_get_ext_parm, .get_info = dummy_get_info, .set_ptt = dummy_set_ptt, .get_ptt = dummy_get_ptt, .get_dcd = dummy_get_dcd, .set_rptr_shift = dummy_set_rptr_shift, .get_rptr_shift = dummy_get_rptr_shift, .set_rptr_offs = dummy_set_rptr_offs, .get_rptr_offs = dummy_get_rptr_offs, .set_ctcss_tone = dummy_set_ctcss_tone, .get_ctcss_tone = dummy_get_ctcss_tone, .set_dcs_code = dummy_set_dcs_code, .get_dcs_code = dummy_get_dcs_code, .set_ctcss_sql = dummy_set_ctcss_sql, .get_ctcss_sql = dummy_get_ctcss_sql, .set_dcs_sql = dummy_set_dcs_sql, .get_dcs_sql = dummy_get_dcs_sql, .set_split_freq = dummy_set_split_freq, .get_split_freq = dummy_get_split_freq, .set_split_mode = dummy_set_split_mode, .get_split_mode = dummy_get_split_mode, .set_split_vfo = dummy_set_split_vfo, .get_split_vfo = dummy_get_split_vfo, .set_rit = dummy_set_rit, .get_rit = dummy_get_rit, .set_xit = dummy_set_xit, .get_xit = dummy_get_xit, .set_ts = dummy_set_ts, .get_ts = dummy_get_ts, .set_ant = dummy_set_ant, .get_ant = dummy_get_ant, .set_bank = dummy_set_bank, .set_mem = dummy_set_mem, .get_mem = dummy_get_mem, .vfo_op = dummy_vfo_op, .scan = dummy_scan, .send_dtmf = dummy_send_dtmf, .recv_dtmf = dummy_recv_dtmf, .send_morse = dummy_send_morse, .send_voice_mem = dummy_send_voice_mem, .set_channel = dummy_set_channel, .get_channel = dummy_get_channel, .set_trn = dummy_set_trn, .get_trn = dummy_get_trn, .power2mW = dummy_power2mW, .mW2power = dummy_mW2power, .set_clock = dummy_set_clock, .get_clock = dummy_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; DECLARE_INITRIG_BACKEND(dummy) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&dummy_caps); rig_register(&netrigctl_caps); rig_register(&flrig_caps); rig_register(&trxmanager_caps); rig_register(&dummy_no_vfo_caps); rig_register(&aclog_caps); rig_register(&sdrsharp_caps); rig_register(&quisk_caps); // rig_register(&tci1x_caps); return RIG_OK; } hamlib-4.6.2/rigs/dummy/netampctl.c0000644000175000017500000001126614752216205014144 00000000000000/* * Hamlib Netampctl backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/amplifier.h" #include "iofunc.h" #define CMD_MAX 32 #define BUF_MAX 64 /* * Helper function with protocol return code parsing */ static int netampctl_transaction(AMP *amp, char *cmd, int len, char *buf) { int ret; hamlib_port_t *ampp = AMPPORT(amp); ret = write_block(ampp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(ampp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret < 0) { return ret; } if (!memcmp(buf, NETAMPCTL_RET, strlen(NETAMPCTL_RET))) { return atoi(buf + strlen(NETAMPCTL_RET)); } return ret; } static int netampctl_open(AMP *amp) { int ret; //struct amp_state *rs = AMPSTATE(amp); hamlib_port_t *ampp = AMPPORT(amp); int pamp_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = netampctl_transaction(amp, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } pamp_ver = atoi(buf); #define AMPCTLD_PAMP_VER 0 if (pamp_ver < AMPCTLD_PAMP_VER) { return -RIG_EPROTO; } ret = read_string(ampp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } do { ret = read_string(ampp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret > 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, string=%s\n", __func__, buf); } } while (ret > 0); if (ret < 0) { return -RIG_EPROTO; } return RIG_OK; } static int netampctl_close(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* clean signoff, no read back */ write_block(AMPPORT(amp), (unsigned char *) "q\n", 2); return RIG_OK; } static int netampctl_set_freq(AMP *amp, freq_t freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENIMPL; } static int netampctl_get_freq(AMP *amp, freq_t *freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *freq = 12345; return -RIG_ENIMPL; } #if 0 static int netampctl_reset(AMP *amp, amp_reset_t reset) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "R %d\n", reset); ret = netampctl_transaction(amp, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } #endif static const char *netampctl_get_info(AMP *amp) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = netampctl_transaction(amp, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } /* * NET ampctl capabilities. */ const struct amp_caps netampctl_caps = { AMP_MODEL(AMP_MODEL_NETAMPCTL), .model_name = "NET ampctl", .mfg_name = "Hamlib", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_NETWORK, .timeout = 2000, .retry = 3, .priv = NULL, /* priv */ /* .amp_init = netampctl_init, */ /* .amp_cleanup = netampctl_cleanup, */ .amp_open = netampctl_open, .amp_close = netampctl_close, .get_freq = netampctl_get_freq, .set_freq = netampctl_set_freq, .get_info = netampctl_get_info }; hamlib-4.6.2/rigs/dummy/amp_dummy.c0000644000175000017500000002167014752216205014145 00000000000000/* * Hamlib Dummy backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/amplifier.h" #include "serial.h" #include "register.h" #include "amp_dummy.h" #if 0 static const struct confparams dummy_amp_ext_levels[] = { { AMP_LEVEL_SWR, "SWR", "SWR", "SWR", NULL, RIG_CONF_NUMERIC, { .n = { 1, 99, .1 } } } }; #endif #define AMP_LEVELS (AMP_LEVEL_SWR|AMP_LEVEL_PF|AMP_LEVEL_NH|AMP_LEVEL_PWR_INPUT|AMP_LEVEL_PWR_FWD|AMP_LEVEL_PWR_REFLECTED|AMP_LEVEL_PWR_PEAK|AMP_LEVEL_FAULT) struct dummy_amp_priv_data { freq_t freq; powerstat_t powerstat; }; static int dummy_amp_init(AMP *amp) { struct dummy_amp_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); AMPSTATE(amp)->priv = (struct dummy_amp_priv_data *) calloc(1, sizeof(struct dummy_amp_priv_data)); if (!AMPSTATE(amp)->priv) { return -RIG_ENOMEM; } priv = AMPSTATE(amp)->priv; AMPPORT(amp)->type.rig = RIG_PORT_NONE; priv->freq = 0; return RIG_OK; } static int dummy_amp_cleanup(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (AMPSTATE(amp)->priv) { free(AMPSTATE(amp)->priv); } AMPSTATE(amp)->priv = NULL; return RIG_OK; } static int dummy_amp_open(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_amp_close(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } static int dummy_amp_reset(AMP *amp, amp_reset_t reset) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (reset) { case AMP_RESET_MEM: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset memory\n", __func__); break; case AMP_RESET_FAULT: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset fault\n", __func__); break; case AMP_RESET_AMP: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset amplifier\n", __func__); break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Reset unknown=%d\n", __func__, reset); return -RIG_EINVAL; } return RIG_OK; } /* ^ON1 turns amp on ^ON0 turns amp off ^OP0 amp in standby ^OP1 amp in operate ^PWF which gets forward power from amp. Reply would be ^PWFnnnn format ^PWK which gets peak forward power. Response is ^PWKnnnn ^PWR peak reflected power. Response is ^PWRnnnn ^SW gets SWR. Response is ^SWnnn. Example return of ^SW025 would be 2.5:1 Also a way to display faults (there are commands) */ static int dummy_amp_get_freq(AMP *amp, freq_t *freq) { const struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *freq = priv->freq; return RIG_OK; } static int dummy_amp_set_freq(AMP *amp, freq_t freq) { struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv->freq = freq; return RIG_OK; } static const char *dummy_amp_get_info(AMP *amp) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return "Dummy amplifier"; } static int dummy_amp_get_level(AMP *amp, setting_t level, value_t *val) { static int flag = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); flag = !flag; // values toggle between two expected min/~max values for dev purposes switch (level) { case AMP_LEVEL_SWR: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_SWR\n", __func__); val->f = flag == 0 ? 1.0 : 99.0; return RIG_OK; case AMP_LEVEL_PF: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PF\n", __func__); val->f = flag == 0 ? 0 : 2701.2; return RIG_OK; case AMP_LEVEL_NH: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_UH\n", __func__); val->i = flag == 0 ? 0 : 8370; return RIG_OK; case AMP_LEVEL_PWR_INPUT: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRINPUT\n", __func__); val->i = flag == 0 ? 0 : 1499 ; return RIG_OK; case AMP_LEVEL_PWR_FWD: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRFWD\n", __func__); val->i = flag == 0 ? 0 : 1499 ; return RIG_OK; case AMP_LEVEL_PWR_REFLECTED: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRREFLECTED\n", __func__); val->i = flag == 0 ? 0 : 1499 ; return RIG_OK; case AMP_LEVEL_PWR_PEAK: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_PWRPEAK\n", __func__); val->i = flag == 0 ? 0 : 1500 ; return RIG_OK; case AMP_LEVEL_FAULT: rig_debug(RIG_DEBUG_VERBOSE, "%s AMP_LEVEL_FAULT\n", __func__); val->s = flag == 0 ? "No Fault" : "SWR too high"; // SWR too high for KPA1500 return RIG_OK; default: rig_debug(RIG_DEBUG_VERBOSE, "%s Unknown AMP_LEVEL=%s\n", __func__, rig_strlevel(level)); } rig_debug(RIG_DEBUG_VERBOSE, "%s flag=%d\n", __func__, flag); return -RIG_EINVAL; } static int dummy_amp_set_powerstat(AMP *amp, powerstat_t status) { struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; switch (status) { case RIG_POWER_OFF: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_OFF\n", __func__); break; case RIG_POWER_ON: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_ON\n", __func__); break; case RIG_POWER_STANDBY: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_STANDBY\n", __func__); break; case RIG_POWER_OPERATE: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_OPERATE\n", __func__); break; case RIG_POWER_UNKNOWN: rig_debug(RIG_DEBUG_VERBOSE, "%s called POWER_UNKNOWN\n", __func__); break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s called invalid power status=%d\n", __func__, status); return -RIG_EINVAL; break; } priv->powerstat = status; return RIG_OK; } static int dummy_amp_get_powerstat(AMP *amp, powerstat_t *status) { const struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; *status = priv->powerstat; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } #if 0 // not implemented yet static int dummy_amp_get_ext_level(AMP *amp, hamlib_token_t token, value_t *val) { struct dummy_amp_priv_data *priv = (struct dummy_amp_priv_data *) AMPSTATE(amp)->priv; const struct confparams *cfp; struct ext_list *elp; cfp = amp_ext_lookup_tok(amp, token); if (!cfp) { return -RIG_EINVAL; } switch (token) { case AMP_LEVEL_SWR: break; default: return -RIG_EINVAL; } elp = find_ext(curr->ext_levels, token); if (!elp) { return -RIG_EINTERNAL; } /* load value */ *val = elp->val; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, cfp->name); return RIG_OK; } #endif /* * Dummy amplifier capabilities. */ const struct amp_caps dummy_amp_caps = { AMP_MODEL(AMP_MODEL_DUMMY), .model_name = "Dummy", .mfg_name = "Hamlib", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .amp_type = AMP_TYPE_OTHER, .port_type = RIG_PORT_NONE, .has_get_level = AMP_LEVELS, .has_set_level = RIG_LEVEL_SET(AMP_LEVELS), .priv = NULL, /* priv */ .amp_init = dummy_amp_init, .amp_cleanup = dummy_amp_cleanup, .amp_open = dummy_amp_open, .amp_close = dummy_amp_close, .get_freq = dummy_amp_get_freq, .set_freq = dummy_amp_set_freq, .get_info = dummy_amp_get_info, .get_level = dummy_amp_get_level, .set_powerstat = dummy_amp_set_powerstat, .get_powerstat = dummy_amp_get_powerstat, .reset = dummy_amp_reset, }; DECLARE_INITAMP_BACKEND(dummy) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); amp_register(&dummy_amp_caps); amp_register(&netampctl_caps); return RIG_OK; } hamlib-4.6.2/rigs/dummy/rot_dummy.h0000644000175000017500000000307014752216205014173 00000000000000/* * Hamlib Dummy backend - main header * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ROT_DUMMY_H #define _ROT_DUMMY_H 1 #include "rotator.h" #include "token.h" /* backend conf */ #define TOK_CFG_ROT_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_ROT_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_ROT_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_ROT_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_ROT_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_ROT_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_ROT_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_ROT_MAGICEXTFUNC TOKEN_BACKEND(6) extern struct rot_caps dummy_rot_caps; extern struct rot_caps netrotctl_caps; extern struct rot_caps pstrotator; extern struct rot_caps satrotctl_caps; #endif /* _ROT_DUMMY_H */ hamlib-4.6.2/rigs/dummy/aclog.c0000644000175000017500000006114114752216205013237 00000000000000/* * Hamlib ACLog backend - main file * Copyright (c) 2023 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #define DEBUG 1 #define DEBUG_TRACE DEBUG_VERBOSE #define TRUE 1 #define FALSE 0 #define MAXCMDLEN 8192 #define MAXXMLLEN 8192 #define MAXARGLEN 128 #define MAXBANDWIDTHLEN 4096 #define DEFAULTPATH "127.0.0.1:1100" #define ACLOG_VFOS (RIG_VFO_A) #define ACLOG_MODES (RIG_MODE_AM | RIG_MODE_PKTAM | RIG_MODE_CW | RIG_MODE_CWR |\ RIG_MODE_RTTY | RIG_MODE_RTTYR |\ RIG_MODE_PKTLSB | RIG_MODE_PKTUSB |\ RIG_MODE_SSB | RIG_MODE_LSB | RIG_MODE_USB |\ RIG_MODE_FM | RIG_MODE_WFM | RIG_MODE_FMN | RIG_MODE_PKTFM |\ RIG_MODE_C4FM) #define streq(s1,s2) (strcmp(s1,s2)==0) struct aclog_priv_data { vfo_t curr_vfo; char bandwidths[MAXBANDWIDTHLEN]; /* pipe delimited set returned from aclog */ int nbandwidths; char info[8192]; ptt_t ptt; split_t split; rmode_t curr_modeA; rmode_t curr_modeB; freq_t curr_freqA; freq_t curr_freqB; pbwidth_t curr_widthA; pbwidth_t curr_widthB; int has_get_modeA; /* True if this function is available */ int has_get_bwA; /* True if this function is available */ int has_set_bwA; /* True if this function is available */ float powermeter_scale; /* So we can scale power meter to 0-1 */ value_t parms[RIG_SETTING_MAX]; struct ext_list *ext_parms; }; //Structure for mapping aclog dynmamic modes to hamlib modes //aclog displays modes as the rig displays them struct s_modeMap { rmode_t mode_hamlib; char *mode_aclog; }; //ACLog will provide us the modes for the selected rig //We will then put them in this struct static struct s_modeMap modeMap[] = { {RIG_MODE_USB, "|USB|"}, {RIG_MODE_USB, "|SSB|"}, {RIG_MODE_LSB, "|LSB|"}, {RIG_MODE_PKTUSB, NULL}, {RIG_MODE_PKTLSB, NULL}, {RIG_MODE_AM, "|AM|"}, {RIG_MODE_FM, "|FM|"}, {RIG_MODE_FMN, NULL}, {RIG_MODE_WFM, NULL}, {RIG_MODE_CW, "|CW|"}, {RIG_MODE_CWR, "|CWR|"}, {RIG_MODE_RTTY, "|RTTY|"}, {RIG_MODE_RTTYR, "|RTTYR|"}, {RIG_MODE_C4FM, "|C4FM|"}, {0, NULL} }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return (FALSE); } return (TRUE); } /* * read_transaction * Assumes rig!=NULL, xml!=NULL, xml_len>=MAXXMLLEN */ static int read_transaction(RIG *rig, char *xml, int xml_len) { int retval; int retry; char *delims; char *terminator = "\r\n"; ENTERFUNC; retry = 2; delims = "\n"; xml[0] = 0; do { char tmp_buf[MAXXMLLEN]; // plenty big for expected aclog responses hopefully if (retry < 2) { rig_debug(RIG_DEBUG_WARN, "%s: retry needed? retry=%d\n", __func__, retry); } int len = read_string(RIGPORT(rig), (unsigned char *) tmp_buf, sizeof(tmp_buf), delims, strlen(delims), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: string='%s'\n", __func__, tmp_buf); // if our first response we should see the HTTP header if (strlen(xml) == 0 && strstr(tmp_buf, "") == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Expected '', got '%s'\n", __func__, tmp_buf); continue; // we'll try again } if (len > 0) { retry = 3; } if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); continue; } if (strlen(xml) + strlen(tmp_buf) < xml_len - 1) { strncat(xml, tmp_buf, xml_len - 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: xml buffer overflow!!\nTrying to add len=%d\nTo len=%d\n", __func__, (int)strlen(tmp_buf), (int)strlen(xml)); RETURNFUNC(-RIG_EPROTO); } } while (retry-- > 0 && strstr(xml, terminator) == NULL); if (retry == 0) { rig_debug(RIG_DEBUG_WARN, "%s: retry timeout\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (strstr(xml, terminator)) { rig_debug(RIG_DEBUG_TRACE, "%s: got %s\n", __func__, terminator); retval = RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: did not get %s\n", __func__, terminator); retval = -(101 + RIG_EPROTO); } RETURNFUNC(retval); } /* * write_transaction * Assumes rig!=NULL, xml!=NULL, xml_len=total size of xml for response */ static int write_transaction(RIG *rig, char *xml, int xml_len) { int try = rig->caps->retry; int retval = -RIG_EPROTO; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // This shouldn't ever happen...but just in case // We need to avoid an empty write as rigctld replies with blank line if (xml_len == 0) { rig_debug(RIG_DEBUG_ERR, "%s: len==0??\n", __func__); RETURNFUNC(retval); } // appears we can lose sync if we don't clear things out // shouldn't be anything for us now anyways rig_flush(rp); while (try-- >= 0 && retval != RIG_OK) { retval = write_block(rp, (unsigned char *) xml, strlen(xml)); if (retval < 0) { RETURNFUNC(-RIG_EIO); } } RETURNFUNC(retval); } static int aclog_transaction(RIG *rig, char *cmd, char *value, int value_len) { char xml[MAXXMLLEN]; int retry = 3; ENTERFUNC; ELAPSED1; strcpy(xml, "UNKNOWN"); set_transaction_active(rig); if (value) { value[0] = 0; } do { int retval; if (retry != 3) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s, retry=%d\n", __func__, cmd, retry); } retval = write_transaction(rig, cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_transaction error=%d\n", __func__, retval); // if we get RIG_EIO the socket has probably disappeared // so bubble up the error so port can re re-opened if (retval == -RIG_EIO) { set_transaction_inactive(rig); RETURNFUNC(retval); } hl_usleep(50 * 1000); // 50ms sleep if error } if (value) { read_transaction(rig, xml, sizeof(xml)); // this might time out -- that's OK } // we get an unknown response if function does not exist if (strstr(xml, "UNKNOWN")) { set_transaction_inactive(rig); RETURNFUNC(RIG_ENAVAIL); } if (value) { strncpy(value, xml, value_len); } } while (((value && strlen(value) == 0)) && retry--); // we'll do retries if needed if (value && strlen(value) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: no value returned\n", __func__); set_transaction_inactive(rig); RETURNFUNC(RIG_EPROTO); } ELAPSED2; set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } /* * aclog_init * Assumes rig!=NULL */ static int aclog_init(RIG *rig) { struct aclog_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); STATE(rig)->priv = (struct aclog_priv_data *)calloc(1, sizeof( struct aclog_priv_data)); if (!STATE(rig)->priv) { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct aclog_priv_data)); memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); /* * set arbitrary initial status */ STATE(rig)->current_vfo = RIG_VFO_A; priv->split = 0; priv->ptt = 0; priv->curr_modeA = -1; priv->curr_modeB = -1; priv->curr_widthA = -1; priv->curr_widthB = -1; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); RETURNFUNC(RIG_OK); } /* * modeMapGet * Assumes mode!=NULL * Return the string for ACLog for the given hamlib mode */ static const char *modeMapGet(rmode_t modeHamlib) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_aclog == NULL) { continue; } rig_debug(RIG_DEBUG_TRACE, "%s: checking modeMap[%d]=%.0f to modeHamlib=%.0f, mode_aclog='%s'\n", __func__, i, (double)modeMap[i].mode_hamlib, (double)modeHamlib, modeMap[i].mode_aclog); if (modeMap[i].mode_hamlib == modeHamlib && strlen(modeMap[i].mode_aclog) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s matched mode=%.0f, returning '%s'\n", __func__, (double)modeHamlib, modeMap[i].mode_aclog); return (modeMap[i].mode_aclog); } } rig_debug(RIG_DEBUG_ERR, "%s: ACLog does not have mode: %s\n", __func__, rig_strrmode(modeHamlib)); return ("ERROR"); } /* * modeMapGetHamlib * Assumes mode!=NULL * Return the hamlib mode from the given ACLog string */ static rmode_t modeMapGetHamlib(const char *modeACLog) { int i; char modeCheck[64]; SNPRINTF(modeCheck, sizeof(modeCheck), "|%s|", modeACLog); for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { rig_debug(RIG_DEBUG_TRACE, "%s: find '%s' in '%s'\n", __func__, modeCheck, modeMap[i].mode_aclog); if (modeMap[i].mode_aclog && strcmp(modeMap[i].mode_aclog, modeCheck) == 0) { return (modeMap[i].mode_hamlib); } } rig_debug(RIG_DEBUG_TRACE, "%s: mode requested: %s, not in modeMap\n", __func__, modeACLog); return (RIG_MODE_NONE); } /* * aclog_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int aclog_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char value[MAXARGLEN]; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } char *cmd = "\r\n"; int retval; retval = aclog_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: READBMF failed retval=%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } char *p = strstr(value, ""); *freq = 0; if (p) { sscanf(p, "%lf", freq); } *freq *= 1e6; // convert from MHz to Hz if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\nvalue=%s\n", __func__, value); RETURNFUNC(-RIG_EPROTO); } else { rig_debug(RIG_DEBUG_TRACE, "%s: freq=%.0f\n", __func__, *freq); } if (vfo == RIG_VFO_A) { priv->curr_freqA = *freq; } else // future support in ACLOG maybe? { priv->curr_freqB = *freq; } RETURNFUNC(RIG_OK); } /* * aclog_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int aclog_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; char value[MAXCMDLEN]; char *cmdp; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } cmdp = "\r\n"; /* default to old way */ retval = aclog_transaction(rig, cmdp, value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, cmdp, rigerror(retval)); RETURNFUNC(retval); } char *p = strstr(value, ""); char modetmp[32]; modetmp[0] = 0; if (p) { *mode = RIG_MODE_NONE; int n = sscanf(p, "%31[^<]", modetmp); if (n == 1) { *mode = modeMapGetHamlib(modetmp); } else { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse from '%s'\n", __func__, value); *mode = RIG_MODE_USB; // just default to USB if we fail parsing } } rig_debug(RIG_DEBUG_TRACE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); if (vfo == RIG_VFO_A) { priv->curr_modeA = *mode; } else { priv->curr_modeB = *mode; } *width = 2400; // just default to 2400 for now RETURNFUNC(RIG_OK); } /* * aclog_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int aclog_open(RIG *rig) { int retval; char value[MAXARGLEN]; char *p; //;struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); retval = aclog_transaction(rig, "\r\n", value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: PROGRAM failed: %s", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_TRACE, "%s: returned value=%s\n", __func__, value); char version_pgm[64]; sscanf(value, "N3FJP's Amateur Contact Log%63[^<]", version_pgm); rig_debug(RIG_DEBUG_VERBOSE, "%s: ACLog version=%s\n", __func__, version_pgm); double version_api = 0; p = strstr(value, ""); if (p) { sscanf(strstr(value, ""), "%lf", &version_api); } rig_debug(RIG_DEBUG_VERBOSE, "%s ACLog API version %.1lf\n", __func__, version_api); retval = aclog_transaction(rig, "\r\n", value, sizeof(value)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: RIGENABLED failed,,,not fatal: %s\n", __func__, rigerror(retval)); } p = strstr(value, ""); char transceiver[64]; strcpy(transceiver, "Unknown"); if (p) { sscanf(p, "%63[^<]", transceiver); } rig_debug(RIG_DEBUG_VERBOSE, "Transceiver=%s\n", transceiver); freq_t freq; retval = aclog_get_freq(rig, RIG_VFO_CURR, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: aclog_get_freq not working!!\n", __func__); RETURNFUNC(RIG_EPROTO); } STATE(rig)->current_vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: currvfo=%s value=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo), value); RETURNFUNC(retval); } /* * aclog_close * Assumes rig!=NULL */ static int aclog_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } /* * aclog_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int aclog_cleanup(RIG *rig) { struct aclog_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (!rig) { RETURNFUNC2(-RIG_EINVAL); } priv = (struct aclog_priv_data *)STATE(rig)->priv; free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; // we really don't need to free this up as it's only done once // was causing problem when cleanup was followed by rig_open // model_aclog was not getting refilled // if we can figure out that one we can re-enable this #if 0 int i; for (i = 0; modeMap[i].mode_hamlib != 0; ++i) { if (modeMap[i].mode_aclog) { free(modeMap[i].mode_aclog); modeMap[i].mode_aclog = NULL; modeMap[i].mode_hamlib = 0; } } #endif RETURNFUNC2(RIG_OK); } /* * aclog_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int aclog_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char cmd[MAXARGLEN]; char value[1024]; //struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } #if 0 if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } #endif SNPRINTF(cmd, sizeof(cmd), "%lfTRUE\r\n", freq / 1e6); retval = aclog_transaction(rig, cmd, value, sizeof(value)); if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } /* * aclog_set_mode * Assumes rig!=NULL */ static int aclog_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char cmd[MAXCMDLEN]; char *p; char *pttmode; char *ttmode = NULL; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); // if ptt is on do not set mode if (priv->ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: returning because priv->ptt=%d\n", __func__, (int)priv->ptt); RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (priv->ptt) { rig_debug(RIG_DEBUG_VERBOSE, "%s set_mode call not made as PTT=1\n", __func__); RETURNFUNC(RIG_OK); // just return OK and ignore this } // Switch to VFOB if appropriate since we can't set mode directly // MDB rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo = %s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); // Set the mode if (strstr(modeMapGet(mode), "ERROR") == NULL) { ttmode = strdup(modeMapGet(mode)); } else { rig_debug(RIG_DEBUG_ERR, "%s: modeMapGet failed on mode=%d\n", __func__, (int)mode); RETURNFUNC(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: got ttmode = %s\n", __func__, ttmode == NULL ? "NULL" : ttmode); if (ttmode == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: strdup failed\n", __func__); RETURNFUNC(-RIG_EINTERNAL); } pttmode = ttmode; if (ttmode[0] == '|') { pttmode = &ttmode[1]; } // remove first pipe symbol p = strchr(pttmode, '|'); if (p) { *p = 0; } // remove any other pipe SNPRINTF(cmd, sizeof(cmd), "%s\r\n", pttmode); free(ttmode); retval = aclog_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (vfo == RIG_VFO_A) { priv->curr_modeA = mode; priv->curr_widthA = width; } else { priv->curr_modeB = mode; priv->curr_widthB = width; } rig_debug(RIG_DEBUG_TRACE, "%s: Return modeA=%s, widthA=%d\n,modeB=%s, widthB=%d\n", __func__, rig_strrmode(priv->curr_modeA), (int)priv->curr_widthA, rig_strrmode(priv->curr_modeB), (int)priv->curr_widthB); RETURNFUNC(RIG_OK); } /* * aclog_get_vfo * assumes rig!=NULL, vfo != NULL */ static int aclog_get_vfo(RIG *rig, vfo_t *vfo) { ENTERFUNC; *vfo = RIG_VFO_A; RETURNFUNC(RIG_OK); } /* * aclog_get_info * assumes rig!=NULL */ static const char *aclog_get_info(RIG *rig) { const struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE( rig)->priv; return (priv->info); } static int aclog_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE( rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed power = %f\n", __func__, power); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); power *= priv->powermeter_scale; *mwpower = (power * 100000); RETURNFUNC(RIG_OK); } static int aclog_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); *power = ((float)mwpower / 100000); RETURNFUNC(RIG_OK); } /* * aclog_set_ptt * Assumes rig!=NULL */ static int aclog_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd[MAXCMDLEN]; struct aclog_priv_data *priv = (struct aclog_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } snprintf(cmd, sizeof(cmd), ptt == RIG_PTT_ON ? "\r\n" : "\r\n"); retval = aclog_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->ptt = ptt; RETURNFUNC(RIG_OK); } struct rig_caps aclog_caps = { RIG_MODEL(RIG_MODEL_ACLOG), .model_name = "ACLog", .mfg_name = "N3FJP", .version = "20230120.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, //.targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 2, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = ACLOG_MODES, .low_power = -1, .high_power = -1, ACLOG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = ACLOG_MODES, .low_power = -1, .high_power = -1, ACLOG_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {ACLOG_MODES, 1}, {ACLOG_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .rig_init = aclog_init, .rig_open = aclog_open, .rig_close = aclog_close, .rig_cleanup = aclog_cleanup, .set_freq = aclog_set_freq, .get_freq = aclog_get_freq, .get_vfo = aclog_get_vfo, .set_mode = aclog_set_mode, .get_mode = aclog_get_mode, .get_info = aclog_get_info, .set_ptt = aclog_set_ptt, //.get_ptt = aclog_get_ptt, .power2mW = aclog_power2mW, .mW2power = aclog_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/dummy/flrig.h0000644000175000017500000000201214752216205013252 00000000000000/* * Hamlib FLRig backend - main header * Copyright (c) 2017 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FLRIG_H #define _FLRIG_H 1 #include "hamlib/rig.h" #define EOM "\r" #define TRUE 1 #define FALSE 0 extern struct rig_caps flrig_caps; #endif /* _FLRIG_H */ hamlib-4.6.2/rigs/dummy/netrotctl.c0000644000175000017500000002225214752216205014170 00000000000000/* * Hamlib Netrotctl backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include "hamlib/rotator.h" #include "iofunc.h" #define CMD_MAX 32 #define BUF_MAX 64 /* * Helper function with protocol return code parsing */ static int netrotctl_transaction(ROT *rot, char *cmd, int len, char *buf) { int ret; hamlib_port_t *rotp = ROTPORT(rot); /* flush anything in the read buffer before command is sent */ rig_flush(rotp); ret = write_block(rotp, (unsigned char *) cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(rotp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret < 0) { return ret; } if (!memcmp(buf, NETROTCTL_RET, strlen(NETROTCTL_RET))) { return atoi(buf + strlen(NETROTCTL_RET)); } return ret; } static int netrotctl_open(ROT *rot) { int ret; struct rot_state *rs = ROTSTATE(rot); hamlib_port_t *rotp = ROTPORT(rot); int prot_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "\\dump_state\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } prot_ver = atoi(buf); #define ROTCTLD_PROT_VER 1 ret = read_string(rotp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (prot_ver == 0) { return (RIG_OK); } // Prot 1 is tag=value format and should cover any needed additions do { char setting[32], value[1024]; ret = read_string(rotp, (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } // ignore the rot_model if (strncmp(buf, "done", 4) == 0) { return (RIG_OK); } if (sscanf(buf, "%31[^=]=%1023[^\t\n]", setting, value) == 2) { if (strcmp(setting, "min_az") == 0) { rs->min_az = rot->caps->min_az = atof(value); } else if (strcmp(setting, "max_az") == 0) { rs->max_az = rot->caps->max_az = atof(value); } else if (strcmp(setting, "min_el") == 0) { rs->min_el = rot->caps->min_el = atof(value); } else if (strcmp(setting, "max_el") == 0) { rs->max_el = rot->caps->max_el = atof(value); } else if (strcmp(setting, "south_zero") == 0) { rs->south_zero = atoi(value); } else if (strcmp(setting, "rot_type") == 0) { if (strcmp(value, "AzEl") == 0) { rot->caps->rot_type = ROT_TYPE_AZEL; } else if (strcmp(value, "Az") == 0) { rot->caps->rot_type = ROT_TYPE_AZIMUTH; } else if (strcmp(value, "El") == 0) { rot->caps->rot_type = ROT_TYPE_ELEVATION; } } else { // not an error -- just a warning for backward compatibility rig_debug(RIG_DEBUG_ERR, "%s: unknown setting='%s'\n", __func__, buf); } } } while (1); return RIG_OK; } static int netrotctl_close(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* clean signoff, no read back */ write_block(ROTPORT(rot), (unsigned char *) "q\n", 2); return RIG_OK; } static int netrotctl_set_position(ROT *rot, azimuth_t az, elevation_t el) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %f %f\n", __func__, az, el); SNPRINTF(cmd, sizeof(cmd), "P %f %f\n", az, el); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_get_position(ROT *rot, azimuth_t *az, elevation_t *el) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "p\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *az = atof(buf); ret = read_string(ROTPORT(rot), (unsigned char *) buf, BUF_MAX, "\n", sizeof("\n"), 0, 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *el = atof(buf); return RIG_OK; } static int netrotctl_stop(ROT *rot) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "S\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_park(ROT *rot) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "K\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_reset(ROT *rot, rot_reset_t reset) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "R %d\n", reset); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrotctl_move(ROT *rot, int direction, int speed) { int ret; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "M %d %d\n", direction, speed); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static const char *netrotctl_get_info(ROT *rot) { int ret; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "_\n"); ret = netrotctl_transaction(rot, cmd, strlen(cmd), buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } /* * NET rotctl capabilities. */ struct rot_caps netrotctl_caps = { ROT_MODEL(ROT_MODEL_NETROTCTL), .model_name = "NET rotctl", .mfg_name = "Hamlib", .version = "20221110.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_NETWORK, .timeout = 2000, .retry = 3, .min_az = -180., .max_az = 180., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ /* .rot_init = netrotctl_init, */ /* .rot_cleanup = netrotctl_cleanup, */ .rot_open = netrotctl_open, .rot_close = netrotctl_close, .set_position = netrotctl_set_position, .get_position = netrotctl_get_position, .park = netrotctl_park, .stop = netrotctl_stop, .reset = netrotctl_reset, .move = netrotctl_move, .get_info = netrotctl_get_info, }; /* * S.A.T. rotator mimics net rotor but only minimal capabilities. * Fails to work with net rotor since it fails dump_state. */ static int satrotcrl_rot_init(ROT *rot) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } struct rot_caps satrotctl_caps = { ROT_MODEL(ROT_MODEL_SATROTCTL), .model_name = "S.A.T. Satellite ctl", .mfg_name = "csntechnologies.net", .version = "20240609.0", .copyright = "LGPL", .status = RIG_STATUS_UNTESTED, .rot_type = ROT_TYPE_AZEL, .port_type = RIG_PORT_NETWORK, .timeout = 400, .min_az = -180., .max_az = 450., .min_el = 0., .max_el = 90., .priv = NULL, /* priv */ .rot_init = satrotcrl_rot_init, .set_position = netrotctl_set_position, .get_position = netrotctl_get_position, }; hamlib-4.6.2/rigs/dummy/dummy_common.c0000644000175000017500000000351514752216205014656 00000000000000/* * Hamlib Dummy backend - shared routines * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (c) 2010 by Nate Bargmann * Copyright (c) 2020 by Mikael Nousiainen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include #include "hamlib/rig.h" struct ext_list *alloc_init_ext(const struct confparams *cfp) { struct ext_list *elp; int i, nb_ext; if (cfp == NULL) { return NULL; } for (nb_ext = 0; !RIG_IS_EXT_END(cfp[nb_ext]); nb_ext++) ; elp = calloc((nb_ext + 1), sizeof(struct ext_list)); if (!elp) { return NULL; } for (i = 0; !RIG_IS_EXT_END(cfp[i]); i++) { elp[i].token = cfp[i].token; /* value reset already by calloc */ } /* last token in array is set to 0 by calloc */ return elp; } struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token) { int i; if (elp == NULL) { return NULL; } for (i = 0; elp[i].token != 0; i++) { if (elp[i].token == token) { return &elp[i]; } } return NULL; } hamlib-4.6.2/rigs/dummy/trxmanager.c0000644000175000017500000007375414752216205014337 00000000000000/* i Hamlib TRXManager backend - main file * Copyright (c) 2018 by Michael Black W9MDB * Derived from flrig.c * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include "trxmanager.h" #define DEBUG_TRACE DEBUG_VERBOSE #define MAXCMDLEN 64 #define DEFAULTPATH "127.0.0.1:1003" #define TRXMANAGER_VFOS (RIG_VFO_A|RIG_VFO_B) #define TRXMANAGER_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_CWR |\ RIG_MODE_RTTY | RIG_MODE_RTTYR |\ RIG_MODE_PKTLSB | RIG_MODE_PKTUSB |\ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) #define streq(s1,s2) (strcmp(s1,s2)==0) #define FLRIG_MODE_LSB '1' #define FLRIG_MODE_USB '2' #define FLRIG_MODE_CW '3' #define FLRIG_MODE_FM '4' #define FLRIG_MODE_AM '5' #define FLRIG_MODE_RTTY '6' #define FLRIG_MODE_CWR '7' #define FLRIG_MODE_RTTYR '9' #define FLRIG_MODE_PKTLSB 'C' #define FLRIG_MODE_PKTUSB 'D' #define FLRIG_MODE_PKTFM 'E' #define FLRIG_MODE_PKTAM 'F' // Hamlib doesn't support D2/D3 modes in hamlib yet // So we define them here but they aren't implemented #define FLRIG_MODE_PKTLSB2 'G' #define FLRIG_MODE_PKTUSB2 'H' #define FLRIG_MODE_PKTFM2 'I' #define FLRIG_MODE_PKTAM2 'J' #define FLRIG_MODE_PKTLSB3 'K' #define FLRIG_MODE_PKTUSB3 'L' #define FLRIG_MODE_PKTFM3 'M' #define FLRIG_MODE_PKTAM3 'N' static int trxmanager_init(RIG *rig); static int trxmanager_open(RIG *rig); static int trxmanager_close(RIG *rig); static int trxmanager_cleanup(RIG *rig); static int trxmanager_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int trxmanager_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int trxmanager_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int trxmanager_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int trxmanager_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int trxmanager_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int trxmanager_get_vfo(RIG *rig, vfo_t *vfo); static int trxmanager_set_vfo(RIG *rig, vfo_t vfo); static int trxmanager_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int trxmanager_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int trxmanager_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int trxmanager_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int trxmanager_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int trxmanager_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int trxmanager_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int trxmanager_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static const char *trxmanager_get_info(RIG *rig); struct trxmanager_priv_data { vfo_t vfo_curr; char info[100]; split_t split; }; struct rig_caps trxmanager_caps = { RIG_MODEL(RIG_MODEL_TRXMANAGER_RIG), .model_name = "TRXManager 5.7.630+", .mfg_name = "TRXManager", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 10000, // long timeout to allow for antenna tuning and such .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rx_range_list1 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TRXMANAGER_MODES, .low_power = -1, .high_power = -1, TRXMANAGER_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = {{ .startf = kHz(1), .endf = GHz(10), .modes = TRXMANAGER_MODES, .low_power = -1, .high_power = -1, TRXMANAGER_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {TRXMANAGER_MODES, 1}, {TRXMANAGER_MODES, RIG_TS_ANY}, RIG_TS_END, }, .priv = NULL, /* priv */ .rig_init = trxmanager_init, .rig_open = trxmanager_open, .rig_close = trxmanager_close, .rig_cleanup = trxmanager_cleanup, .set_freq = trxmanager_set_freq, .get_freq = trxmanager_get_freq, .set_mode = trxmanager_set_mode, .get_mode = trxmanager_get_mode, .set_vfo = trxmanager_set_vfo, .get_vfo = trxmanager_get_vfo, .get_info = trxmanager_get_info, .set_ptt = trxmanager_set_ptt, .get_ptt = trxmanager_get_ptt, .set_split_mode = trxmanager_set_split_mode, .set_split_freq = trxmanager_set_split_freq, .get_split_freq = trxmanager_get_split_freq, .set_split_vfo = trxmanager_set_split_vfo, .get_split_vfo = trxmanager_get_split_vfo, .set_split_freq_mode = trxmanager_set_split_freq_mode, .get_split_freq_mode = trxmanager_get_split_freq_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * check_vfo * No assumptions */ static int check_vfo(vfo_t vfo) { switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_TX: case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return FALSE; } return TRUE; } #if 0 // looks like we don't need this but it's here just in case /* * vfo_curr * Assumes rig!=NULL */ static int vfo_curr(RIG *rig, vfo_t vfo) { int retval = 0; vfo_t vfocurr; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; // get the current VFO from trxmanager in case user changed it if ((retval = trxmanager_get_vfo(rig, &vfocurr)) != RIG_OK) { return retval; } priv->vfo_curr = vfocurr; retval = (vfo == vfocurr); return retval; } #endif /* * read_transaction * Assumes rig!=NULL, response!=NULL, response_len>=MAXCMDLEN */ static int read_transaction(RIG *rig, char *response, int response_len) { const char *delims = "\n"; int len; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); len = read_string(RIGPORT(rig), (unsigned char *) response, response_len, delims, strlen(delims), 0, 1); if (len <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_string error=%d\n", __func__, len); return -RIG_EPROTO; } return RIG_OK; } /* * trxmanager_init * Assumes rig!=NULL */ static int trxmanager_init(RIG *rig) { struct trxmanager_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, BACKEND_VER); STATE(rig)->priv = (struct trxmanager_priv_data *)calloc(1, sizeof(struct trxmanager_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct trxmanager_priv_data)); /* * set arbitrary initial status */ priv->vfo_curr = RIG_VFO_A; priv->split = 0; if (!rig->caps) { return -RIG_EINVAL; } strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); return RIG_OK; } /* * trxmanager_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int trxmanager_open(RIG *rig) { int retval; char *cmd; char *saveptr; char response[MAXCMDLEN] = ""; hamlib_port_t *rp = RIGPORT(rig); struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, BACKEND_VER); rp->timeout = 10000; // long timeout for antenna switching/tuning retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) == 0) { rig_debug(RIG_DEBUG_ERR, "%s response len==0\n", __func__); return -RIG_EPROTO; } // Should have rig info now strtok_r(response, ";\r\n", &saveptr); strncpy(priv->info, &response[2], sizeof(priv->info)); rig_debug(RIG_DEBUG_VERBOSE, "%s connected to %s\n", __func__, priv->info); // Turn off active messages cmd = "AI0;"; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strncmp("AI0;", response, 4) != 0) { rig_debug(RIG_DEBUG_ERR, "%s AI invalid response=%s\n", __func__, response); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s AI response=%s\n", __func__, response); cmd = "FN;"; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s FN; write failed\n", __func__); } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } rig_debug(RIG_DEBUG_VERBOSE, "%s FN response=%s\n", __func__, response); priv->vfo_curr = RIG_VFO_A; return retval; } /* * trxmanager_close * Assumes rig!=NULL */ static int trxmanager_close(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); return RIG_OK; } /* * trxmanager_cleanup * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int trxmanager_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * trxmanager_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ static int trxmanager_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; int n; char vfoab; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { if ((retval = trxmanager_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } priv->vfo_curr = vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } vfoab = vfo == RIG_VFO_A ? 'R' : 'T'; SNPRINTF(cmd, sizeof(cmd), "X%c;", vfoab); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } *freq = 0; n = sscanf(&response[2], "%lg", freq); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: can't parse freq from %s", __func__, response); } if (*freq == 0) { rig_debug(RIG_DEBUG_ERR, "%s: freq==0??\n", __func__); return -RIG_EPROTO; } return retval; } /* * trxmanager_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int trxmanager_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char vfoab; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; const struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { if ((retval = trxmanager_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } else if (vfo == RIG_VFO_TX && priv->split) { vfo = RIG_VFO_B; // if split always TX on VFOB } vfoab = vfo == RIG_VFO_A ? 'A' : 'B'; SNPRINTF(cmd, sizeof(cmd), "F%c%011lu;", vfoab, (unsigned long)freq); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } return RIG_OK; } /* * trxmanager_set_ptt * Assumes rig!=NULL */ static int trxmanager_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "%s;", ptt == 1 ? "TX" : "RX"); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 5 || strstr(response, cmd) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * trxmanager_get_ptt * Assumes rig!=NULL ptt!=NULL */ static int trxmanager_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char cptt; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), "IF;"); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 40) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: IF response len=%d\n", __func__, (int)strlen(response)); cptt = response[28]; *ptt = cptt == '0' ? 0 : 1; return RIG_OK; } /* * trxmanager_set_split_mode * Assumes rig!=NULL */ static int trxmanager_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); retval = trxmanager_set_mode(rig, RIG_VFO_B, mode, width); return retval; } /* * trxmanager_set_mode * Assumes rig!=NULL */ static int trxmanager_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char ttmode; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } ttmode = FLRIG_MODE_USB; switch (mode) { case RIG_MODE_LSB: ttmode = RIG_MODE_LSB; break; case RIG_MODE_USB: ttmode = RIG_MODE_USB; break; case RIG_MODE_CW: ttmode = FLRIG_MODE_CW; break; case RIG_MODE_FM: ttmode = FLRIG_MODE_FM; break; case RIG_MODE_AM: ttmode = FLRIG_MODE_AM; break; case RIG_MODE_RTTY: ttmode = FLRIG_MODE_RTTY; break; case RIG_MODE_CWR: ttmode = FLRIG_MODE_CWR; break; case RIG_MODE_RTTYR: ttmode = FLRIG_MODE_RTTYR; break; case RIG_MODE_PKTLSB: ttmode = FLRIG_MODE_PKTLSB; break; case RIG_MODE_PKTUSB: ttmode = FLRIG_MODE_PKTUSB; break; case RIG_MODE_PKTFM: ttmode = FLRIG_MODE_PKTFM; break; case RIG_MODE_PKTAM: ttmode = FLRIG_MODE_PKTAM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "MD%c;", ttmode); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } // Get the response retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } rig_debug(RIG_DEBUG_VERBOSE, "%s: response=%s\n", __func__, response); // Can't set BW on TRXManger as of 20180427 -- can only read it return RIG_OK; } /* * trxmanager_get_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL */ static int trxmanager_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int n; long iwidth = 0; char tmode; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; hamlib_port_t *rp = RIGPORT(rig); struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { if ((retval = trxmanager_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } priv->vfo_curr = vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), "MD;"); retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } n = sscanf(response, "MD%c;", &tmode); if (n != 1 || strlen(response) != 6) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } switch (tmode) { case FLRIG_MODE_LSB: *mode = RIG_MODE_LSB; break; case FLRIG_MODE_USB: *mode = RIG_MODE_USB; break; case FLRIG_MODE_CW: *mode = RIG_MODE_CW; break; case FLRIG_MODE_FM: *mode = RIG_MODE_FM; break; case FLRIG_MODE_AM: *mode = RIG_MODE_AM; break; case FLRIG_MODE_RTTY: *mode = RIG_MODE_RTTY; break; case FLRIG_MODE_CWR: *mode = RIG_MODE_CWR; break; case FLRIG_MODE_RTTYR: *mode = RIG_MODE_RTTYR; break; case FLRIG_MODE_PKTLSB: *mode = RIG_MODE_PKTLSB; break; case FLRIG_MODE_PKTUSB: *mode = RIG_MODE_PKTUSB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode='%c'\n", __func__, tmode); return -RIG_ENIMPL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: mode='%s'\n", __func__, rig_strrmode(*mode)); // now get the bandwidth SNPRINTF(cmd, sizeof(cmd), "BW;"); retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strncmp(response, "BW", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } n = sscanf(response, "BW%ld;", &iwidth); if (n != 1) { char *saveptr; rig_debug(RIG_DEBUG_ERR, "%s bandwidth scan failed '%s'\n", __func__, strtok_r(response, "\r\n", &saveptr)); return -RIG_EPROTO; } *width = iwidth; printf("Bandwidth=%ld\n", *width); return RIG_OK; } static int trxmanager_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct rig_state *rs = STATE(rig); struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_VERBOSE, "%s: RIG_VFO_TX used\n", __func__); vfo = RIG_VFO_B; // always TX on VFOB } if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } SNPRINTF(cmd, sizeof(cmd), "FN%d;", vfo == RIG_VFO_A ? 0 : 1); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } priv->vfo_curr = vfo; rs->tx_vfo = RIG_VFO_B; // always VFOB retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } return RIG_OK; } static int trxmanager_get_vfo(RIG *rig, vfo_t *vfo) { // TRXManager does not swap vfos // So we maintain our own internal state during set_vfo // This keeps the hamlib interface consistent with other rigs struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; char vfoab; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); vfoab = priv->vfo_curr; switch (vfoab) { case RIG_VFO_A: *vfo = RIG_VFO_A; break; case RIG_VFO_B: *vfo = RIG_VFO_B; break; default: priv->vfo_curr = *vfo; *vfo = RIG_VFO_CURR; return -RIG_EINVAL; } if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } priv->vfo_curr = *vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } /* * trxmanager_set_split_freq */ static int trxmanager_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __func__, rig_strvfo(vfo), tx_freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "XT%011lu;", (unsigned long) tx_freq); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } return RIG_OK; } /* * trxmanager_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ static int trxmanager_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = trxmanager_get_freq(rig, RIG_VFO_B, tx_freq); return retval; } /* * trxmanager_set_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int trxmanager_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; split_t tsplit; vfo_t ttx_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __func__, rig_strvfo(tx_vfo)); #if 0 /* for flrig we have to be on VFOA when we set split for VFOB Tx */ /* we can keep the rig on VFOA since we can set freq by VFO now */ if (!vfo_curr(rig, RIG_VFO_A)) { trxmanager_set_vfo(rig, RIG_VFO_A); } #endif retval = trxmanager_get_split_vfo(rig, vfo, &tsplit, &ttx_vfo); if (retval < 0) { return retval; } if (tsplit == split) { return RIG_OK; } // don't need to change it SNPRINTF(cmd, sizeof(cmd), "SP%c;", split ? '1' : '0'); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 6 || strstr(response, cmd) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s invalid response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * trxmanager_get_split_vfo * assumes rig!=NULL, tx_freq!=NULL */ static int trxmanager_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval; int tsplit = 0; int n; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); SNPRINTF(cmd, sizeof(cmd), "SP;"); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); // get response but don't care if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } *tx_vfo = RIG_VFO_B; n = sscanf(response, "SP%d", &tsplit); if (n == 0 || n == EOF) { rig_debug(RIG_DEBUG_ERR, "%s error getting split from '%s'\n", __func__, response); } *split = tsplit; priv->split = *split; return RIG_OK; } /* * trxmanager_set_split_freq_mode * assumes rig!=NULL */ static int trxmanager_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; char cmd[MAXCMDLEN]; char response[MAXCMDLEN] = ""; struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX && vfo != RIG_VFO_B) { return -RIG_ENTARGET; } // assume split is on B // SNPRINTF(cmd, sizeof(cmd), "XT%011lu;", (unsigned long)freq); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval < 0) { return retval; } retval = read_transaction(rig, response, sizeof(response)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s read_transaction failed\n", __func__); } if (strlen(response) != 16 || strstr(response, cmd) == NULL) { FILE *fp; rig_debug(RIG_DEBUG_ERR, "%s invalid response='%s'\n", __func__, response); fp = fopen("debug.txt", "w+"); fprintf(fp, "XT response=%s\n", response); fclose(fp); return -RIG_EPROTO; } priv->split = 1; // XT command also puts rig in split return retval; } /* * trxmanager_get_split_freq_mode * assumes rig!=NULL, freq!=NULL, mode!=NULL, width!=NULL */ static int trxmanager_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; if (vfo != RIG_VFO_CURR && vfo != RIG_VFO_TX) { return -RIG_ENTARGET; } retval = trxmanager_get_freq(rig, RIG_VFO_B, freq); if (RIG_OK == retval) { retval = trxmanager_get_mode(rig, vfo, mode, width); } return retval; } static const char *trxmanager_get_info(RIG *rig) { const struct trxmanager_priv_data *priv = (struct trxmanager_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return priv->info; } hamlib-4.6.2/rigs/mds/0000755000175000017500000000000014752216244011516 500000000000000hamlib-4.6.2/rigs/mds/mds.c0000644000175000017500000003142514752216205012367 00000000000000/* * Hamlib MDS 4710/9710 backend - main file * Copyright (c) 2022 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "serial.h" #include "misc.h" #include "register.h" #include "mds.h" #define MAXCMDLEN 32 extern struct rig_caps mds_4710_caps; extern struct rig_caps mds_9710_caps; DECLARE_INITRIG_BACKEND(mds) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&mds_4710_caps); rig_register(&mds_9710_caps); rig_debug(RIG_DEBUG_VERBOSE, "%s: _init back from rig_register\n", __func__); return RIG_OK; } int mds_transaction(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; int retval; hamlib_port_t *rp = RIGPORT(rig); struct mds_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, cmd); SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s\n", cmd); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { return retval; } if (expected == 0) { return RIG_OK; } else { char cmdtrm_str[2]; /* Default Command/Reply termination char */ cmdtrm_str[0] = 0x0d; cmdtrm_str[1] = 0x00; retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), cmdtrm_str, strlen(cmdtrm_str), 0, expected); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_block\n", __func__, __LINE__); return retval; } } if (result != NULL) { rig_debug(RIG_DEBUG_VERBOSE, "%s: setting result\n", __func__); *result = &(priv->ret_data[0]); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: no result requested\n", __func__); } return RIG_OK; } int mds_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); // cppcheck claims leak here but it's freed in cleanup STATE(rig)->priv = (struct mds_priv_data *)calloc(1, sizeof(struct mds_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } /* * mds_cleanup * */ int mds_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * mds_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ int mds_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *freq = 0; retval = mds_transaction(rig, "TX", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } retval = sscanf(response, "%lg", freq); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse response\n", __func__); return -RIG_EPROTO; } return RIG_OK; } // TC command does not work on 4050 -- not implemented as of 2022-01-12 /* * mds_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int mds_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; freq_t tfreq; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); retval = rig_get_freq(rig, vfo, &tfreq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq failed: %s\n", __func__, strerror(retval)); return retval; } if (tfreq == freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq not changing\n", __func__); return RIG_OK; } // If we are not explicitly asking for VFO_B then we'll set the receive side also if (vfo != RIG_VFO_B) { char cmd_buf[MAXCMDLEN]; char *response = NULL; SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TX%.4f", freq / 1e6); retval = mds_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: TX failed\n", __func__); return retval; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "RX%.4f", freq / 1e6); retval = mds_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: RX failed\n", __func__); return retval; } } return RIG_OK; } /* * mds_set_ptt * Assumes rig!=NULL */ int mds_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_buf[MAXCMDLEN]; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s", ptt ? "KEY" : "DKEY"); retval = mds_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd:IP result=%s\n", __func__, response); return RIG_OK; } /* * mds_get_ptt * Assumes rig!=NULL */ int mds_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char *response = NULL; char c; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = mds_transaction(rig, "IP", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error response?='%s'\n", __func__, response); return retval; } c = response[0]; if (c == '1' || c == '0') { *ptt = c - '0'; } else { rig_debug(RIG_DEBUG_ERR, "%s: error response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * mds_set_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ #if 0 int mds_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char cmd_buf[32], ttmode; int retval; rmode_t tmode; pbwidth_t twidth; //struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); retval = rig_get_mode(rig, vfo, &tmode, &twidth); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode failed %s\n", __func__, strerror(retval)); } if (tmode == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: already mode %s so not changing\n", __func__, rig_strrmode(mode)); return RIG_OK; } switch (mode) { case RIG_MODE_USB: ttmode = 'U'; break; case RIG_MODE_LSB: ttmode = 'L'; break; case RIG_MODE_CW: ttmode = 'C'; break; case RIG_MODE_AM: ttmode = 'A'; break; case RIG_MODE_RTTY: ttmode = 'F'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TB%c\n", ttmode); retval = mds_transaction(rig, cmd_buf, 0, NULL); if (retval < 0) { return retval; } return RIG_OK; } #endif /* * mds_get_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ #if 0 int mds_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *result = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = mds_transaction(rig, "IB", 0, &result); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad response=%s\n", __func__, result); return retval; } //dump_hex((unsigned char *)result,strlen(result)); switch (result[1]) { case 'L': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'A': *mode = RIG_MODE_AM; break; case 'F': *mode = RIG_MODE_RTTY; break; case 'C': *mode = RIG_MODE_CW; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode='%c%c'\n", __func__, result[0], result[1]); return -RIG_EPROTO; } *width = 3000; // we'll default this to 3000 for now rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } #endif #if 0 int mds_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = RIG_VFO_A; if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } #endif /* * mds_get_level */ #if 0 int mds_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval = 0; char *response = NULL; switch (level) { int strength; int n; case RIG_LEVEL_STRENGTH: retval = mds_transaction(rig, "IAL", 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } n = sscanf(response, "%2d", &strength); if (n == 1) { val->i = strength; } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse STRENGTH from %s\n", __func__, response); return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s val=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level), response); return RIG_OK; } #endif /* * mds_get_info */ const char *mds_get_info(RIG *rig) { char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = mds_transaction(rig, "MODEL", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: MODEL command failed: %s\n", __func__, strerror(retval)); } else { rig_debug(RIG_DEBUG_VERBOSE, "Model: %s\n", response); } response = NULL; retval = mds_transaction(rig, "SER", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: SER command failed: %s\n", __func__, strerror(retval)); } else { rig_debug(RIG_DEBUG_VERBOSE, "Serial# %s\n", response); } response = NULL; retval = mds_transaction(rig, "SREV", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: SREV command failed: %s\n", __func__, strerror(retval)); } else { rig_debug(RIG_DEBUG_VERBOSE, "Firmware %s\n", response); } response = NULL; retval = mds_transaction(rig, "SHOW DC", 16, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SHOW DC failed result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "DC %s\n", response); } return response; } int mds_open(RIG *rig) { char *response = NULL; int retval; ENTERFUNC; mds_get_info(rig); retval = mds_transaction(rig, "MODEM NONE", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: MODEM cmd failed: %s\n", __func__, rigerror(retval)); } else { retval = mds_transaction(rig, "PTT 0", 0, &response); } RETURNFUNC(retval); } hamlib-4.6.2/rigs/mds/9710.c0000644000175000017500000000562514752216205012207 00000000000000#include "mds.h" struct rig_caps mds_9710_caps = { RIG_MODEL(RIG_MODEL_MDS9710), .model_name = "9710", .mfg_name = "MDS", .version = "20221116.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 110, .serial_rate_max = 38400, .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 = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = MDS_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, // .ctcss_list = common_ctcss_list, // .dcs_list = full_dcs_list, // 2050 does have channels...not implemented yet as no need yet // .chan_list = { // { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, // { 19, 19, RIG_MTYPE_CALL }, // { 20, NB_CHAN-1, RIG_MTYPE_EDGE }, // RIG_CHAN_END, // }, // .scan_ops = DUMMY_SCAN, // .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .rx_range_list1 = { { .startf = MHz(800), .endf = MHz(880), .modes = MDS_ALL_MODES, .low_power = 0, .high_power = 0, MDS_ALL_MODES, RIG_ANT_1, }, { .startf = MHz(880), .endf = MHz(960), .modes = MDS_ALL_MODES, .low_power = 0, .high_power = 0, MDS_ALL_MODES, RIG_ANT_1, }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = { {MHz(380), MHz(530), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE}, RIG_FRNG_END, }, // .tx_range_list2 = {RIG_FRNG_END,} .tuning_steps = { // Rem: no support for changing tuning step {MDS_ALL_MODES, 6250}, RIG_TS_END, }, .filters = { {MDS_ALL_MODES, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, .rig_init = mds_init, .rig_open = mds_open, .rig_cleanup = mds_cleanup, // .set_conf = dummy_set_conf, // .get_conf = dummy_get_conf, .set_freq = mds_set_freq, .get_freq = mds_get_freq, // .set_mode = mds_set_mode, // .get_mode = mds_get_mode, // .set_level = dummy_set_level, // .get_level = mds_get_level, .get_info = mds_get_info, .set_ptt = mds_set_ptt, .get_ptt = mds_get_ptt, // .get_dcd = dummy_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/mds/Makefile.am0000644000175000017500000000021014752216205013460 00000000000000MDSSRC = mds.c mds.h 4710.c 9710.c noinst_LTLIBRARIES = libhamlib-mds.la libhamlib_mds_la_SOURCES = $(MDSSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/mds/Makefile.in0000644000175000017500000005253114752216216013510 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/mds ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_mds_la_LIBADD = am__objects_1 = mds.lo 4710.lo 9710.lo am_libhamlib_mds_la_OBJECTS = $(am__objects_1) libhamlib_mds_la_OBJECTS = $(am_libhamlib_mds_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/4710.Plo ./$(DEPDIR)/9710.Plo \ ./$(DEPDIR)/mds.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_mds_la_SOURCES) DIST_SOURCES = $(libhamlib_mds_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MDSSRC = mds.c mds.h 4710.c 9710.c noinst_LTLIBRARIES = libhamlib-mds.la libhamlib_mds_la_SOURCES = $(MDSSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/mds/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/mds/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-mds.la: $(libhamlib_mds_la_OBJECTS) $(libhamlib_mds_la_DEPENDENCIES) $(EXTRA_libhamlib_mds_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_mds_la_OBJECTS) $(libhamlib_mds_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/4710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/9710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mds.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/4710.Plo -rm -f ./$(DEPDIR)/9710.Plo -rm -f ./$(DEPDIR)/mds.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/4710.Plo -rm -f ./$(DEPDIR)/9710.Plo -rm -f ./$(DEPDIR)/mds.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/mds/Android.mk0000644000175000017500000000036414752216205013347 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := mds.c LOCAL_MODULE := mds LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/mds/4710.c0000644000175000017500000000600514752216205012173 00000000000000#include "mds.h" struct rig_caps mds_4710_caps = { RIG_MODEL(RIG_MODEL_MDS4710), .model_name = "4710", .mfg_name = "MDS", .version = "20221114.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 110, .serial_rate_max = 38400, .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 = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = MDS_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, // .ctcss_list = common_ctcss_list, // .dcs_list = full_dcs_list, // 2050 does have channels...not implemented yet as no need yet // .chan_list = { // { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, // { 19, 19, RIG_MTYPE_CALL }, // { 20, NB_CHAN-1, RIG_MTYPE_EDGE }, // RIG_CHAN_END, // }, // .scan_ops = DUMMY_SCAN, // .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .rx_range_list1 = { { .startf = MHz(380), .endf = MHz(530), .modes = MDS_ALL_MODES, .low_power = 0, .high_power = 0, MDS_VFOS, RIG_ANT_1, "USA" }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = { {MHz(380), MHz(400), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, {MHz(400), MHz(450), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, {MHz(450), MHz(512), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, {MHz(406), MHz(530), MDS_ALL_MODES, W(.1), W(5), RIG_VFO_A, RIG_ANT_NONE, "USA"}, RIG_FRNG_END, }, // .tx_range_list2 = {RIG_FRNG_END,} .tuning_steps = { // Rem: no support for changing tuning step {MDS_ALL_MODES, 6250}, RIG_TS_END, }, .filters = { {MDS_ALL_MODES, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, .rig_init = mds_init, .rig_open = mds_open, .rig_cleanup = mds_cleanup, // .set_conf = dummy_set_conf, // .get_conf = dummy_get_conf, .set_freq = mds_set_freq, .get_freq = mds_get_freq, // .set_mode = mds_set_mode, // .get_mode = mds_get_mode, // .set_level = dummy_set_level, // .get_level = mds_get_level, .get_info = mds_get_info, .set_ptt = mds_set_ptt, .get_ptt = mds_get_ptt, // .get_dcd = dummy_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/mds/mds.h0000644000175000017500000000135614752216205012374 00000000000000#include #define MDS_DATA_LEN 256 #define MDS_RET_LEN 256 #define MDS_VFOS (RIG_VFO_A) #define MDS_ALL_MODES (RIG_MODE_USB) #define MDS_LEVELS (RIG_LEVEL_NONE) struct mds_priv_data { char cmd_str[MDS_DATA_LEN]; /* command string buffer */ char ret_data[MDS_RET_LEN]; /* returned data--max value, most are less */ }; extern struct rig_caps mds_4710_caps; extern struct rig_caps mds_9710_caps; int mds_init(RIG *rig); int mds_open(RIG *rig); int mds_cleanup(RIG *rig); int mds_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int mds_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int mds_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int mds_set_freq(RIG *rig, vfo_t vfo, freq_t freq); const char *mds_get_info(RIG *rig); hamlib-4.6.2/rigs/uniden/0000755000175000017500000000000014752216244012215 500000000000000hamlib-4.6.2/rigs/uniden/bc895.c0000644000175000017500000001027614752216205013136 00000000000000/* * Hamlib Uniden backend - BC895 description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC895_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC895_FUNC (RIG_FUNC_MUTE) #define BC895_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC895_PARM_ALL (RIG_PARM_NONE) #define BC895_VFO RIG_VFO_A #define BC895_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .ctcss_sql=1, \ .dcs_sql=1 /* The BC895 seems to max out at 32 while 12 seems to be about minimum. */ #define BC895_STR_CAL { 4, \ { \ { 0, -54 }, \ { 12, -20 }, /* TBC */ \ { 32, 4 }, /* TBC */ \ { 255, 60 }, \ } } /* * bc895 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc895_caps = { RIG_MODEL(RIG_MODEL_BC895), .model_name = "BC895xlt", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC895_FUNC, .has_set_func = BC895_FUNC, .has_get_level = BC895_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC895_LEVEL_ALL), .has_get_parm = BC895_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC895_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = uniden_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 0, .str_cal = BC895_STR_CAL, .chan_list = { { 1, 300, RIG_MTYPE_MEM, {BC895_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(29), MHz(956), BC895_MODES, -1, -1, BC895_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC895_MODES, kHz(5)}, {BC895_MODES, kHz(7.5)}, {BC895_MODES, kHz(10)}, {BC895_MODES, kHz(12.5)}, {BC895_MODES, kHz(25)}, {BC895_MODES, kHz(50)}, RIG_TS_END, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/uniden/Makefile.am0000644000175000017500000000036714752216205014174 00000000000000UNIDENSRC = bc895.c bc898.c bc245.c pro2052.c bc780.c bc250.c bcd396t.c \ bcd996t.c uniden.c uniden.h uniden_digital.c uniden_digital.h noinst_LTLIBRARIES = libhamlib-uniden.la libhamlib_uniden_la_SOURCES = $(UNIDENSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/uniden/bc898.c0000644000175000017500000001124114752216205013132 00000000000000/* * Hamlib Uniden backend - BC898 description * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC898_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC898_FUNC (RIG_FUNC_MUTE) #define BC898_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC898_PARM_ALL (RIG_PARM_NONE) #define BC898_VFO RIG_VFO_A #define BC898_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .ctcss_sql=1, \ .dcs_sql=1 /* The BC898 seems to max out at 32 while 12 seems to be about minimum. */ #define BC898_STR_CAL { 4, \ { \ { 0, -54 }, \ { 12, -20 }, /* TBC */ \ { 32, 4 }, /* TBC */ \ { 255, 60 }, \ } } static tone_t bc898_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0 }; /* * bc898 rig capabilities. * * TODO: check this with manual or web site. * http://www.uniden.com/products/productdetail.cfm?product=BC898T&filter=Mobile */ struct rig_caps bc898_caps = { RIG_MODEL(RIG_MODEL_BC898), .model_name = "BC898T", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC898_FUNC, .has_set_func = BC898_FUNC, .has_get_level = BC898_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC898_LEVEL_ALL), .has_get_parm = BC898_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC898_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = bc898_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 0, .str_cal = BC898_STR_CAL, .chan_list = { { 1, 500, RIG_MTYPE_MEM, {BC898_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(956), BC898_MODES, -1, -1, BC898_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* TODO: is it really continuous coverage ? what about cellular? */ {MHz(25), MHz(956), BC898_MODES, -1, -1, BC898_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC898_MODES, kHz(5)}, {BC898_MODES, kHz(6.25)}, {BC898_MODES, kHz(12.5)}, {BC898_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/uniden/Makefile.in0000644000175000017500000005554014752216216014212 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/uniden ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_uniden_la_LIBADD = am__objects_1 = bc895.lo bc898.lo bc245.lo pro2052.lo bc780.lo \ bc250.lo bcd396t.lo bcd996t.lo uniden.lo uniden_digital.lo am_libhamlib_uniden_la_OBJECTS = $(am__objects_1) libhamlib_uniden_la_OBJECTS = $(am_libhamlib_uniden_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/bc245.Plo ./$(DEPDIR)/bc250.Plo \ ./$(DEPDIR)/bc780.Plo ./$(DEPDIR)/bc895.Plo \ ./$(DEPDIR)/bc898.Plo ./$(DEPDIR)/bcd396t.Plo \ ./$(DEPDIR)/bcd996t.Plo ./$(DEPDIR)/pro2052.Plo \ ./$(DEPDIR)/uniden.Plo ./$(DEPDIR)/uniden_digital.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_uniden_la_SOURCES) DIST_SOURCES = $(libhamlib_uniden_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ UNIDENSRC = bc895.c bc898.c bc245.c pro2052.c bc780.c bc250.c bcd396t.c \ bcd996t.c uniden.c uniden.h uniden_digital.c uniden_digital.h noinst_LTLIBRARIES = libhamlib-uniden.la libhamlib_uniden_la_SOURCES = $(UNIDENSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/uniden/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/uniden/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-uniden.la: $(libhamlib_uniden_la_OBJECTS) $(libhamlib_uniden_la_DEPENDENCIES) $(EXTRA_libhamlib_uniden_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_uniden_la_OBJECTS) $(libhamlib_uniden_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc245.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc250.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc780.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc895.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bc898.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcd396t.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcd996t.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pro2052.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniden.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniden_digital.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/bc245.Plo -rm -f ./$(DEPDIR)/bc250.Plo -rm -f ./$(DEPDIR)/bc780.Plo -rm -f ./$(DEPDIR)/bc895.Plo -rm -f ./$(DEPDIR)/bc898.Plo -rm -f ./$(DEPDIR)/bcd396t.Plo -rm -f ./$(DEPDIR)/bcd996t.Plo -rm -f ./$(DEPDIR)/pro2052.Plo -rm -f ./$(DEPDIR)/uniden.Plo -rm -f ./$(DEPDIR)/uniden_digital.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/bc245.Plo -rm -f ./$(DEPDIR)/bc250.Plo -rm -f ./$(DEPDIR)/bc780.Plo -rm -f ./$(DEPDIR)/bc895.Plo -rm -f ./$(DEPDIR)/bc898.Plo -rm -f ./$(DEPDIR)/bcd396t.Plo -rm -f ./$(DEPDIR)/bcd996t.Plo -rm -f ./$(DEPDIR)/pro2052.Plo -rm -f ./$(DEPDIR)/uniden.Plo -rm -f ./$(DEPDIR)/uniden_digital.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/uniden/uniden_digital.h0000644000175000017500000000247014752216205015265 00000000000000/* * Hamlib Uniden backend - uniden_digital header * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _UNIDEN_DIGITAL_H #define _UNIDEN_DIGITAL_H 1 #include "hamlib/rig.h" #define BACKEND_DIGITAL_VER "20170808" int uniden_digital_transaction (RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize); const char* uniden_digital_get_info(RIG *rig); int uniden_digital_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int uniden_digital_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); #endif /* _UNIDEN_DIGITAL_H */ hamlib-4.6.2/rigs/uniden/Android.mk0000644000175000017500000000053114752216205014042 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := bc895.c bc898.c bc245.c pro2052.c bc780.c bc250.c \ bcd396t.c bcd996t.c \ uniden.c uniden_digital.c LOCAL_MODULE := uniden LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/uniden/bcd396t.c0000644000175000017500000000774014752216205013464 00000000000000/* * Hamlib Uniden backend - BCD396T description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" /*#include "uniden.h"*/ #include "uniden_digital.h" /* TODO: All these defines have to be filled in properly */ #define BCD396T_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BCD396T_FUNC (RIG_FUNC_MUTE) #define BCD396T_LEVEL_ALL (RIG_LEVEL_ATT) #define BCD396T_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define BCD396T_VFO (RIG_VFO_A|RIG_VFO_B) #define BCD396T_CHANNEL_CAPS \ .freq=1,\ .flags=1, /* L/O */ /* * bcd396t rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bcd396t_caps = { RIG_MODEL(RIG_MODEL_BCD396T), .model_name = "BCD-396T", .mfg_name = "Uniden", .version = BACKEND_DIGITAL_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 2000, .retry = 3, .has_get_func = BCD396T_FUNC, .has_set_func = BCD396T_FUNC, .has_get_level = BCD396T_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BCD396T_LEVEL_ALL), .has_get_parm = BCD396T_PARM_ALL, .has_set_parm = RIG_PARM_SET(BCD396T_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list? */ .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 5999, RIG_MTYPE_MEM, {BCD396T_CHANNEL_CAPS} }, /* Really 6000 channels? */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(764), MHz(775.9875), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(794), MHz(823.9875), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(849.0125), MHz(868.9875), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(894.0125), MHz(956), BCD396T_MODES, -1, -1, BCD396T_VFO}, {MHz(1240), MHz(1300), BCD396T_MODES, -1, -1, BCD396T_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BCD396T_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .get_info = uniden_digital_get_info, .set_freq = uniden_digital_set_freq, .get_freq = uniden_digital_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/uniden/uniden.h0000644000175000017500000000530714752216205013572 00000000000000/* * Hamlib Uniden backend - main header * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _UNIDEN_H #define _UNIDEN_H 1 #include #include #define BACKEND_VER "20200621" /* TODO: Trunk, Delay, Recording * * .channel_desc=1 is only on BC780 BC250 BC785 * .ctcss_sql=1, * .dcs_sql=1, */ #define UNIDEN_CHANNEL_CAPS \ .freq=1,\ .levels=RIG_LEVEL_ATT,\ .flags=1, /* L/O */ /* Calibration, actually from the BC785D */ #define UNIDEN_STR_CAL { 8, \ { \ { 0, -54 }, \ { 134, -20 }, /* < 0.50uV */ \ { 157, -12 }, \ { 173, -9 }, \ { 189, -5 }, \ { 204, -1 }, \ { 221, 4 }, /* < 7.50uV */ \ { 255, 60 }, \ } } extern tone_t uniden_ctcss_list[]; extern tone_t uniden_dcs_list[]; int uniden_transaction (RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize); int uniden_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int uniden_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int uniden_get_freq_2(RIG *rig, vfo_t vfo, freq_t *freq); int uniden_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int uniden_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int uniden_set_mem(RIG *rig, vfo_t vfo, int ch); int uniden_get_mem(RIG *rig, vfo_t vfo, int *ch); int uniden_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int uniden_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int uniden_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int uniden_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int uniden_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); const char* uniden_get_info(RIG *rig); extern struct rig_caps bc895_caps; extern struct rig_caps bc898_caps; extern struct rig_caps bc245_caps; extern struct rig_caps bc780_caps; extern struct rig_caps bc250_caps; extern struct rig_caps pro2052_caps; extern struct rig_caps bcd396t_caps; extern struct rig_caps bcd996t_caps; #endif /* _UNIDEN_H */ hamlib-4.6.2/rigs/uniden/bc780.c0000644000175000017500000001025314752216205013122 00000000000000/* * Hamlib Uniden backend - BC780 description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC780_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC780_FUNC (RIG_FUNC_MUTE) #define BC780_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC780_PARM_ALL (RIG_PARM_NONE) #define BC780_VFO RIG_VFO_A #define BC780_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .channel_desc=1, \ .ctcss_sql=1, \ .dcs_sql=1 #define BC780_STR_CAL UNIDEN_STR_CAL /* * bc780 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc780_caps = { RIG_MODEL(RIG_MODEL_BC780), .model_name = "BC780xlt", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC780_FUNC, .has_set_func = BC780_FUNC, .has_get_level = BC780_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC780_LEVEL_ALL), .has_get_parm = BC780_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC780_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = uniden_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 16, .str_cal = BC780_STR_CAL, .chan_list = { { 1, 500, RIG_MTYPE_MEM, {BC780_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BC780_MODES, -1, -1, BC780_VFO}, {MHz(806), MHz(956), BC780_MODES, -1, -1, BC780_VFO}, /* (minus Cellular frequencies) */ {MHz(1240), MHz(1300), BC780_MODES, -1, -1, BC780_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC780_MODES, kHz(5)}, {BC780_MODES, kHz(7.5)}, {BC780_MODES, kHz(10)}, {BC780_MODES, kHz(12.5)}, {BC780_MODES, kHz(50)}, RIG_TS_END, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq_2, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/uniden/uniden.c0000644000175000017500000005120314752216205013561 00000000000000/* * Hamlib Uniden backend - main file * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "idx_builtin.h" #include "uniden.h" static const struct { rig_model_t model; const char *id; } uniden_id_string_list[] = { { RIG_MODEL_BC780, "BC780" }, { RIG_MODEL_BC245, "BC245XLT" }, { RIG_MODEL_BC250, "BC250D" }, { RIG_MODEL_BC895, "BC895" }, { RIG_MODEL_BC235, "BC235XLT" }, { RIG_MODEL_BC785, "BC785" }, { RIG_MODEL_BC786, "BC786D" }, { RIG_MODEL_PRO2052, "PRO2052" }, /* ?? */ { RIG_MODEL_BCT8, "BCT8" }, /* ?? */ { RIG_MODEL_BC898, "BC898T" }, /* TBC */ { RIG_MODEL_NONE, NULL }, /* end marker */ }; tone_t uniden_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }; tone_t uniden_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0 }; /* * Uniden backend: should work for: * BC235XLT, BC895XLT, BC245XLT, BC780XLT, BC250D, BC785D and BCT8 * and most probably for the RadioShack PRO-2052. * * Protocol information available at http://www.cantonmaine.com/pro2052.htm * and http://www.freqofnature.com/software/protocols.html * * It seems like these rigs have no VFO, I mean only mem channels. * Is that correct? --SF */ #define EOM "\r" #define BUFSZ 64 /** * uniden_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * cmdstr - Command to be sent to the rig. Cmdstr can also be NULL, indicating * that only a reply is needed (nothing will be send). * replystr - Reply prefix to be expected. Replystr can also be NULL, indicating * that the prefix is either the cmdstr prefix or OK. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed and will return with RIG_OK after command was sent. * datasize - in: Size of buffer. It is the caller's responsibily to provide * a large enough buffer for all possible replies for a command. * out: location where to store number of bytes read. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int uniden_transaction(RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize) { struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); int retval; int retry_read = 0; char replybuf[BUFSZ]; size_t reply_len = BUFSZ; rs = STATE(rig); rs->transaction_active = 1; transaction_write: rig_flush(rp); if (cmdstr) { retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to known if it went OK */ if (!data) { data = replybuf; } if (!datasize) { datasize = &reply_len; } memset(data, 0, *datasize); retval = read_string(rp, (unsigned char *) data, *datasize, EOM, strlen(EOM), 0, 1); if (retval < 0) { if (retry_read++ < rp->retry) { goto transaction_write; } goto transaction_quit; } else { *datasize = retval; } /* Check that command termination is correct */ if (strchr(EOM, data[strlen(data) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (strcmp(data, "OK"EOM) == 0) { /* everything is fine */ retval = RIG_OK; goto transaction_quit; } /* Any syntax returning NG indicates a VALID Command but not entered * in the right mode or using the correct parameters. ERR indicates * an INVALID Command. */ if (strcmp(data, "NG"EOM) == 0 || strcmp(data, "ORER"EOM) == 0) { /* Invalid command */ rig_debug(RIG_DEBUG_VERBOSE, "%s: NG/Overflow for '%s'\n", __func__, cmdstr); retval = -RIG_EPROTO; goto transaction_quit; } if (strcmp(data, "ERR"EOM) == 0) { /* Command format error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Error for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } #define CONFIG_STRIP_CMDTRM 1 #ifdef CONFIG_STRIP_CMDTRM if (strlen(data) > 0) { data[strlen(data) - 1] = '\0'; /* not very elegant, but should work. */ } else { data[0] = '\0'; } #endif /* Special case for SQuelch */ if (replystr && !memcmp(cmdstr, "SQ", 2) && (data[0] == '-' || data[0] == '+')) { retval = RIG_OK; goto transaction_quit; } /* Command prefix if no replystr supplied */ if (!replystr) { replystr = cmdstr; } /* * Check that received the correct reply. The first two characters * should be the same as command. */ if (replystr && replystr[0] && (data[0] != replystr[0] || (replystr[1] && data[1] != replystr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string * to the decoder for callback. That way we don't ignore * any commands. */ rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, data); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } retval = RIG_OK; transaction_quit: rs->transaction_active = 0; return retval; } /* * uniden_set_freq * Assumes rig!=NULL */ int uniden_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; /* freq in hundreds of Hz */ freq /= 100; /* exactly 8 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "RF%08u" EOM, (unsigned)freq); return uniden_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL, NULL); } /* * uniden_get_freq * Assumes rig!=NULL */ int uniden_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; size_t freq_len = BUFSZ; int ret; ret = uniden_transaction(rig, "RF" EOM, 3, NULL, freqbuf, &freq_len); if (ret != RIG_OK) { return ret; } if (freq_len < 10) { return -RIG_EPROTO; } sscanf(freqbuf + 2, "%"SCNfreq, freq); /* returned freq in hundreds of Hz */ *freq *= 100; return RIG_OK; } /* * uniden_get_freq * Assumes rig!=NULL */ int uniden_get_freq_2(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; size_t freq_len = BUFSZ; int ret; ret = uniden_transaction(rig, "SG" EOM, 3, "S", freqbuf, &freq_len); if (ret != RIG_OK) { return ret; } if (freq_len < 10) { return -RIG_EPROTO; } sscanf(freqbuf + 6, "%"SCNfreq, freq); /* returned freq in hundreds of Hz */ *freq *= 100; return RIG_OK; } int uniden_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const char *modebuf; switch (mode) { case RIG_MODE_AM: modebuf = "RM AM"EOM; break; case RIG_MODE_FM: if (width > 0 && width < rig_passband_normal(rig, mode)) { modebuf = "RM NFM"EOM; } else { modebuf = "RM FM"EOM; } break; case RIG_MODE_WFM: modebuf = "RM WFM"EOM; break; default: return -RIG_EINVAL; } return uniden_transaction(rig, modebuf, strlen(modebuf), NULL, NULL, NULL); } int uniden_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char modebuf[BUFSZ]; size_t mode_len = BUFSZ; int ret; ret = uniden_transaction(rig, "RM" EOM, 3, NULL, modebuf, &mode_len); if (ret != RIG_OK) { return ret; } if (mode_len < 4) { return -RIG_EPROTO; } *width = 0; if (!strcmp(modebuf + 3, "AM")) { *mode = RIG_MODE_AM; } else if (!strcmp(modebuf + 3, "WFM")) { *mode = RIG_MODE_WFM; } else if (!strcmp(modebuf + 3, "FM")) { *mode = RIG_MODE_FM; } else if (!strcmp(modebuf + 3, "NFM")) { *mode = RIG_MODE_FM; *width = rig_passband_narrow(rig, RIG_MODE_FM); } if (*width == 0) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } int uniden_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int retval; switch (level) { case RIG_LEVEL_ATT: if (STATE(rig)->attenuator[0] == 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "AT%c"EOM, val.i != 0 ? 'N' : 'F'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = uniden_transaction(rig, levelbuf, strlen(levelbuf), NULL, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * uniden_get_level * Assumes rig!=NULL, val!=NULL */ int uniden_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[BUFSZ]; int retval; size_t lvl_len = BUFSZ; switch (level) { case RIG_LEVEL_RAWSTR: retval = uniden_transaction(rig, "SG"EOM, 3, "S", lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } /* S182 F08594375 */ sscanf(lvlbuf + 1, "%d", &val->i); /* rawstr */ break; case RIG_LEVEL_ATT: retval = uniden_transaction(rig, "AT"EOM, 3, NULL, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } val->i = lvlbuf[2] == 'N' ? STATE(rig)->attenuator[0] : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * uniden_get_dcd * Assumes rig!=NULL */ int uniden_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; size_t dcd_len = BUFSZ; int ret; ret = uniden_transaction(rig, "SQ" EOM, 3, NULL, dcdbuf, &dcd_len); if (ret != RIG_OK) { return ret; } if (dcd_len < 1 || (dcdbuf[0] != '+' && dcdbuf[0] != '-')) { return -RIG_EPROTO; } *dcd = (dcdbuf[0] == '-') ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } /* * uniden_set_mem * Assumes rig!=NULL */ int uniden_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "MA%03d" EOM, ch); return uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL, NULL); } /* * uniden_get_mem * Assumes rig!=NULL */ int uniden_get_mem(RIG *rig, vfo_t vfo, int *ch) { char membuf[BUFSZ]; size_t mem_len = BUFSZ; int ret; ret = uniden_transaction(rig, "MA" EOM, 3, "C", membuf, &mem_len); if (ret != RIG_OK) { return ret; } if (mem_len < 4) { return -RIG_EPROTO; } sscanf(membuf + 1, "%d", ch); return RIG_OK; } /* * uniden_get_channel * Assumes rig!=NULL */ int uniden_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { char cmdbuf[BUFSZ], membuf[BUFSZ]; size_t mem_len = BUFSZ; int ret; int tone; if (chan->vfo == RIG_VFO_MEM) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "PM%03d" EOM, chan->channel_num); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "MA" EOM); } ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), "C", membuf, &mem_len); if (ret != RIG_OK) { return ret; } /* * 0123456789012345678901234567890123456789 * C089 F08511625 TN DN LF AF RF N000 */ if (mem_len < 30 || membuf[5] != 'F' || membuf[15] != 'T' || membuf[18] != 'D' || membuf[21] != 'L' || membuf[24] != 'A' || membuf[27] != 'R' || membuf[30] != 'N') { return -RIG_EPROTO; } sscanf(membuf + 1, "%d", &chan->channel_num); sscanf(membuf + 6, "%"SCNfreq, &chan->freq); /* returned freq in hundreds of Hz */ chan->freq *= 100; /* TODO: Trunk, Delay, Recording */ chan->flags = (membuf[22] == 'N') ? RIG_CHFLAG_SKIP : 0; chan->levels[LVL_ATT].i = (membuf[25] == 'N') ? STATE(rig)->attenuator[0] : 0; sscanf(membuf + 41, "%d", &tone); if (tone >= 1 && tone <= 38) { chan->ctcss_sql = rig->caps->ctcss_list[tone - 1]; /* 1..38 */ } else if (tone > 38) { chan->dcs_sql = rig->caps->dcs_list[tone - 39]; /* 39..142 */ } if (chan->vfo == RIG_VFO_MEM && rig->caps->chan_desc_sz != 0) { /* only BC780 BC250 BC785 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "TA C %03d" EOM, chan->channel_num); ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, membuf, &mem_len); if (ret != RIG_OK) { return ret; } if (mem_len < 10 || memcmp(membuf, cmdbuf, 8)) { return -RIG_EPROTO; } /* TA C 001 My Alpha Tag */ strncpy(chan->channel_desc, membuf + 9, rig->caps->chan_desc_sz); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * uniden_set_channel * * Only freq can be set? */ int uniden_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char cmdbuf[BUFSZ], membuf[BUFSZ]; size_t mem_len = BUFSZ; int ret; if (chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* PM089T08511625 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "PM%03d%c%08u" EOM, chan->channel_num, ' ', (unsigned)(chan->freq / 100)); ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, membuf, &mem_len); if (ret != RIG_OK) { return ret; } if (rig->caps->chan_desc_sz != 0) { /* only BC780 BC250 BC785 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "TA C %03d %s" EOM, chan->channel_num, chan->channel_desc); ret = uniden_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL, NULL); if (ret != RIG_OK) { return ret; } } return RIG_OK; } /* * uniden_get_info * Assumes rig!=NULL */ const char *uniden_get_info(RIG *rig) { static char infobuf[BUFSZ]; size_t info_len = BUFSZ / 2, vrinfo_len = BUFSZ / 2; int ret; ret = uniden_transaction(rig, "SI" EOM, 3, NULL, infobuf, &info_len); if (ret != RIG_OK) { return NULL; } /* SI BC250D,0000000000,104 */ if (info_len < 4) { return NULL; } if (info_len >= BUFSZ) { info_len = BUFSZ - 1; } infobuf[info_len] = '\0'; /* VR not on every rig */ /* VR1.00 */ ret = uniden_transaction(rig, "VR" EOM, 3, NULL, infobuf + info_len, &vrinfo_len); if (ret == RIG_OK) { /* overwrite "VR" */ /* FIXME: need to filter \r or it screws w/ stdout */ infobuf[info_len] = '\n'; infobuf[info_len + 1] = ' '; } else { infobuf[info_len] = '\0'; } /* skip "SI " */ return infobuf + 3; } #define IDBUFSZ 32 /* * proberigs_uniden * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_uniden(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(uniden) { char idbuf[IDBUFSZ]; int id_len = -1, i; int retval = -1; int rates[] = { 9600, 19200, 0 }; /* possible baud rates */ int rates_idx; memset(idbuf, 0, IDBUFSZ); if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 1; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "SI"EOM, 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, EOM, 1, 0, 1); close(port->fd); if (retval != RIG_OK || id_len < 0) { continue; } } if (retval != RIG_OK || id_len < 0 || memcmp(idbuf, "SI ", 3)) { return RIG_MODEL_NONE; } /* * reply should be something like 'SI xxx,xx,xx\x0d' */ if (id_len < 4) { idbuf[id_len] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "probe_uniden: protocol error," " received %d: '%s'\n", id_len, idbuf); return RIG_MODEL_NONE; } /* search ID string */ for (i = 0; uniden_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (!memcmp(uniden_id_string_list[i].id, idbuf + 3, strlen(uniden_id_string_list[i].id))) { rig_debug(RIG_DEBUG_VERBOSE, "probe_uniden: " "found '%s'\n", idbuf + 3); if (cfunc) { (*cfunc)(port, uniden_id_string_list[i].model, data); } return uniden_id_string_list[i].model; } } /* * not found in known table.... * update uniden_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_uniden: found unknown device " "with ID '%s', please report to Hamlib " "developers.\n", idbuf + 3); return RIG_MODEL_NONE; } /* * initrigs_uniden is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(uniden) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&bc895_caps); rig_register(&bc898_caps); rig_register(&bc245_caps); rig_register(&bc780_caps); rig_register(&bc250_caps); rig_register(&pro2052_caps); rig_register(&bcd396t_caps); rig_register(&bcd996t_caps); return RIG_OK; } hamlib-4.6.2/rigs/uniden/bc245.c0000644000175000017500000000751014752216205013120 00000000000000/* * Hamlib Uniden backend - BC245 description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC245_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC245_FUNC (RIG_FUNC_MUTE) #define BC245_LEVEL_ALL (RIG_LEVEL_ATT) #define BC245_PARM_ALL (RIG_PARM_NONE) #define BC245_VFO RIG_VFO_A /* * bc245 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc245_caps = { RIG_MODEL(RIG_MODEL_BC245), .model_name = "BC245xlt", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC245_FUNC, .has_set_func = BC245_FUNC, .has_get_level = BC245_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC245_LEVEL_ALL), .has_get_parm = BC245_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC245_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list? */ .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 300, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(29), MHz(54), BC245_MODES, -1, -1, BC245_VFO}, {MHz(108), MHz(174), BC245_MODES, -1, -1, BC245_VFO}, {MHz(406), MHz(512), BC245_MODES, -1, -1, BC245_VFO}, {MHz(806), MHz(956), BC245_MODES, -1, -1, BC245_VFO}, /* TODO: less cellular */ RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC245_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/uniden/uniden_digital.c0000644000175000017500000002723514752216205015266 00000000000000/* * Hamlib Uniden backend - uniden_digital backend * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "uniden_digital.h" /* * Uniden Digital backend should work for: * BCD996T as well as the BCD396T. Some protocols available for the * BCD996T may not be available for the BCD396T or modified to work. * * Protocol information can be found here: * http://www.uniden.com/files/BCD396T_Protocol.pdf * http://www.uniden.com/files/BCD996T_Protocol.pdf * * There are undocumented commands such as firmware_dump and * firmware_load. These commands are defined within DSctl code. * * There are two methods of retrieving the next memory location * (aka frequency bank). Use either the "Get Next Location" or * use the address returned from one of the commands. If you decide * the latter method, the order is slightly confusing but, I have it * well documented within DSctl. The latter method is also as much * as 30% faster than using the Uniden software or "Get Next * Location" command. */ #if 0 // deactivated temporarily because uniden_id_string_list is nowhere used static const struct { rig_model_t model; const char *id; } uniden_id_string_list[] = { { RIG_MODEL_BCD396T, "BCD396T" }, { RIG_MODEL_BCD996T, "BCD996T" }, { RIG_MODEL_NONE, NULL }, /* end marker */ }; #endif /* EOM is not consistent with this BCD996T! * Some commands return newline while others carriage return. * Some commands return nothing special for End of Line char. */ #define EOM "\r" /* end of message */ /* I'm still getting clipped output from buffers being too small elsewhere! */ #define BUFSZ 256 /* Wild guess, 64 was too small. */ /** * uniden_transaction * uniden_digital_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * cmdstr - Command to be sent to the rig. Cmdstr can also be NULL, indicating * that only a reply is needed (nothing will be send). * replystr - Reply prefix to be expected. Replystr can also be NULL, indicating * that the prefix is either the cmdstr prefix or OK. * data - Buffer for reply string. Can be NULL, indicating that no reply is * is needed and will return with RIG_OK after command was sent. * datasize - in: Size of buffer. It is the caller's responsibily to provide * a large enough buffer for all possible replies for a command. * out: location where to store number of bytes read. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int uniden_digital_transaction(RIG *rig, const char *cmdstr, int cmd_len, const char *replystr, char *data, size_t *datasize) { struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); int retval; int retry_read = 0; char replybuf[BUFSZ]; size_t reply_len = BUFSZ; rs = STATE(rig); rs->transaction_active = 1; transaction_write: rig_flush(rp); if (cmdstr) { retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { goto transaction_quit; } } /* Always read the reply to known if it went OK */ if (!data) { data = replybuf; } if (!datasize) { datasize = &reply_len; } memset(data, 0, *datasize); retval = read_string(rp, (unsigned char *) data, *datasize, EOM, strlen(EOM), 0, 1); if (retval < 0) { if (retry_read++ < rp->retry) { goto transaction_write; } goto transaction_quit; } else { *datasize = retval; } /* Check that command termination is correct * FIXME: Sometimes the BCD996T DOES NOT return a * consistent carriage return or newline. * ie: STS command will not return either "\r" or "\n"! */ /*if (strchr(EOM, data[strlen(data)-1])==NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, data); if (retry_read++ < rp->retry) goto transaction_write; retval = -RIG_EPROTO; goto transaction_quit; }*/ if (strcmp(data, "OK"EOM)) { /* everything is fine */ retval = RIG_OK; goto transaction_quit; } /* Any syntax returning NG indicates a VALID Command but not entered * in the right mode or using the correct parameters. ERR indicates * an INVALID Command. */ if (strcmp(data, "NG"EOM)) { /* Invalid command */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Command Format Error / Value Error for '%s'\n", __func__, cmdstr); retval = -RIG_EPROTO; goto transaction_quit; } if (strcmp(data, "ERR"EOM)) { /* Command format error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: The Command is Invalid at this Time for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } if (strcmp(data, "FER"EOM)) { /* Framing error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Framing Error for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } if (strcmp(data, "ORER"EOM)) { /* Overrun error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Overrun Error for '%s'\n", __func__, cmdstr); retval = -RIG_EINVAL; goto transaction_quit; } #define CONFIG_STRIP_CMDTRM 1 #ifdef CONFIG_STRIP_CMDTRM if (strlen(data) > 0) { data[strlen(data) - 1] = '\0'; /* not very elegant, but should work. */ } else { data[0] = '\0'; } #endif /* Special case for SQuelch */ /*if (!memcmp(cmdstr,"SQ",2) && (replystr[0] == '-' || replystr[0] == '+')) { retval = RIG_OK; goto transaction_quit; }*/ /* Command prefix if no replystr supplied */ if (!replystr) { replystr = cmdstr; } /* * Check that received the correct reply. The first two characters * should be the same as command. */ if (replystr && replystr[0] && (data[0] != replystr[0] || (replystr[1] && data[1] != replystr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string * to the decoder for callback. That way we don't ignore * any commands. */ rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, data); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } retval = RIG_OK; transaction_quit: rs->transaction_active = 0; return retval; } /* * uniden_get_info * Assumes rig!=NULL */ const char *uniden_digital_get_info(RIG *rig) { static char infobuf[BUFSZ]; size_t info_len = BUFSZ / 2, mdlinfo_len = BUFSZ / 2; int ret; /* GET CURRENT STATUS -- STS */ ret = uniden_digital_transaction(rig, "STS" EOM, 3, NULL, infobuf, &info_len); /* NOTE FOR ME: Check Buffer Size with what we got returned in info_len. * Don't know the max length of return on these units, so check frequently! * Use five v's (-vvvvv) to activate output. */ rig_debug(RIG_DEBUG_VERBOSE, "%s: DEBUG BUFSZ'%i'\n", __func__, BUFSZ); rig_debug(RIG_DEBUG_VERBOSE, "%s: DEBUG info_len'%i'\n", __func__, (int)info_len); if (ret != RIG_OK) { return NULL; } /* Example output: * STS,011000, XXX ,,Fa * * STS command returns 3 lines including system, truck, freq info * * XXX indicates the BCD996T returns some non-printable ascii chars * within its comma separated fields. See pg 30-32 of BCD996T_Protocol.pdf. * These chars cause abnomalies on stdout! */ /* FIXME: Strip or replace non-printable chars return from STS command! * (Below is a snip from DSctl utils.c file) * * For example, search each character. For each sequence of chars found, replace with normal printable ascii [KEY] * if (strstr(bcd_chars, "\213") != 0) * strncat(tmp_line, "[FUNCTION KEY] ", 15); * * if (strstr(bcd_chars, "\215\216\217\220") != 0) * strncat(tmp_line, "[HOLD] ", 7); */ if (info_len < 4) { return NULL; } if (info_len >= BUFSZ) { rig_debug(RIG_DEBUG_VERBOSE, "%s: DEBUG Max BUFSZ Reached: info_len = '%i'\n", __func__, (int)info_len); info_len = BUFSZ - 1; } infobuf[info_len] = '\0'; /* VR not on every rig <- This doesn't belong here for the newer BCD* units*/ /* VR1.00 */ /*ret = uniden_digital_transaction (rig, "VR" EOM, 2, NULL, infobuf+info_len, &vrinfo_len); if (ret == RIG_OK) {*/ /* overwrite "VR" */ /* FIXME: need to filter \r or it screws w/ stdout */ /*infobuf[info_len] = '\n'; infobuf[info_len+1] = ' '; } else { infobuf[info_len] = '\0'; }*/ /* GET MODEL INFO -- MDL */ ret = uniden_digital_transaction(rig, "MDL" EOM, 3, NULL, infobuf + info_len, &mdlinfo_len); if (ret == RIG_OK) { infobuf[info_len] = '\n'; infobuf[info_len + 1] = ' '; } else { infobuf[info_len] = '\0'; } /* GET FIRMWARE VERSION -- VER */ ret = uniden_digital_transaction(rig, "VER" EOM, 3, NULL, infobuf + info_len, &mdlinfo_len); if (ret == RIG_OK) { infobuf[info_len] = '\n'; infobuf[info_len + 1] = ' '; } else { infobuf[info_len] = '\0'; } /* skip beginning "STS, " */ /* FIXME: What about clipping the above two other MDL & VER Commands? */ return infobuf + 4; } /* * skeleton */ int uniden_digital_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { #if 0 char freqbuf[BUFSZ]; /* freq in hundreds of Hz */ freq /= 100; /* exactly 8 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "RF%08u" EOM, (unsigned)freq); return uniden_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL, NULL); #else return -RIG_ENIMPL; #endif } /* * skeleton */ int uniden_digital_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { #if 0 char freqbuf[BUFSZ]; size_t freq_len = BUFSZ; int ret; ret = uniden_transaction(rig, "RF" EOM, 3, NULL, freqbuf, &freq_len); if (ret != RIG_OK) { return ret; } if (freq_len < 10) { return -RIG_EPROTO; } sscanf(freqbuf + 2, "%"SCNfreq, freq); /* returned freq in hundreds of Hz */ *freq *= 100; return RIG_OK; #else return -RIG_ENIMPL; #endif } hamlib-4.6.2/rigs/uniden/bc250.c0000644000175000017500000001023514752216205013112 00000000000000/* * Hamlib Uniden backend - BC250 description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define BC250_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BC250_FUNC (RIG_FUNC_MUTE) #define BC250_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define BC250_PARM_ALL (RIG_PARM_NONE) #define BC250_VFO RIG_VFO_A #define BC250_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS \ .channel_desc=1, \ .ctcss_sql=1, \ .dcs_sql=1 #define BC250_STR_CAL UNIDEN_STR_CAL /* * bc250 rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bc250_caps = { RIG_MODEL(RIG_MODEL_BC250), .model_name = "BC250D", .mfg_name = "Uniden", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = BC250_FUNC, .has_set_func = BC250_FUNC, .has_get_level = BC250_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BC250_LEVEL_ALL), .has_get_parm = BC250_PARM_ALL, .has_set_parm = RIG_PARM_SET(BC250_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = uniden_ctcss_list, .dcs_list = uniden_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 16, .str_cal = BC250_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, {BC250_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BC250_MODES, -1, -1, BC250_VFO}, {MHz(806), MHz(956), BC250_MODES, -1, -1, BC250_VFO}, /* (minus Cellular frequencies) */ {MHz(1240), MHz(1300), BC250_MODES, -1, -1, BC250_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BC250_MODES, kHz(5)}, {BC250_MODES, kHz(7.5)}, {BC250_MODES, kHz(10)}, {BC250_MODES, kHz(12.5)}, {BC250_MODES, kHz(50)}, RIG_TS_END, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/uniden/bcd996t.c0000644000175000017500000000751514752216205013472 00000000000000/* * Hamlib Uniden backend - BCD996T description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" /*#include "uniden.h"*/ #include "uniden_digital.h" /* TODO: All these defines have to be filled in properly */ #define BCD996T_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define BCD996T_FUNC (RIG_FUNC_MUTE) #define BCD996T_LEVEL_ALL (RIG_LEVEL_ATT) #define BCD996T_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define BCD996T_VFO (RIG_VFO_A|RIG_VFO_B) #define BCD996T_CHANNEL_CAPS \ .freq=1,\ .flags=1, /* L/O */ /* * bcd996t rig capabilities. * * TODO: check this with manual or web site. */ struct rig_caps bcd996t_caps = { RIG_MODEL(RIG_MODEL_BCD996T), .model_name = "BCD-996T", .mfg_name = "Uniden", .version = BACKEND_DIGITAL_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 2000, .retry = 3, .has_get_func = BCD996T_FUNC, .has_set_func = BCD996T_FUNC, .has_get_level = BCD996T_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(BCD996T_LEVEL_ALL), .has_get_parm = BCD996T_PARM_ALL, .has_set_parm = RIG_PARM_SET(BCD996T_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list? */ .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 5999, RIG_MTYPE_MEM, {BCD996T_CHANNEL_CAPS} }, /* Really 6000 channels? */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(512), BCD996T_MODES, -1, -1, BCD996T_VFO}, {MHz(764), MHz(776), BCD996T_MODES, -1, -1, BCD996T_VFO}, {MHz(794), MHz(956), BCD996T_MODES, -1, -1, BCD996T_VFO}, {MHz(1240), MHz(1300), BCD996T_MODES, -1, -1, BCD996T_VFO}, /* TBC */ RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {BCD996T_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .get_info = uniden_digital_get_info, .set_freq = uniden_digital_set_freq, .get_freq = uniden_digital_get_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/uniden/pro2052.c0000644000175000017500000001151314752216205013410 00000000000000/* * Hamlib Uniden backend - Radio Shack PRO-2052 description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "uniden.h" #define PRO2052_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define PRO2052_FUNC (RIG_FUNC_MUTE) #define PRO2052_LEVEL_ALL (RIG_LEVEL_NONE) #define PRO2052_PARM_ALL (RIG_PARM_NONE) #define PRO2052_VFO RIG_VFO_A #define PRO2052_CHANNEL_CAPS \ UNIDEN_CHANNEL_CAPS /* * PRO-2052 rig capabilities. * * From http://www.cantonmaine.com/pro2052.htm: * After connecting the cable, turn on the computer and the scanner and then * press and hold the Remote/Hold button on the scanner until you see "SFT" * flashing on the right side of the LCD. You should now be communicating * with the scanner. If it doesn't work, check all the normal stuff for * whatever it was you overlooked. NOTE: You can change the scanner's * default * baud rate by holding down the Remote/Hold button while turning * on the scanner.) * * TODO: check this with manual or web site. */ struct rig_caps pro2052_caps = { RIG_MODEL(RIG_MODEL_PRO2052), .model_name = "PRO-2052", .mfg_name = "Radio Shack", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRUNKSCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = PRO2052_FUNC, .has_set_func = PRO2052_FUNC, .has_get_level = PRO2052_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(PRO2052_LEVEL_ALL), .has_get_parm = PRO2052_PARM_ALL, .has_set_parm = RIG_PARM_SET(PRO2052_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list? */ .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 10, /* A..J */ .chan_desc_sz = 0, .chan_list = { { 0, 999, RIG_MTYPE_MEM, {PRO2052_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(29), MHz(54), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(108), MHz(174), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(179.75), MHz(512), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(806), MHz(823.9375), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(851), MHz(868.9875), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(896.1125), MHz(956), PRO2052_MODES, -1, -1, PRO2052_VFO}, {MHz(1240), MHz(1300), PRO2052_MODES, -1, -1, PRO2052_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {PRO2052_MODES, kHz(5)}, {PRO2052_MODES, kHz(7.5)}, {PRO2052_MODES, kHz(10)}, {PRO2052_MODES, kHz(12.5)}, {PRO2052_MODES, kHz(25)}, {PRO2052_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, .set_freq = uniden_set_freq, .get_freq = uniden_get_freq, .set_mode = uniden_set_mode, .get_mode = uniden_get_mode, .set_mem = uniden_set_mem, .get_mem = uniden_get_mem, .get_dcd = uniden_get_dcd, .get_info = uniden_get_info, .get_level = uniden_get_level, .set_level = uniden_set_level, .get_channel = uniden_get_channel, .set_channel = uniden_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/dorji/0000755000175000017500000000000014752216242012040 500000000000000hamlib-4.6.2/rigs/dorji/Makefile.am0000644000175000017500000000023014752216205014006 00000000000000DORJISRC = dorji.c dorji.h dra818.c dra818.h noinst_LTLIBRARIES = libhamlib-dorji.la libhamlib_dorji_la_SOURCES = $(DORJISRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/dorji/Makefile.in0000644000175000017500000005234714752216216014041 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/dorji ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_dorji_la_LIBADD = am__objects_1 = dorji.lo dra818.lo am_libhamlib_dorji_la_OBJECTS = $(am__objects_1) libhamlib_dorji_la_OBJECTS = $(am_libhamlib_dorji_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dorji.Plo ./$(DEPDIR)/dra818.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_dorji_la_SOURCES) DIST_SOURCES = $(libhamlib_dorji_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DORJISRC = dorji.c dorji.h dra818.c dra818.h noinst_LTLIBRARIES = libhamlib-dorji.la libhamlib_dorji_la_SOURCES = $(DORJISRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/dorji/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/dorji/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-dorji.la: $(libhamlib_dorji_la_OBJECTS) $(libhamlib_dorji_la_DEPENDENCIES) $(EXTRA_libhamlib_dorji_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_dorji_la_OBJECTS) $(libhamlib_dorji_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dorji.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dra818.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dorji.Plo -rm -f ./$(DEPDIR)/dra818.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dorji.Plo -rm -f ./$(DEPDIR)/dra818.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/dorji/Android.mk0000644000175000017500000000040114752216205013663 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dorji.c dra818.c LOCAL_MODULE := dorji LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/dorji/dorji.c0000644000175000017500000000222114752216205013227 00000000000000/* * Hamlib Dorji backend - main file * Copyright (c) 2017 by Jeroen Vreeken * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "register.h" #include "dorji.h" /* * initrigs_dorji is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(dorji) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&dra818u_caps); rig_register(&dra818v_caps); return RIG_OK; } hamlib-4.6.2/rigs/dorji/dorji.h0000644000175000017500000000177314752216205013247 00000000000000/* * Hamlib Dorji backend - main header * Copyright (c) 2017 by Jeroen Vreeken * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DORJI_H #define _DORJI_H 1 #include "hamlib/rig.h" extern struct rig_caps dra818u_caps; extern struct rig_caps dra818v_caps; #endif /* _DORJI_H */ hamlib-4.6.2/rigs/dorji/dra818.h0000644000175000017500000000162414752216205013142 00000000000000/* * Hamlib Dorji DRA818 backend * Copyright (c) 2017 by Jeroen Vreeken * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DRA818_H #define _DRA818_H 1 #endif /* _DRA818_H */ hamlib-4.6.2/rigs/dorji/dra818.c0000644000175000017500000004277514752216205013151 00000000000000/* * Hamlib Dorji DRA818 backend * Copyright (c) 2017 by Jeroen Vreeken * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "tones.h" #include "dra818.h" static const char *dra818_handshake_cmd = "AT+DMOCONNECT\r\n"; static const char *dra818_handshake_res = "+DMOCONNECT:0\r\n"; static const char *dra818_setgroup_res = "+DMOSETGROUP:0\r\n"; static const char *dra818_setvolume_res = "+DMOSETVOLUME:0\r\n"; struct dra818_priv { shortfreq_t tx_freq; shortfreq_t rx_freq; shortfreq_t bw; split_t split; tone_t ctcss_tone; tone_t ctcss_sql; tone_t dcs_code; tone_t dcs_sql; int sql; int vol; }; static int dra818_response(RIG *rig, const char *expected) { char response[80]; int r = read_string(RIGPORT(rig), (unsigned char *) response, sizeof(response), "\n", 1, 0, 1); if (r != strlen(expected)) { return -RIG_EIO; } if (strcmp(expected, response) != 0) { rig_debug(RIG_DEBUG_VERBOSE, "dra818: response: %s\n", response); return -RIG_ERJCTED; } return RIG_OK; } static void dra818_subaudio(RIG *rig, char *subaudio, int subaudio_len, tone_t tone, tone_t code) { if (code) { SNPRINTF(subaudio, subaudio_len, "%03uI", code % 10000); return; } else if (tone) { int i; for (i = 0; rig->caps->ctcss_list[i]; i++) { if (rig->caps->ctcss_list[i] == tone) { SNPRINTF(subaudio, subaudio_len, "%04d", (i + 1) % 10000); return; } } } subaudio[0] = '0'; subaudio[1] = '0'; subaudio[2] = '0'; subaudio[3] = '0'; } static int dra818_setgroup(RIG *rig) { const struct dra818_priv *priv = STATE(rig)->priv; char cmd[80]; char subtx[8] = { 0 }; char subrx[8] = { 0 }; dra818_subaudio(rig, subtx, sizeof(subtx), priv->ctcss_tone, priv->dcs_code); dra818_subaudio(rig, subrx, sizeof(subrx), priv->ctcss_sql, priv->dcs_sql); SNPRINTF(cmd, sizeof(cmd), "AT+DMOSETGROUP=%1d,%03d.%04d,%03d.%04d,%4s,%1d,%4s\r\n", priv->bw == 12500 ? 0 : 1, (int)(priv->tx_freq / 1000000), (int)((priv->tx_freq % 1000000) / 100), (int)(priv->rx_freq / 1000000), (int)((priv->rx_freq % 1000000) / 100), subtx, priv->sql, subrx); write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); return dra818_response(rig, dra818_setgroup_res); } static int dra818_setvolume(RIG *rig) { const struct dra818_priv *priv = STATE(rig)->priv; char cmd[80]; SNPRINTF(cmd, sizeof(cmd), "AT+DMOSETVOLUME=%1d\r\n", priv->vol); write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); return dra818_response(rig, dra818_setvolume_res); } int dra818_init(RIG *rig) { struct dra818_priv *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: dra818_init called\n", __func__); STATE(rig)->priv = calloc(sizeof(*priv), 1); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; switch (rig->caps->rig_model) { case RIG_MODEL_DORJI_DRA818V: priv->rx_freq = 145000000; break; case RIG_MODEL_DORJI_DRA818U: priv->rx_freq = 435000000; break; } priv->tx_freq = priv->rx_freq; priv->bw = 12500; priv->split = RIG_SPLIT_OFF; priv->ctcss_tone = 0; priv->ctcss_sql = 0; priv->dcs_code = 0; priv->dcs_sql = 0; priv->sql = 4; priv->vol = 6; return RIG_OK; } int dra818_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: dra818_cleanup called\n", __func__); free(STATE(rig)->priv); return RIG_OK; } int dra818_open(RIG *rig) { int i; int r = -1; for (i = 0; i < 3; i++) { write_block(RIGPORT(rig), (unsigned char *) dra818_handshake_cmd, strlen(dra818_handshake_cmd)); r = dra818_response(rig, dra818_handshake_res); if (r == RIG_OK) { break; } } if (r != RIG_OK) { return r; } r = dra818_setvolume(rig); if (r != RIG_OK) { return r; } return dra818_setgroup(rig); } int dra818_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dra818_priv *priv = STATE(rig)->priv; /* Nearest channel */ shortfreq_t sfreq = ((freq + priv->bw / 2) / priv->bw); sfreq *= priv->bw; rig_debug(RIG_DEBUG_VERBOSE, "dra818: requested freq = %"PRIfreq" Hz, set freq = %d Hz\n", freq, (int)sfreq); if (vfo == RIG_VFO_RX) { priv->rx_freq = sfreq; if (priv->split == RIG_SPLIT_OFF) { priv->tx_freq = sfreq; } } else if (vfo == RIG_VFO_TX) { priv->tx_freq = sfreq; if (priv->split == RIG_SPLIT_OFF) { priv->rx_freq = sfreq; } } else { return -RIG_EINVAL; } return dra818_setgroup(rig); } int dra818_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct dra818_priv *priv = STATE(rig)->priv; if (width > 12500) { priv->bw = 25000; } else { priv->bw = 12500; } rig_debug(RIG_DEBUG_VERBOSE, "dra818: bandwidth: %d\n", (int)priv->bw); return dra818_setgroup(rig); } int dra818_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct dra818_priv *priv = STATE(rig)->priv; *mode = RIG_MODE_FM; *width = priv->bw; return RIG_OK; } int dra818_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { const struct dra818_priv *priv = STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char cmd[80]; char response[8]; int r; SNPRINTF(cmd, sizeof(cmd), "S+%03d.%04d\r\n", (int)(priv->rx_freq / 1000000), (int)((priv->rx_freq % 1000000) / 100)); write_block(rp, (unsigned char *) cmd, strlen(cmd)); r = read_string(rp, (unsigned char *) response, sizeof(response), "\n", 1, 0, 1); if (r != 5) { return -RIG_EIO; } if (response[3] == 1) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } int dra818_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct dra818_priv *priv = STATE(rig)->priv; switch (vfo) { case RIG_VFO_RX: *freq = priv->rx_freq; break; case RIG_VFO_TX: *freq = priv->tx_freq; break; default: return -RIG_EINVAL; } return RIG_OK; } int dra818_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct dra818_priv *priv = STATE(rig)->priv; priv->split = split; if (split == RIG_SPLIT_OFF) { priv->tx_freq = priv->rx_freq; } return dra818_setgroup(rig); } int dra818_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct dra818_priv *priv = STATE(rig)->priv; *split = priv->split; if (priv->split == RIG_SPLIT_ON) { *tx_vfo = RIG_VFO_TX; } else { *tx_vfo = RIG_VFO_RX; } return RIG_OK; } int dra818_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct dra818_priv *priv = STATE(rig)->priv; switch (level) { case RIG_LEVEL_SQL: /* SQL range: 0..8 (0=monitor) */ val->f = (priv->sql / 8.0); break; case RIG_LEVEL_AF: /* AF range: 1..8 */ val->f = (priv->vol / 8.0); break; default: return -RIG_EINVAL; } return RIG_OK; } int dra818_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dra818_priv *priv = STATE(rig)->priv; switch (level) { case RIG_LEVEL_SQL: /* SQL range: 0..8 (0=monitor) */ priv->sql = val.f * 8; if (priv->sql < 0) { priv->sql = 0; } if (priv->sql > 8) { priv->sql = 8; } return dra818_setgroup(rig); case RIG_LEVEL_AF: /* AF range: 1..8 */ priv->vol = val.f * 8; if (priv->vol < 1) { priv->vol = 1; } if (priv->vol > 8) { priv->vol = 8; } return dra818_setvolume(rig); default: break; } return -RIG_EINVAL; } int dra818_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { struct dra818_priv *priv = STATE(rig)->priv; priv->dcs_code = code; if (code) { priv->ctcss_tone = 0; } return dra818_setgroup(rig); } int dra818_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct dra818_priv *priv = STATE(rig)->priv; priv->ctcss_tone = tone; if (tone) { priv->dcs_code = 0; } return dra818_setgroup(rig); } int dra818_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { struct dra818_priv *priv = STATE(rig)->priv; priv->dcs_sql = code; if (code) { priv->ctcss_sql = 0; } return dra818_setgroup(rig); } int dra818_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct dra818_priv *priv = STATE(rig)->priv; priv->ctcss_sql = tone; if (tone) { priv->dcs_sql = 0; } return dra818_setgroup(rig); } int dra818_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { const struct dra818_priv *priv = STATE(rig)->priv; *tone = priv->ctcss_sql; return RIG_OK; } int dra818_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { const struct dra818_priv *priv = STATE(rig)->priv; *code = priv->dcs_sql; return RIG_OK; } int dra818_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { const struct dra818_priv *priv = STATE(rig)->priv; *code = priv->dcs_code; return RIG_OK; } int dra818_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct dra818_priv *priv = STATE(rig)->priv; *tone = priv->ctcss_tone; return RIG_OK; } struct rig_caps dra818u_caps = { RIG_MODEL(RIG_MODEL_DORJI_DRA818U), .model_name = "DRA818U", .mfg_name = "Dorji", .version = "20191209.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_set_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_get_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_set_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = /* 38 according to doc, are they all correct? */ (tone_t[]) { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(400), MHz(480), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(400), MHz(480), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_70cm(1, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_70cm(2, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_FM, Hz(12500)}, RIG_TS_END, }, .filters = { {RIG_MODE_FM, Hz(12500)}, {RIG_MODE_FM, Hz(25000)}, RIG_FLT_END, }, .rig_init = dra818_init, .rig_cleanup = dra818_cleanup, .rig_open = dra818_open, .set_freq = dra818_set_freq, .get_freq = dra818_get_freq, .set_split_vfo = dra818_set_split_vfo, .get_split_vfo = dra818_get_split_vfo, .set_mode = dra818_set_mode, .get_mode = dra818_get_mode, .get_dcd = dra818_get_dcd, .set_level = dra818_set_level, .get_level = dra818_get_level, .set_dcs_code = dra818_set_dcs_code, .set_ctcss_tone = dra818_set_ctcss_tone, .set_dcs_sql = dra818_set_dcs_sql, .set_ctcss_sql = dra818_set_ctcss_sql, .get_dcs_code = dra818_get_dcs_code, .get_ctcss_tone = dra818_get_ctcss_tone, .get_dcs_sql = dra818_get_dcs_sql, .get_ctcss_sql = dra818_get_ctcss_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps dra818v_caps = { RIG_MODEL(RIG_MODEL_DORJI_DRA818V), .model_name = "DRA818V", .mfg_name = "Dorji", .version = "20191209.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_set_func = RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_SQL, .has_get_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_set_level = RIG_LEVEL_AF | RIG_LEVEL_SQL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = /* 38 according to doc, are they all correct? */ (tone_t[]) { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(134), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(134), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_RX }, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_2m(1, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_2m(2, RIG_MODE_FM, W(0.5), W(1), RIG_VFO_TX, RIG_ANT_1), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_FM, Hz(12500)}, RIG_TS_END, }, .filters = { {RIG_MODE_FM, Hz(12500)}, {RIG_MODE_FM, Hz(25000)}, RIG_FLT_END, }, .rig_init = dra818_init, .rig_cleanup = dra818_cleanup, .rig_open = dra818_open, .set_freq = dra818_set_freq, .get_freq = dra818_get_freq, .set_split_vfo = dra818_set_split_vfo, .get_split_vfo = dra818_get_split_vfo, .set_mode = dra818_set_mode, .get_mode = dra818_get_mode, .get_dcd = dra818_get_dcd, .set_level = dra818_set_level, .get_level = dra818_get_level, .set_dcs_code = dra818_set_dcs_code, .set_ctcss_tone = dra818_set_ctcss_tone, .set_dcs_sql = dra818_set_dcs_sql, .set_ctcss_sql = dra818_set_ctcss_sql, .get_dcs_code = dra818_get_dcs_code, .get_ctcss_tone = dra818_get_ctcss_tone, .get_dcs_sql = dra818_get_dcs_sql, .get_ctcss_sql = dra818_get_ctcss_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/pcr/0000755000175000017500000000000014752216243011516 500000000000000hamlib-4.6.2/rigs/pcr/pcr1000.c0000644000175000017500000001170014752216205012664 00000000000000/* * Hamlib PCR backend - PCR-1000 description * Copyright (c) 2001-2009 by Stephane Fillod and Darren Hatcher * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR1000_MODES ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM | RIG_MODE_CW | RIG_MODE_SSB ) #define PCR1000_FUNC ( RIG_FUNC_NB | RIG_FUNC_TSQL | RIG_FUNC_NB | \ RIG_FUNC_ANF | RIG_FUNC_NR | RIG_FUNC_AFC ) #define PCR1000_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | \ RIG_LEVEL_NR ) static const struct pcr_priv_caps pcr1000_priv = { .reply_size = 6, .reply_offset = 1, .always_sync = 0, }; /* * IC PCR1000 rigs capabilities. */ struct rig_caps pcr1000_caps = { RIG_MODEL(RIG_MODEL_PCR1000), .model_name = "IC-PCR1000", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* slower speeds gave troubles */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 12, .post_write_delay = 2, .timeout = 400, .retry = 3, .has_get_func = PCR1000_FUNC, .has_set_func = PCR1000_FUNC, .has_get_level = PCR1000_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR1000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = {}, .ctcss_list = pcr_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(10), GHz(1.3), PCR1000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(10), MHz(824) - 10, PCR1000_MODES, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR1000_MODES, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(1.3), PCR1000_MODES, -1, -1, RIG_VFO_A }, RIG_FRNG_END }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR1000_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_FM | RIG_MODE_AM, kHz(15) }, { RIG_MODE_FM | RIG_MODE_AM, kHz(6) }, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM, kHz(2.8) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM | RIG_MODE_FM | RIG_MODE_AM, kHz(50) }, RIG_FLT_END, }, .priv = (void *)& pcr1000_priv, /* XXX fake */ .str_cal = { 3, { { 0, -60 }, { 127, 0 }, { 255, 60 } } }, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/pcr/Makefile.am0000644000175000017500000000024114752216205013465 00000000000000PCRSRC = pcr1000.c pcr100.c pcr1500.c pcr2500.c pcr.c pcr.h noinst_LTLIBRARIES = libhamlib-pcr.la libhamlib_pcr_la_SOURCES = $(PCRSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/pcr/Makefile.in0000644000175000017500000005341614752216216013514 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/pcr ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_pcr_la_LIBADD = am__objects_1 = pcr1000.lo pcr100.lo pcr1500.lo pcr2500.lo pcr.lo am_libhamlib_pcr_la_OBJECTS = $(am__objects_1) libhamlib_pcr_la_OBJECTS = $(am_libhamlib_pcr_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/pcr.Plo ./$(DEPDIR)/pcr100.Plo \ ./$(DEPDIR)/pcr1000.Plo ./$(DEPDIR)/pcr1500.Plo \ ./$(DEPDIR)/pcr2500.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_pcr_la_SOURCES) DIST_SOURCES = $(libhamlib_pcr_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ PCRSRC = pcr1000.c pcr100.c pcr1500.c pcr2500.c pcr.c pcr.h noinst_LTLIBRARIES = libhamlib-pcr.la libhamlib_pcr_la_SOURCES = $(PCRSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/pcr/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/pcr/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-pcr.la: $(libhamlib_pcr_la_OBJECTS) $(libhamlib_pcr_la_DEPENDENCIES) $(EXTRA_libhamlib_pcr_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_pcr_la_OBJECTS) $(libhamlib_pcr_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr1000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr1500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcr2500.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/pcr.Plo -rm -f ./$(DEPDIR)/pcr100.Plo -rm -f ./$(DEPDIR)/pcr1000.Plo -rm -f ./$(DEPDIR)/pcr1500.Plo -rm -f ./$(DEPDIR)/pcr2500.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/pcr.Plo -rm -f ./$(DEPDIR)/pcr100.Plo -rm -f ./$(DEPDIR)/pcr1000.Plo -rm -f ./$(DEPDIR)/pcr1500.Plo -rm -f ./$(DEPDIR)/pcr2500.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/pcr/pcr1500.c0000644000175000017500000001265214752216205012700 00000000000000/* * Hamlib PCR backend - PCR-1500 description * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR1500_MODES_WIDE ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM ) #define PCR1500_MODES_NAR ( RIG_MODE_CW | RIG_MODE_SSB ) #define PCR1500_MODES ( PCR1500_MODES_NAR | PCR1500_MODES_WIDE ) #define PCR1500_FUNC ( RIG_FUNC_NB | RIG_FUNC_TSQL | RIG_FUNC_NB | \ RIG_FUNC_ANF | RIG_FUNC_NR | RIG_FUNC_AFC ) #define PCR1500_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | \ RIG_LEVEL_NR ) static const struct pcr_priv_caps pcr1500_priv = { .reply_size = 6, .reply_offset = 0, .always_sync = 0, }; /* * IC PCR1500 rigs capabilities. */ struct rig_caps pcr1500_caps = { RIG_MODEL(RIG_MODEL_PCR1500), .model_name = "IC-PCR1500", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* lower speeds gave troubles */ .serial_rate_max = 38400, .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 = 400, .retry = 3, .has_get_func = PCR1500_FUNC, .has_set_func = PCR1500_FUNC, .has_get_level = PCR1500_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR1500_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = { .i = 1 } }, [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 16.0 }, .step = { .f = 1.0 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = {}, .ctcss_list = pcr_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(495), GHz(1.3), PCR1500_MODES_NAR, -1, -1, RIG_VFO_A}, { kHz(10), GHz(3.3) - kHz(1), PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A}, RIG_FRNG_END }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(495), MHz(824) - 10, PCR1500_MODES_NAR, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR1500_MODES_NAR, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(1.3), PCR1500_MODES_NAR, -1, -1, RIG_VFO_A }, { kHz(10), MHz(824) - 10, PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(3.3) - kHz(1), PCR1500_MODES_WIDE, -1, -1, RIG_VFO_A }, RIG_FRNG_END }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR1500_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_FM | RIG_MODE_AM, kHz(15) }, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM, kHz(2.8)}, { RIG_MODE_FM | RIG_MODE_AM, kHz(6) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM | RIG_MODE_FM | RIG_MODE_AM, kHz(50) }, RIG_FLT_END, }, .priv = (void *)& pcr1500_priv, /* XXX fake */ .str_cal = { 3, { { 0, -60 }, { 127, 0 }, { 255, 60 } } }, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/pcr/Android.mk0000644000175000017500000000043314752216205013345 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := pcr1000.c pcr100.c pcr1500.c pcr2500.c pcr.c LOCAL_MODULE := pcr LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/pcr/pcr.c0000644000175000017500000013743614752216205012402 00000000000000/* * Hamlib PCR backend - main file * Copyright (c) 2001-2005 by Darren Hatcher * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (C) 2007-09 by Alessandro Zummo * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Tested on * * (402) PCR100 fw 1.2, proto 1.0 (usb-to-serial) by IZ1PRB * (401) PCR1000 fw 1.0, proto 1.0 (serial) by KM3T * (403) PCR1500 fw 2.0, proto 2.0 (usb) by KM3T * */ #include #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "cal.h" #include "pcr.h" /* * modes in use by the "MD" command */ #define MD_LSB '0' #define MD_USB '1' #define MD_AM '2' #define MD_CW '3' #define MD_FM '5' #define MD_WFM '6' #define MD_DSTAR '7' /* PCR-2500 Only */ #define MD_P25 '8' /* PCR-2500 Only */ /* define 2.8kHz, 6kHz, 15kHz, 50kHz, and 230kHz */ #define FLT_2_8kHz '0' #define FLT_6kHz '1' #define FLT_15kHz '2' #define FLT_50kHz '3' #define FLT_230kHz '4' /* as returned by GD? */ #define OPT_UT106 (1 << 0) #define OPT_UT107 (1 << 4) /* * CTCSS sub-audible tones for PCR100 and PCR1000 * Don't even touch a single bit! indexes will be used in the protocol! * 51 tones, the 60.0 Hz tone is missing. */ tone_t pcr_ctcss_list[] = { 670, 693, 710, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0, }; /* * DTCS SQL code list * Don't even touch a single bit! indexes will be used in the protocol! * 104 codes */ tone_t pcr_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0, }; struct pcr_country { int id; char *name; }; struct pcr_country pcr_countries[] = { { 0x00, "Japan" }, { 0x01, "USA" }, { 0x02, "EUR/AUS" }, { 0x03, "FRA" }, { 0x04, "DEN" }, { 0x05, "CAN" }, { 0x06, "Generic 1" }, { 0x07, "Generic 2" }, { 0x08, "FCC Japan" }, { 0x09, "FCC USA" }, { 0x0A, "FCC EUR/AUS" }, { 0x0B, "FCC FRA" }, { 0x0C, "FCC DEN" }, { 0x0D, "FCC CAN" }, { 0x0E, "FCC Generic 1" }, { 0x0F, "FCC Generic 2" }, }; static int pcr_set_volume(RIG *rig, vfo_t vfo, float level); static int pcr_set_squelch(RIG *rig, vfo_t vfo, float level); static int pcr_set_if_shift(RIG *rig, vfo_t vfo, int level); static int pcr_set_agc(RIG *rig, vfo_t vfo, int status); // J45xx static int pcr_set_afc(RIG *rig, vfo_t vfo, int status); // LD820xx static int pcr_set_nb(RIG *rig, vfo_t vfo, int status); // J46xx static int pcr_set_attenuator(RIG *rig, vfo_t vfo, int status); // J47xx static int pcr_set_anl(RIG *rig, vfo_t vfo, int status); // J4Dxx static int pcr_set_diversity(RIG *rig, vfo_t vfo, int status); // J00xx on PCR-2500 static int pcr_set_bfo_shift(RIG *rig, vfo_t vfo, int level); // J4Axx static int pcr_set_vsc(RIG *rig, vfo_t vfo, int level); // J50xx static int pcr_set_dsp(RIG *rig, vfo_t vfo, int level); // J80xx static int pcr_set_dsp_state(RIG *rig, vfo_t vfo, int level); // J8100=off J8101=on #if 1 /* unused; re-enabled as needed. */ static int pcr_set_dsp_noise_reducer(RIG *rig, vfo_t vfo, int level); // J82xx #endif /* unused */ static int pcr_set_dsp_auto_notch(RIG *rig, vfo_t vfo, int level); // J83xx static int pcr_check_ok(RIG *rig); static int is_sub_rcvr(RIG *rig, vfo_t vfo); #define PCR_COUNTRIES (sizeof(pcr_countries) / sizeof(struct pcr_country)) #define is_valid_answer(x) \ ((x) == 'I' || (x) == 'G' || (x) == 'N' || (x) == 'H') static int pcr_read_block(RIG *rig, char *rxbuffer, size_t count) { int read = 0, tries = 4; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); const struct pcr_priv_caps *caps = pcr_caps(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); /* already in sync? */ if (priv->sync && !caps->always_sync) { return read_block(rp, (unsigned char *) rxbuffer, count); } /* read first char */ do { char *p = &rxbuffer[0]; /* read first char */ int err = read_block(rp, (unsigned char *) p, 1); if (err < 0) { return err; } if (err != 1) { return -RIG_EPROTO; } /* validate */ if (*p != 0x0a && !is_valid_answer(*p)) { continue; } /* sync ok, read remaining chars */ read++; count--; p++; err = read_block(rp, (unsigned char *) p, count); if (err < 0) { rig_debug(RIG_DEBUG_ERR, "%s: read failed - %s\n", __func__, strerror(errno)); return err; } if (err == count) { read += err; priv->sync = 1; } rig_debug(RIG_DEBUG_TRACE, "%s: RX %d bytes\n", __func__, read); return read; } while (--tries > 0); return -RIG_EPROTO; } /* expects a 4 byte buffer to parse */ static int pcr_parse_answer(RIG *rig, char *buf, int len) { struct rig_state *rs = STATE(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: len = %d\n", __func__, len); if (len < 4) { priv->sync = 0; return -RIG_EPROTO; } if (strncmp("G000", buf, 4) == 0) { return RIG_OK; } if (strncmp("G001", buf, 4) == 0) { return -RIG_ERJCTED; } if (strncmp("H101", buf, 4) == 0) { return RIG_OK; } if (strncmp("H100", buf, 4) == 0) { return -RIG_ERJCTED; } if (buf[0] == 'I') { switch (buf[1]) { /* Main receiver */ case '0': sscanf(buf, "I0%02X", &priv->main_rcvr.squelch_status); return RIG_OK; case '1': sscanf(buf, "I1%02X", &priv->main_rcvr.raw_level); return RIG_OK; case '2': rig_debug(RIG_DEBUG_VERBOSE, "%s: Signal centering %c%c\n", __func__, buf[2], buf[3]); return RIG_OK; case '3': rig_debug(RIG_DEBUG_WARN, "%s: DTMF %c\n", __func__, buf[3]); return RIG_OK; /* Sub receiver (on PCR-2500..) - TBC */ case '4': sscanf(buf, "I4%02X", &priv->sub_rcvr.squelch_status); return RIG_OK; case '5': sscanf(buf, "I5%02X", &priv->sub_rcvr.raw_level); return RIG_OK; case '6': rig_debug(RIG_DEBUG_VERBOSE, "%s: Signal centering %c%c (Sub)\n", __func__, buf[2], buf[3]); return RIG_OK; case '7': rig_debug(RIG_DEBUG_WARN, "%s: DTMF %c (Sub)\n", __func__, buf[3]); return RIG_OK; } } else if (buf[0] == 'G') { switch (buf[1]) { case '2': /* G2 */ sscanf((char *) buf, "G2%d", &priv->protocol); return RIG_OK; case '4': /* G4 */ sscanf((char *) buf, "G4%d", &priv->firmware); return RIG_OK; case 'D': /* GD */ sscanf((char *) buf, "GD%d", &priv->options); return RIG_OK; case 'E': /* GE */ sscanf((char *) buf, "GE%d", &priv->country); return RIG_OK; } } priv->sync = 0; return -RIG_EPROTO; /* XXX bandscope */ } static int pcr_send(RIG *rig, const char *cmd) { int err; struct rig_state *rs = STATE(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; int len = strlen(cmd); rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s, len = %d\n", __func__, cmd, len); /* XXX check max len */ memcpy(priv->cmd_buf, cmd, len); /* append cr */ /* XXX not required in auto update mode? (should not harm) */ priv->cmd_buf[len + 0] = 0x0a; rs->transaction_active = 1; err = write_block(RIGPORT(rig), (unsigned char *) priv->cmd_buf, len + 1); rs->transaction_active = 0; return err; } static int pcr_transaction(RIG *rig, const char *cmd) { int err; struct rig_state *rs = STATE(rig); struct pcr_priv_caps *caps = pcr_caps(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s\n", __func__, cmd); if (!priv->auto_update) { rig_flush(RIGPORT(rig)); } pcr_send(rig, cmd); /* the pcr does not give ack in auto update mode */ if (priv->auto_update) { return RIG_OK; } err = pcr_read_block(rig, priv->reply_buf, caps->reply_size); if (err < 0) { rig_debug(RIG_DEBUG_ERR, "%s: read error, %s\n", __func__, strerror(errno)); return err; } if (err != caps->reply_size) { priv->sync = 0; return -RIG_EPROTO; } return pcr_parse_answer(rig, &priv->reply_buf[caps->reply_offset], err); } static int pcr_set_comm_speed(RIG *rig, int rate) { int err; const char *rate_cmd; /* limit maximum rate */ if (rate > 38400) { rate = 38400; } switch (rate) { case 300: rate_cmd = "G100"; break; case 1200: rate_cmd = "G101"; break; case 2400: rate_cmd = "G102"; break; case 9600: default: rate_cmd = "G103"; break; case 19200: rate_cmd = "G104"; break; case 38400: rate_cmd = "G105"; break; } rig_debug(RIG_DEBUG_VERBOSE, "%s: setting speed to %d with %s\n", __func__, rate, rate_cmd); /* the answer will be sent at the new baudrate, * so we do not use pcr_transaction */ err = pcr_send(rig, rate_cmd); if (err != RIG_OK) { return err; } RIGPORT(rig)->parm.serial.rate = rate; serial_setup(RIGPORT(rig)); /* check if the pcr is still alive */ return pcr_check_ok(rig); } /* Basically, it sets up *priv */ int pcr_init(RIG *rig) { struct pcr_priv_data *priv; if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct pcr_priv_data *) calloc(1, sizeof(struct pcr_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0x00, sizeof(struct pcr_priv_data)); /* * FIXME: how can we retrieve initial status? * The protocol doesn't allow this. */ /* Some values are already at zero due to the memset above, * but we reinitialize here for sake of completeness */ priv->country = -1; priv->sync = 0; priv->power = RIG_POWER_OFF; priv->main_rcvr.last_att = 0; priv->main_rcvr.last_agc = 0; priv->main_rcvr.last_ctcss_sql = 0; priv->main_rcvr.last_freq = MHz(145); priv->main_rcvr.last_mode = MD_FM; priv->main_rcvr.last_filter = FLT_15kHz; priv->main_rcvr.volume = 0.25; priv->main_rcvr.squelch = 0.00; priv->sub_rcvr = priv->main_rcvr; priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /* * PCR Generic pcr_cleanup routine * the serial port is closed by the frontend */ int pcr_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * pcr_open * - send power on * - set auto update off * * Assumes rig!=NULL */ int pcr_open(RIG *rig) { struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct pcr_priv_data *priv = (struct pcr_priv_data *) rs->priv; int err; int wanted_serial_rate; int startup_serial_rate; /* * initial communication is at 9600bps for PCR 100/1000 * once the power is on, the serial speed can be changed with G1xx */ if (rig->caps->rig_model == RIG_MODEL_PCR1500 || rig->caps->rig_model == RIG_MODEL_PCR2500) { startup_serial_rate = 38400; } else { startup_serial_rate = 9600; } wanted_serial_rate = rp->parm.serial.rate; rp->parm.serial.rate = startup_serial_rate; serial_setup(rp); /* let the pcr settle and flush any remaining data*/ hl_usleep(100 * 1000); rig_flush(rp); /* try powering on twice, sometimes the pcr answers H100 (off) */ pcr_send(rig, "H101"); hl_usleep(100 * 250); pcr_send(rig, "H101"); hl_usleep(100 * 250); rig_flush(rp); /* return RIG_ERJCTED if power is off */ err = pcr_transaction(rig, "H1?"); if (err != RIG_OK) { return err; } priv->power = RIG_POWER_ON; /* turn off auto update (just to be sure) */ err = pcr_transaction(rig, "G300"); if (err != RIG_OK) { return err; } /* set squelch and volume */ err = pcr_set_squelch(rig, RIG_VFO_MAIN, priv->main_rcvr.squelch); if (err != RIG_OK) { return err; } err = pcr_set_volume(rig, RIG_VFO_MAIN, priv->main_rcvr.volume); if (err != RIG_OK) { return err; } /* get device features */ pcr_get_info(rig); /* tune to last freq */ err = pcr_set_freq(rig, RIG_VFO_MAIN, priv->main_rcvr.last_freq); if (err != RIG_OK) { return err; } if ((STATE(rig)->vfo_list & RIG_VFO_SUB) == RIG_VFO_SUB) { err = pcr_set_squelch(rig, RIG_VFO_SUB, priv->sub_rcvr.squelch); if (err != RIG_OK) { return err; } err = pcr_set_volume(rig, RIG_VFO_SUB, priv->sub_rcvr.volume); if (err != RIG_OK) { return err; } err = pcr_set_freq(rig, RIG_VFO_SUB, priv->sub_rcvr.last_freq); if (err != RIG_OK) { return err; } pcr_set_vfo(rig, RIG_VFO_MAIN); } /* switch to different speed if requested */ if (wanted_serial_rate != startup_serial_rate && wanted_serial_rate >= 300) { return pcr_set_comm_speed(rig, wanted_serial_rate); } return RIG_OK; } /* * pcr_close - send power off * Assumes rig!=NULL */ int pcr_close(RIG *rig) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; /* when the pcr turns itself off sometimes we receive * a malformed answer, so don't check for it. */ priv->power = RIG_POWER_OFF; return pcr_send(rig, "H100"); } /* * pcr_set_vfo * * Only useful on PCR-2500 which is a double receiver. * Simply remember what the current VFO is for RIG_VFO_CURR. */ int pcr_set_vfo(RIG *rig, vfo_t vfo) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo = %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_MAIN: case RIG_VFO_SUB: break; default: return -RIG_EINVAL; } priv->current_vfo = vfo; return RIG_OK; } int pcr_get_vfo(RIG *rig, vfo_t *vfo) { const struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; *vfo = priv->current_vfo; return RIG_OK; } /* * pcr_set_freq * Assumes rig!=NULL * * K0GMMMKKKHHHmmff00 * GMMMKKKHHH is frequency GHz.MHz.KHz.Hz * mm is the mode setting * 00 = LSB * 01 = USB * 02 = AM * 03 = CW * 04 = Not used or Unknown * 05 = NFM * 06 = WFM * ff is the filter setting * 00 = 2.8 Khz (CW USB LSB AM) * 01 = 6.0 Khz (CW USB LSB AM NFM) * 02 = 15 Khz (AM NFM) * 03 = 50 Khz (AM NFM WFM) * 04 = 230 Khz (WFM) * */ int pcr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct pcr_priv_data *priv; struct pcr_rcvr *rcvr; unsigned char buf[20]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo = %s, freq = %.0f\n", __func__, rig_strvfo(vfo), freq); priv = (struct pcr_priv_data *) STATE(rig)->priv; rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; SNPRINTF((char *) buf, sizeof(buf), "K%c%010" PRIll "0%c0%c00", is_sub_rcvr(rig, vfo) ? '1' : '0', (int64_t) freq, rcvr->last_mode, rcvr->last_filter); err = pcr_transaction(rig, (char *) buf); if (err != RIG_OK) { return err; } rcvr->last_freq = freq; return RIG_OK; } /* * pcr_get_freq * frequency can't be read back, so report the last one that was set. * Assumes rig != NULL, freq != NULL */ int pcr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; *freq = rcvr->last_freq; return RIG_OK; } /* * pcr_set_mode * Assumes rig != NULL */ int pcr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; unsigned char buf[20]; int err; int pcrmode; rig_debug(RIG_DEBUG_VERBOSE, "%s: mode = %s, width = %d\n", __func__, rig_strrmode(mode), (int)width); /* XXX? */ if (mode == RIG_MODE_NONE) { mode = RIG_MODE_FM; } /* * not so sure about modes and filters * as I write this from manual (no testing) --SF */ switch (mode) { case RIG_MODE_CW: pcrmode = MD_CW; break; case RIG_MODE_USB: pcrmode = MD_USB; break; case RIG_MODE_LSB: pcrmode = MD_LSB; break; case RIG_MODE_AM: pcrmode = MD_AM; break; case RIG_MODE_WFM: pcrmode = MD_WFM; break; case RIG_MODE_FM: pcrmode = MD_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { int pcrfilter; if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } rig_debug(RIG_DEBUG_VERBOSE, "%s: will set to %d\n", __func__, (int)width); switch (width) { /* nop, pcrfilter already set * TODO: use rig_passband_normal instead? */ case s_kHz(2.8): pcrfilter = FLT_2_8kHz; break; case s_kHz(6): pcrfilter = FLT_6kHz; break; case s_kHz(15): pcrfilter = FLT_15kHz; break; case s_kHz(50): pcrfilter = FLT_50kHz; break; case s_kHz(230): pcrfilter = FLT_230kHz; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: filter set to %d (%c)\n", __func__, (int)width, pcrfilter); SNPRINTF((char *) buf, sizeof(buf), "K%c%010" PRIll "0%c0%c00", is_sub_rcvr(rig, vfo) ? '1' : '0', (int64_t) rcvr->last_freq, pcrmode, pcrfilter); err = pcr_transaction(rig, (char *) buf); if (err != RIG_OK) { return err; } rcvr->last_filter = pcrfilter; } else { SNPRINTF((char *) buf, sizeof(buf), "K%c%010" PRIll "0%c0%c00", is_sub_rcvr(rig, vfo) ? '1' : '0', (int64_t) rcvr->last_freq, pcrmode, rcvr->last_filter); err = pcr_transaction(rig, (char *) buf); if (err != RIG_OK) { return err; } } rcvr->last_mode = pcrmode; return RIG_OK; } /* * hack! pcr_get_mode * Assumes rig!=NULL, mode!=NULL */ int pcr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct pcr_priv_data *priv; struct pcr_rcvr *rcvr; priv = (struct pcr_priv_data *) STATE(rig)->priv; rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s, last_mode = %c, last_filter = %c\n", __func__, rcvr->last_mode, rcvr->last_filter); switch (rcvr->last_mode) { case MD_CW: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_WFM: *mode = RIG_MODE_WFM; break; case MD_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "pcr_get_mode: unsupported mode %d\n", rcvr->last_mode); return -RIG_EINVAL; } switch (rcvr->last_filter) { case FLT_2_8kHz: *width = kHz(2.8); break; case FLT_6kHz: *width = kHz(6); break; case FLT_15kHz: *width = kHz(15); break; case FLT_50kHz: *width = kHz(50); break; case FLT_230kHz: *width = kHz(230); break; default: rig_debug(RIG_DEBUG_ERR, "pcr_get_mode: unsupported " "width %d\n", rcvr->last_filter); return -RIG_EINVAL; } return RIG_OK; } /* * pcr_get_info * Assumes rig!=NULL */ const char * pcr_get_info(RIG *rig) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; char *country = NULL; pcr_transaction(rig, "G2?"); /* protocol */ pcr_transaction(rig, "G4?"); /* firmware */ pcr_transaction(rig, "GD?"); /* options */ pcr_transaction(rig, "GE?"); /* country */ /* translate country id to name */ if (priv->country > -1) { int i; for (i = 0; i < PCR_COUNTRIES; i++) { if (pcr_countries[i].id == priv->country) { country = pcr_countries[i].name; break; } } if (country == NULL) { country = "Unknown"; rig_debug(RIG_DEBUG_ERR, "%s: unknown country code %#x, " "please report to Hamlib maintainer\n", __func__, priv->country); } } else { country = "Not queried yet"; } SNPRINTF(priv->info, sizeof(priv->info), "Firmware v%d.%d, Protocol v%d.%d, " "Optional devices:%s%s%s, Country: %s", priv->firmware / 10, priv->firmware % 10, priv->protocol / 10, priv->protocol % 10, (priv->options & OPT_UT106) ? " DSP" : "", (priv->options & OPT_UT107) ? " DARC" : "", priv->options ? "" : " none", country); rig_debug(RIG_DEBUG_VERBOSE, "%s: Firmware v%d.%d, Protocol v%d.%d, " "Optional devices:%s%s%s, Country: %s\n", __func__, priv->firmware / 10, priv->firmware % 10, priv->protocol / 10, priv->protocol % 10, (priv->options & OPT_UT106) ? " DSP" : "", (priv->options & OPT_UT107) ? " DARC" : "", priv->options ? "" : " none", country); return priv->info; } /* *********************************************************************** */ /* load of new stuff added in by Darren Hatcher - G0WCW */ /* *********************************************************************** */ /* * pcr_set_level called by generic set level handler * * We are missing a way to set the BFO on/off here, */ int pcr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int err = -RIG_ENIMPL; if (RIG_LEVEL_IS_FLOAT(level)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: level = %s, val = %f\n", __func__, rig_strlevel(level), val.f); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: level = %s, val = %d\n", __func__, rig_strlevel(level), val.i); } switch (level) { case RIG_LEVEL_ATT: /* This is only on or off, but hamlib forces to use set level * and pass as a float. Here we'll use 0 for off and 1 for on. * If someone finds out how to set the ATT for the PCR in dB, let us * know and the function can be changed to allow a true set level. * * Experiment shows it seems to have an effect, but unsure by how many db */ return pcr_set_attenuator(rig, vfo, val.i); case RIG_LEVEL_IF: return pcr_set_if_shift(rig, vfo, val.i); case RIG_LEVEL_CWPITCH: /* BFO */ return pcr_set_bfo_shift(rig, vfo, val.i); case RIG_LEVEL_AGC: /* Only AGC on/off supported by PCR's */ return pcr_set_agc(rig, vfo, val.i == RIG_AGC_OFF ? 0 : 1); /* floats */ case RIG_LEVEL_AF: /* "val" can be 0.0 to 1.0 float which is 0 to 255 levels * 0.3 seems to be ok in terms of loudness */ return pcr_set_volume(rig, vfo, val.f); case RIG_LEVEL_SQL: /* "val" can be 0.0 to 1.0 float * .... rig supports 0 to FF - look at function for * squelch "bands" */ return pcr_set_squelch(rig, vfo, val.f); case RIG_LEVEL_NR: /* This selectss the DSP unit - this isn't a level per se, * but in the manual it says that we have to switch it on first * we'll assume 1 is for the UT-106, and anything else as off * * Later on we can set if the DSP features are on or off in set_func */ /* return pcr_set_dsp(rig, vfo, (int) val.f); */ return pcr_set_dsp_noise_reducer(rig, vfo, val.f); } return err; } /* * pcr_get_level * * This needs a set of stored variables as the PCR doesn't return the current status of settings. * So we'll need to store them as we go along and keep them in sync. */ int pcr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; // rig_debug(RIG_DEBUG_TRACE, "%s: level = %d\n", __func__, level); switch (level) { case RIG_LEVEL_SQL: val->f = rcvr->squelch; return RIG_OK; case RIG_LEVEL_AF: val->f = rcvr->volume; return RIG_OK; case RIG_LEVEL_STRENGTH: if (priv->auto_update == 0) { err = pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "I5?" : "I1?"); if (err != RIG_OK) { return err; } } val->i = rig_raw2val(rcvr->raw_level, &STATE(rig)->str_cal); /* rig_debug(RIG_DEBUG_TRACE, "%s, raw = %d, converted = %d\n", __func__, rcvr->raw_level, val->i); */ return RIG_OK; case RIG_LEVEL_RAWSTR: if (priv->auto_update == 0) { err = pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "I5?" : "I1?"); if (err != RIG_OK) { return err; } } val->i = rcvr->raw_level; return RIG_OK; case RIG_LEVEL_IF: val->i = rcvr->last_shift; return RIG_OK; case RIG_LEVEL_ATT: val->i = rcvr->last_att; return RIG_OK; case RIG_LEVEL_AGC: val->i = rcvr->last_agc; return RIG_OK; } return -RIG_ENIMPL; } /* * pcr_set_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * This is missing a way to call the set DSP noise reducer, as we don't have a func to call it * based on the flags in rig.h -> see also missing a flag for setting the BFO. */ int pcr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d, func = %s\n", __func__, status, rig_strfunc(func)); switch (func) { case RIG_FUNC_NR: /* sets DSP noise reduction on or off */ /* status = 00 for off or 01 for on * always enable the DSP unit * even if only to turn it off */ if (status == 1) { pcr_set_dsp(rig, vfo, 1); return pcr_set_dsp_state(rig, vfo, 1); } else { pcr_set_dsp(rig, vfo, 1); return pcr_set_dsp_state(rig, vfo, 0); } break; case RIG_FUNC_ANF: /* DSP auto notch filter */ if (status == 1) { return pcr_set_dsp_auto_notch(rig, vfo, 1); } else { return pcr_set_dsp_auto_notch(rig, vfo, 0); } break; case RIG_FUNC_NB: /* noise blanker */ if (status == 0) { return pcr_set_nb(rig, vfo, 0); } else { return pcr_set_nb(rig, vfo, 1); } break; case RIG_FUNC_AFC: /* Tracking Filter */ if (status == 0) { return pcr_set_afc(rig, vfo, 0); } else { return pcr_set_afc(rig, vfo, 1); } break; case RIG_FUNC_TSQL: if (rcvr->last_mode != MD_FM) { return -RIG_ERJCTED; } if (status == 0) { return pcr_set_ctcss_sql(rig, vfo, 0); } else { return pcr_set_ctcss_sql(rig, vfo, rcvr->last_ctcss_sql); } case RIG_FUNC_VSC: /* Voice Scan Control */ if (status == 0) { return pcr_set_vsc(rig, vfo, 0); } else { return pcr_set_vsc(rig, vfo, 1); } break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: default\n", __func__); return -RIG_EINVAL; } } /* * pcr_get_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * This will need similar variables/flags as get_level. The PCR doesn't offer much in the way of * confirmation of current settings (according to the docs). */ int pcr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { /* stub here ... */ return -RIG_ENIMPL; } int pcr_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tok = %s\n", __func__, rig_strlevel(token)); switch (token) { case TOK_EL_ANL: /* automatic noise limiter */ return pcr_set_anl(rig, vfo, (0 == val.i) ? 0 : 1); case TOK_EL_DIVERSITY: /* antenna diversity */ return pcr_set_diversity(rig, vfo, (0 == val.i) ? 0 : 2); default: rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown token: %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } return RIG_OK; } /* --------------------------------------------------------------------------------------- */ /* The next functions are all "helper types". These are called by the base functions above */ /* --------------------------------------------------------------------------------------- */ /* * Asks if the rig is ok = G0? response is G000 if ok or G001 if not * * Is only useful in fast transfer mode (when the CR/LF is stripped off all commands) ... * but also works on standard mode. */ static int pcr_check_ok(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); return pcr_transaction(rig, "G0?"); } static int is_sub_rcvr(RIG *rig, vfo_t vfo) { const struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; return vfo == RIG_VFO_SUB || (vfo == RIG_VFO_CURR && priv->current_vfo == RIG_VFO_SUB); } static int pcr_set_level_cmd(RIG *rig, const char *base, int level) { char buf[12]; rig_debug(RIG_DEBUG_TRACE, "%s: base is %s, level is %d\n", __func__, base, level); if (level < 0x0) { rig_debug(RIG_DEBUG_ERR, "%s: too low: %d\n", __func__, level); return -RIG_EINVAL; } else if (level > 0xff) { rig_debug(RIG_DEBUG_ERR, "%s: too high: %d\n", __func__, level); return -RIG_EINVAL; } SNPRINTF(buf, 12, "%s%02X", base, level); buf[11] = '\0'; return pcr_transaction(rig, buf); } /* * Sets the volume of the rig to the level specified in the level integer. * Format is J40xx - where xx is 00 to FF in hex, and specifies 255 volume levels */ static int pcr_set_volume(RIG *rig, vfo_t vfo, float level) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_TRACE, "%s: level = %f\n", __func__, level); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J60" : "J40", level * 0xff); if (err == RIG_OK) { rcvr->volume = level; } return err; } /* * pcr_set_squelch * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Format is J41xx - where xx is 00 to FF in hex, and specifies 255 squelch levels * * Sets the squelch of the rig to the level specified in the level integer. * There are some bands though ... * 00 Tone squelch clear and squelch open * 01-3f Squelch open * 40-7f Noise squelch * 80-ff Noise squelch + S meter squelch ... * Comparative S level = (squelch setting - 128) X 2 * * Could do with some constants to add together to allow better (and more accurate) * use of Hamlib API. Otherwise may get unexpected squelch settings if have to do by hand. */ static int pcr_set_squelch(RIG *rig, vfo_t vfo, float level) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_TRACE, "%s: level = %f\n", __func__, level); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J61" : "J41", level * 0xff); if (err == RIG_OK) { rcvr->squelch = level; } return err; } /* * pcr_set_if_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the IF shift of the rig to the level specified in the level integer. * IF-SHIFT position (in 256 stages, 80 = centre): * * < 80 Minus shift (in 10 Hz steps) * > 80 Plus shift (in 10 Hz steps) * 80 Centre * * Format is J43xx - where xx is 00 to FF in hex * */ int pcr_set_if_shift(RIG *rig, vfo_t vfo, int level) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J63" : "J43", (level / 10) + 0x80); if (err == RIG_OK) { rcvr->last_shift = level; } return err; } /* * pcr_set_agc * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the AGC on or off based on the level specified in the level integer. * 00 = off, 01 (non zero) is on * * Format is J45xx - where xx is 00 to 01 in hex * */ int pcr_set_agc(RIG *rig, vfo_t vfo, int status) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J65" : "J45", status ? 1 : 0); if (err == RIG_OK) { rcvr->last_agc = status ? 1 : 0; } return err; } /* * pcr_set_afc(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the Tracking Filter on or off based on the status argument. * 00 = on, 01 (non zero) is off * * Format is LD820xx - where xx is 00 to ff in hex * */ int pcr_set_afc(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); return pcr_set_level_cmd(rig, "LD820", status ? 0 : 1); } /* * pcr_set_nb(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the noise blanker on or off based on the level specified in the level integer. * 00 = off, 01 (non zero) is on * * Format is J46xx - where xx is 00 to 01 in hex * */ int pcr_set_nb(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); return pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J66" : "J46", status ? 1 : 0); } /* Automatic Noise Limiter - J4Dxx - 00 off, 01 on */ int pcr_set_anl(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); return pcr_set_level_cmd(rig, "J4D", status ? 1 : 0); } /* Antenna Diversity/Tuners - J00xx - * 02=Dual Diversity ON, 1 display using 2 tuners * 01=Single Diversity OFF, 1 display using 1 tuner * 00=OFF Diversity OFF, 2 displays using 2 tuners */ int pcr_set_diversity(RIG *rig, vfo_t vfo, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); if (status < 0 || status > 2) { return -RIG_EINVAL; } return pcr_set_level_cmd(rig, "J00", status); } /* * pcr_set_attenuator(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the attenuator on or off based on the level specified in the level integer. * 00 = off, 01 (non zero) is on * The attenuator seems to be fixed at ~ -20dB * * Format is J47xx - where xx is 00 to 01 in hex * */ int pcr_set_attenuator(RIG *rig, vfo_t vfo, int status) { int err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: status = %d\n", __func__, status); err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J67" : "J47", status ? 1 : 0); if (err == RIG_OK) { rcvr->last_att = status; } return err; } /* * pcr_set_bfo_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the BFO of the rig to the level specified in the level integer. * BFO-SHIFT position (in 256 stages, 80 = centre): * * < 80 Minus shift (in 10 Hz steps) * > 80 Plus shift (in 10 Hz steps) * 80 Centre * * Format is J4Axx - where xx is 00 to FF in hex, and specifies 255 levels * XXX command undocumented? */ int pcr_set_bfo_shift(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); return pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J6A" : "J4A", 0x80 + level / 10); } /* * pcr_set_dsp(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the DSP to UT106 (01) or off (non 01) * */ int pcr_set_dsp(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J80", level); } /* * pcr_set_dsp_state(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the DSP on or off (> 0 = on, 0 = off) * */ int pcr_set_dsp_state(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J81", level); } /* * pcr_set_dsp_noise_reducer(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the DSP noise reducer on or off (0x01 = on, 0x00 = off) * the level of NR set by values 0x01 to 0x10 (1 to 16 inclusive) */ #if 1 /* unused; re-enabled as needed. */ int pcr_set_dsp_noise_reducer(RIG *rig, vfo_t vfo, int level) { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, level); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J82", level); } #endif /* unused */ /* * pcr_set_dsp_auto_notch(RIG *rig, vfo_t vfo, int level); * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Sets the auto notch on or off (1 = on, 0 = off) */ int pcr_set_dsp_auto_notch(RIG *rig, vfo_t vfo, int status) // J83xx { rig_debug(RIG_DEBUG_TRACE, "%s: level is %d\n", __func__, status); if (is_sub_rcvr(rig, vfo)) { return -RIG_ENAVAIL; } return pcr_set_level_cmd(rig, "J83", status ? 1 : 0); } int pcr_set_vsc(RIG *rig, vfo_t vfo, int status) // J50xx { /* Not sure what VSC for so skipping the function here ... */ return pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J70" : "J50", status ? 1 : 0); } int pcr_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; *tone = rcvr->last_ctcss_sql; return RIG_OK; } int pcr_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int i, err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: tone = %u\n", __func__, tone); if (tone == 0) { return pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "J7100" : "J5100"); } for (i = 0; rig->caps->ctcss_list[i] != 0; i++) { if (rig->caps->ctcss_list[i] == tone) { break; } } rig_debug(RIG_DEBUG_TRACE, "%s: index = %d, tone = %u\n", __func__, i, rig->caps->ctcss_list[i]); if (rig->caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J71" : "J51", i + 1); if (err == RIG_OK) { rcvr->last_ctcss_sql = tone; } return RIG_OK; } int pcr_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; *tone = rcvr->last_dcs_sql; return RIG_OK; } int pcr_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t tone) { int i, err; struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; rig_debug(RIG_DEBUG_VERBOSE, "%s: tone = %u\n", __func__, tone); if (tone == 0) { return pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "J720000" : "J520000"); } for (i = 0; rig->caps->dcs_list[i] != 0; i++) { if (rig->caps->dcs_list[i] == tone) { break; } } rig_debug(RIG_DEBUG_TRACE, "%s: index = %d, tone = %u\n", __func__, i, rig->caps->dcs_list[i]); if (rig->caps->dcs_list[i] != tone) { return -RIG_EINVAL; } err = pcr_set_level_cmd(rig, is_sub_rcvr(rig, vfo) ? "J7200" : "J5200", i + 1); if (err == RIG_OK) { rcvr->last_dcs_sql = tone; } return RIG_OK; } int pcr_set_trn(RIG *rig, int trn) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: trn = %d\n", __func__, trn); if (trn == RIG_TRN_OFF) { priv->auto_update = 0; return pcr_transaction(rig, "G300"); } else if (trn == RIG_TRN_RIG) { priv->auto_update = 1; return pcr_send(rig, "G301"); } else { return -RIG_EINVAL; } } int pcr_decode_event(RIG *rig) { int err; char buf[4]; /* XXX check this */ err = pcr_read_block(rig, buf, 4); if (err == 4) { return pcr_parse_answer(rig, buf, 4); } return RIG_OK; } int pcr_set_powerstat(RIG *rig, powerstat_t status) { const struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; if (status == priv->power) { return RIG_OK; } if (status == RIG_POWER_ON) { return pcr_open(rig); } else if (status == RIG_POWER_OFF) { return pcr_close(rig); } return -RIG_ENIMPL; } int pcr_get_powerstat(RIG *rig, powerstat_t *status) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; int err; /* return RIG_ERJCTED if power is off */ err = pcr_transaction(rig, "H1?"); if (err != RIG_OK && err != -RIG_ERJCTED) { return err; } priv->power = err == RIG_OK ? RIG_POWER_ON : RIG_POWER_OFF; *status = priv->power; return RIG_OK; } int pcr_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct pcr_priv_data *priv = (struct pcr_priv_data *) STATE(rig)->priv; const struct pcr_rcvr *rcvr = is_sub_rcvr(rig, vfo) ? &priv->sub_rcvr : &priv->main_rcvr; if (priv->auto_update == 0) { int err = pcr_transaction(rig, is_sub_rcvr(rig, vfo) ? "I4?" : "I0?"); if (err != RIG_OK) { return err; } } /* 04 = Closed, 07 = Open * * Bit 0: busy * Bit 1: AF open (CTCSS open) * Bit 2: VSC open * Bit 3: RX error (not ready to receive) */ *dcd = (rcvr->squelch_status & 0x02) ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } /* ********************************************************************************************* * int pcr_set_comm_mode(RIG *rig, int mode_type); // Set radio to fast/diagnostic mode G3xx * int pcr_soft_reset(RIG *rig); // Ask rig to reset itself H0xx ********************************************************************************************* */ DECLARE_INITRIG_BACKEND(pcr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: init called\n", __func__); rig_register(&pcr100_caps); rig_register(&pcr1000_caps); rig_register(&pcr1500_caps); rig_register(&pcr2500_caps); return RIG_OK; } hamlib-4.6.2/rigs/pcr/pcr.h0000644000175000017500000000677614752216205012411 00000000000000/* * Hamlib PCR backend - main header * Copyright (c) 2001-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _PCR_H #define _PCR_H 1 #include "hamlib/rig.h" #include "token.h" /* ext_level's tokens */ #define TOK_EL_ANL TOKEN_BACKEND(1) #define TOK_EL_DIVERSITY TOKEN_BACKEND(2) #define BACKEND_VER "20200323" #define PCR_MAX_CMD_LEN 32 struct pcr_priv_data { struct pcr_rcvr { freq_t last_freq; int last_mode; int last_filter; int last_shift; int last_att; int last_agc; tone_t last_ctcss_sql; tone_t last_dcs_sql; float volume; float squelch; unsigned int raw_level; unsigned int squelch_status; } main_rcvr, sub_rcvr; vfo_t current_vfo; int auto_update; char info[100]; char cmd_buf[PCR_MAX_CMD_LEN]; char reply_buf[PCR_MAX_CMD_LEN]; int protocol; int firmware; int country; int options; int sync; powerstat_t power; }; struct pcr_priv_caps { unsigned int reply_size; unsigned int reply_offset; unsigned int always_sync; }; #define pcr_caps(rig) ((struct pcr_priv_caps *)(rig)->caps->priv) extern tone_t pcr_ctcss_list[]; extern tone_t pcr_dcs_list[]; int pcr_init(RIG *rig); int pcr_cleanup(RIG *rig); int pcr_open(RIG *rig); int pcr_close(RIG *rig); int pcr_set_vfo(RIG * rig, vfo_t vfo); int pcr_get_vfo(RIG * rig, vfo_t *vfo); int pcr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int pcr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int pcr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int pcr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); const char *pcr_get_info(RIG *rig); /* Added - G0WCW */ int pcr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int pcr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int pcr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int pcr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int pcr_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int pcr_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int pcr_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int pcr_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *tone); int pcr_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t tone); int pcr_set_trn(RIG * rig, int trn); int pcr_decode_event(RIG *rig); int pcr_set_powerstat(RIG * rig, powerstat_t status); int pcr_get_powerstat(RIG * rig, powerstat_t *status); int pcr_get_dcd(RIG * rig, vfo_t vfo, dcd_t *dcd); /* ------------------------------------------------------------------ */ // int pcr_get_param(RIG *rig, setting_t parm, value_t *val); // int pcr_set_param(RIG *rig, setting_t parm, value_t *val); extern struct rig_caps pcr1000_caps; extern struct rig_caps pcr100_caps; extern struct rig_caps pcr1500_caps; extern struct rig_caps pcr2500_caps; #endif /* _PCR_H */ hamlib-4.6.2/rigs/pcr/pcr100.c0000644000175000017500000001232014752216205012603 00000000000000/* * Hamlib PCR backend - PCR-100 description * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR100_MODES ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM ) #define PCR100_FUNC ( RIG_FUNC_TSQL ) #define PCR100_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR ) static const struct confparams pcr_ext_levels[] = { { TOK_EL_ANL, "ANL", "Auto Noise Limiter", "Auto Noise Limiter", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; static const struct pcr_priv_caps pcr100_priv = { .reply_size = 6, .reply_offset = 0, .always_sync = 0, }; /* * IC PCR100 rigs capabilities. */ struct rig_caps pcr100_caps = { RIG_MODEL(RIG_MODEL_PCR100), .model_name = "IC-PCR100", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* slower speeds gave troubles */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 12, .post_write_delay = 2, .timeout = 400, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = PCR100_FUNC, .has_get_level = PCR100_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR100_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = { }, .ctcss_list = pcr_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(10), GHz(1.3), PCR100_MODES, -1, -1, RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(10), MHz(824) - 10, PCR100_MODES, -1, -1, RIG_VFO_A }, { MHz(849) + 10, MHz(869) - 10, PCR100_MODES, -1, -1, RIG_VFO_A }, { MHz(894) + 10, GHz(1.3), PCR100_MODES, -1, -1, RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR100_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! * first one is the default mode, the one given back * by rig_mode_normal(), the others must be sorted. */ .filters = { { RIG_MODE_AM | RIG_MODE_FM, kHz(15) }, { RIG_MODE_AM, kHz(2.8) }, { RIG_MODE_AM | RIG_MODE_FM, kHz(6) }, { RIG_MODE_AM | RIG_MODE_FM, kHz(50) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM, kHz(50) }, RIG_FLT_END, }, .priv = (void *)& pcr100_priv, /* XXX verify */ .str_cal = { 7, { { 0, -60 }, { 160, 0 }, { 176, 20 }, { 192, 30 }, { 208, 40 }, { 224, 50 }, { 240, 60 }, } }, .extlevels = pcr_ext_levels, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ext_level = pcr_set_ext_level, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/pcr/pcr2500.c0000644000175000017500000001415714752216205012703 00000000000000/* * Hamlib PCR backend - PCR-2500 description * Copyright (c) 2001-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "pcr.h" #include "idx_builtin.h" #define PCR2500_MODES_WIDE ( RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM ) #define PCR2500_MODES_NAR ( RIG_MODE_CW | RIG_MODE_SSB ) #define PCR2500_MODES ( PCR2500_MODES_NAR | PCR2500_MODES_WIDE ) #define PCR2500_FUNC ( RIG_FUNC_NB | RIG_FUNC_TSQL | RIG_FUNC_NB | \ RIG_FUNC_ANF | RIG_FUNC_NR | RIG_FUNC_AFC ) #define PCR2500_LEVEL ( \ RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_SQL | RIG_LEVEL_IF | \ RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | \ RIG_LEVEL_NR ) static const struct confparams pcr2500_ext_levels[] = { { TOK_EL_DIVERSITY, "DIV", "Diversity", "Antenna/tuner diversity", NULL, RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; static const struct pcr_priv_caps pcr2500_priv = { .reply_size = 6, .reply_offset = 0, .always_sync = 0, }; /* * IC PCR2500 rigs capabilities. */ struct rig_caps pcr2500_caps = { RIG_MODEL(RIG_MODEL_PCR2500), .model_name = "IC-PCR2500", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, /* lower speeds gave troubles */ .serial_rate_max = 38400, .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 = 400, .retry = 3, .has_get_func = PCR2500_FUNC, .has_set_func = PCR2500_FUNC, .has_get_level = PCR2500_LEVEL, .has_set_level = RIG_LEVEL_SET(PCR2500_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* XXX check this */ [LVL_IF] = { .min = { .i = -1270 }, .max = { .i = 1270 }, .step = { .i = 10 } }, }, .parm_gran = {}, .ctcss_list = pcr_ctcss_list, .dcs_list = pcr_dcs_list, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { { kHz(100), GHz(1.3), PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { kHz(10), GHz(3.3) - kHz(1), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(50), GHz(1.3), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_SUB, RIG_ANT_2 }, RIG_FRNG_END }, .tx_range_list1 = { RIG_FRNG_END }, .rx_range_list2 = { { kHz(495), MHz(824) - 10, PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(849) + 10, MHz(869) - 10, PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(894) + 10, GHz(1.3), PCR2500_MODES_NAR, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { kHz(10), MHz(824) - 10, PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(849) + 10, MHz(869) - 10, PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(894) + 10, GHz(3.3) - kHz(1), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_MAIN, RIG_ANT_1 }, { MHz(50), GHz(1.3), PCR2500_MODES_WIDE, -1, -1, RIG_VFO_SUB, RIG_ANT_2 }, RIG_FRNG_END }, .tx_range_list2 = { RIG_FRNG_END }, /* no TX ranges, this is a receiver */ .tuning_steps = { { PCR2500_MODES, Hz(1) }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_FM | RIG_MODE_AM, kHz(15) }, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM, kHz(2.8)}, { RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_AM | RIG_MODE_FM, kHz(6) }, { RIG_MODE_WFM, kHz(230) }, { RIG_MODE_WFM | RIG_MODE_FM | RIG_MODE_AM, kHz(50) }, RIG_FLT_END, }, .extlevels = pcr2500_ext_levels, .priv = (void *)& pcr2500_priv, /* XXX fake */ .str_cal = { 3, { { 0, -60 }, { 127, 0 }, { 255, 60 } } }, .rig_init = pcr_init, .rig_cleanup = pcr_cleanup, .rig_open = pcr_open, .rig_close = pcr_close, .set_vfo = pcr_set_vfo, .get_vfo = pcr_get_vfo, .set_freq = pcr_set_freq, .get_freq = pcr_get_freq, .set_mode = pcr_set_mode, .get_mode = pcr_get_mode, .get_info = pcr_get_info, .set_level = pcr_set_level, .get_level = pcr_get_level, .set_ext_level = pcr_set_ext_level, .set_func = pcr_set_func, .get_func = pcr_get_func, .set_ctcss_sql = pcr_set_ctcss_sql, .get_ctcss_sql = pcr_get_ctcss_sql, .set_dcs_sql = pcr_set_dcs_sql, .get_dcs_sql = pcr_get_dcs_sql, .set_trn = pcr_set_trn, .decode_event = pcr_decode_event, .get_dcd = pcr_get_dcd, .set_powerstat = pcr_set_powerstat, .get_powerstat = pcr_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/aor/0000755000175000017500000000000014752216242011512 500000000000000hamlib-4.6.2/rigs/aor/ar8600.c0000644000175000017500000001433014752216205012516 00000000000000/* * Hamlib AOR backend - AR8600 description * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "aor.h" #define AR8600_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR8600_FUNC (RIG_FUNC_TSQL|RIG_FUNC_ABM|RIG_FUNC_AFC) #define AR8600_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define AR8600_PARM (RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define AR8600_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN|RIG_OP_LEFT|RIG_OP_RIGHT) #define AR8600_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR8600_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Measurement by Mark, WAØTOP, * using a HP8640B signal generator on an AR8600 Mark 2 (sn. 551454). * The mode was AM. The ATT was off. */ #define AR8600_STR_CAL { 12, \ { \ { 0, -54 }, /* 1st point is extrapolated */ \ { 13, -27 }, /* S-pixels: none */ \ { 29, -17 }, \ { 41, - 7 }, \ { 49, 3 }, /* S-pixels: 21 */ \ { 54, 13 }, \ { 59, 23 }, \ { 62, 33 }, /* S-pixels: 30 */ \ { 64, 43 }, \ { 65, 53 }, \ { 68, 63 }, \ { 69, 73 } /* S-pixels: 36 */ \ } } #define AR8600_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT, \ .funcs = RIG_FUNC_ABM, \ } static const struct aor_priv_caps ar8600_priv_caps = { .format_mode = format8k_mode, .parse_aor_mode = parse8k_aor_mode, .bank_base1 = 'A', .bank_base2 = 'a', }; /* * ar8600 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/8600.htm */ struct rig_caps ar8600_caps = { RIG_MODEL(RIG_MODEL_AR8600), .model_name = "AR8600", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR8600_FUNC, .has_get_level = AR8600_LEVEL, .has_set_level = RIG_LEVEL_SET(AR8600_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 20, /* A through J, and a through j */ .chan_desc_sz = 12, .vfo_ops = AR8600_VFO_OPS, .scan_ops = AR8600_SCAN_OPS, .str_cal = AR8600_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR8600_MEM_CAP }, /* flat space */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(2040), AR8600_MODES, -1, -1, AR8600_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(2040), AR8600_MODES, -1, -1, AR8600_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR8600_MODES, 50}, {AR8600_MODES, 100}, {AR8600_MODES, kHz(1)}, {AR8600_MODES, kHz(5)}, {AR8600_MODES, kHz(9)}, {AR8600_MODES, kHz(10)}, {AR8600_MODES, 12500}, {AR8600_MODES, kHz(20)}, {AR8600_MODES, kHz(25)}, {AR8600_MODES, kHz(100)}, {AR8600_MODES, MHz(1)}, #if 0 {AR8600_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(3)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM, kHz(9)}, {RIG_MODE_WFM, kHz(230)}, /* 150kHz at -3dB, 380kHz at -20dB */ RIG_FLT_END, }, .priv = (void *)& ar8600_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/aor/ar7030p.h0000644000175000017500000016041214752216205012702 00000000000000/* * Hamlib AOR backend - AR7030 Plus description * Copyright (c) 2000-2010 by Stephane Fillod & Fritz Melchert * Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AR7030P_H #define _AR7030P_H 1 #include "hamlib/rig.h" #include "token.h" /* AR-7030 Computer remote control protocol. Information for firmware releases 1.1A, 1.2A, 1.4A and 1.4B 1) Remote control overview. The AR-7030 receiver allows remote control of all of its functions by means of a direct memory access system. A controlling computer can read and modify the internal memory maps of the receiver to set required parameters and then call for the receiver's control program to process the new settings. Commands to the receiver are byte structured in binary format, so it is not possible to control from a terminal. All multi-byte numbers within the receiver are binary, stored MSB first. 2) Receiver frequency configuration. Receive frequency is set by two oscillators - local and carrier. In AM and FM modes the carrier oscillator is not used, and the final IF frequency is 455 kHz. In Sync mode the carrier oscillator is offset by +20.29kHz before mixing with the IF. The IF frequencies have a fixed inter-conversion frequency of 44.545MHz and, because of the high-side local oscillator, both IF's are inverted. The receiver controller processes the following variables to establish the tuned frequency :- [local offset] Frequency shift applied to local oscillator. [carrier offset] 455.00kHz for LSB, USB, Data and CW modes / 434.71kHz for Sync mode. [filter offset] IF Filter frequency at the (vestigial) carrier position as an offset from 455kHz. [PBS] User set filter shift. [BFO] User set offset between carrier position and frequency display. [TUNE] Receiver tuned frequency as shown on display. The relationship between these variables and the tuning is as follows :- [carrier offset] + [filter offset] + [PBS] + [BFO] ==> Carrier oscillator 45.000MHz + [filter offset] + [PBS] ==> [local offset] [TUNE] + [local offset] ==> Local oscillator 3) Serial data protocol. All data transfers are at 1200 baud, No parity, 8 bits, 1 stop bit (1200 N 8 1). There is no hardware or software flow control other than that inherent in the command structure. The receiver can accept data at any time at full rate provided the IR remote controller is not used or is disabled. A maximum of one byte can be transmitted for each byte received, so data flow into a controlling computer is appropriately limited. Each byte sent to the receiver is a complete command - it is best thought of as two hexadecimal digits - the first digit is the operation code, the second digit is 4-bits of data relating to the operation. Because the receiver operates with 8-bit bytes, intermediate 4-bit values are stored in registers in the receiver for recombination and processing. For example to write into the receiver's memory, the following steps would be followed:- a) Send address high order 4-bits into H-register b) Send address low order 4-bits and set Address register c) Send first data byte high order 4-bits into H-register d) Send first data byte low order 4-bits and execute Write Data Operation e) Send second data byte high order 4-bits into H-register f) Send second data byte low order 4-bits and execute Write Data Operation g) Repeat (e) and (f) for each subsequent byte to be written. 4) Memory organisation. Different memory areas in the receiver are referenced by selecting Pages - up to 16 pages are supported. The memory is broadly divided into 3 sections :- a) Working memory - where all current operating variables are stored and registers and stack are located. This memory is volatile and data is lost when power to the receiver is removed. b) Battery sustained memory - where duplicate parameters are stored for retention when power is removed. This memory area is also used for storage of filter parameters, setup memories and squelch and BFO settings for the frequency memories and contains the real time clock registers. c) EEPROM - where frequency, mode, filter and PBS information for the frequency memories is stored. Additionally S-meter and IF calibration values are stored here. This memory can be read or written to download and upload the receiver's frequency memories, but repetitive writing should be avoided because the memory devices will only support a finite number of write cycles. 5) Variations between A and B types and firmware revisions. Type A firmware supports only basic receiver functions, type B extends operations and includes support for the Notch / Noise Blanker option. The whole of the type A memory map is retained in type B, but more memory and operations are added for the extended functions of type B. In the following information, circled note numbers are included to indicate where items are specific to one type or revision of the firmware:- <1> Applicable to type B firmware only. <2> Applicable to revision 1.4 only, types A and B <3> Function is changed or added to in type B 6) Operation codes. The high order 4-bits of each byte sent to the receiver is the operation code, the low order 4-bits is data (shown here as x) :- Code Ident Operation 0x NOP No Operation 3x SRH Set H-register x => H-register (4-bits) 5x PGE Set page x => Page register (4-bits) 4x ADR Set address 0Hx => Address register (12-bits) 0 => H-register 1x ADH Set address high x => Address register (high 4-bits) 6x WRD Write data Hx => [Page, Address] Address register + 1 => Address register 0 => H-register, 0 => Mask register 9x MSK <1> Set mask Hx => Mask register 0 => H-register 2x EXE Execute routine x Ax BUT <1> Operate button x 7x RDD Read data [Page, Address] => Serial output Address register + x => Address register 8x LOC Set lock level x */ #if 1 #define NOP(x) (unsigned char) ( 0x00 | ( 0x0f & (x) ) ) #define SRH(x) (unsigned char) ( 0x30 | ( 0x0f & (x) ) ) #define PGE(x) (unsigned char) ( 0x50 | ( 0x0f & (x) ) ) #define ADR(x) (unsigned char) ( 0x40 | ( 0x0f & (x) ) ) #define ADH(x) (unsigned char) ( 0x10 | ( 0x0f & (x) ) ) #define WRD(x) (unsigned char) ( 0x60 | ( 0x0f & (x) ) ) #define MSK(x) (unsigned char) ( 0x90 | ( 0x0f & (x) ) ) #define EXE(x) (unsigned char) ( 0x20 | ( 0x0f & (x) ) ) #define BUT(x) (unsigned char) ( 0xa0 | ( 0x0f & (x) ) ) #define RDD(x) (unsigned char) ( 0x70 | ( 0x0f & (x) ) ) #define LOC(x) (unsigned char) ( 0x80 | ( 0x0f & (x) ) ) #endif // 0 enum OPCODE_e { op_NOP = 0x00, op_SRH = 0x30, op_PGE = 0x50, op_ADR = 0x40, op_ADH = 0x10, op_WRD = 0x60, op_MSK = 0x90, op_EXE = 0x20, op_BUT = 0xa0, op_RDD = 0x70, op_LOC = 0x80 }; /* Note that the H-register is zeroed after use, and that the high order 4-bits of the Address register must be set (if non-zero) after the low order 8-bits. The Address register is automatically incremented by one after a write data operation and by x after a read data operation. When writing to any of the EEPROM memory pages a time of 10ms per byte has to be allowed. For this reason it is recommended that instructions SRH and WRD are always used together (even if the SRH is not needed) since this will ensure that the EEPROM has sufficient time to complete its write cycle. Additionally to allow time for local receiver memory updates and SNC detector sampling in addition to the EEPROM write cycle, it is recommended to lock the receiver to level 2 or 3, or add a NOP instruction after each write. This is not required for firmware revision 1.4 but locking is still recommended. The mask operation helps with locations in memory that are shared by two parameters and aids setting and clearing bits. The mask operates only in Page 0. If bits in the mask are set, then a following write operation will leave the corresponding bits unchanged. The mask register is cleared after a write so that subsequent writes are processed normally. Because it defaults to zero at reset, the mask is inoperative unless specifically set. The operate button instruction uses the same button codes as are returned from routine 15 (see section 8), with an additional code of zero which operates the power button, but will not switch the receiver off. Also code 0 will switch the receiver on (from standby state). 7) Memory pages. Page 0 Working memory (RAM) 256 bytes. Page 1 Battery sustained memory (RAM) 256 bytes. Page 2 Non-volatile memory (EEPROM) 512 bytes. Page 3 <1> Non-volatile memory (EEPROM) 4096 bytes. Page 4 <1> Non-volatile memory (EEPROM) 4096 bytes. Pages 5 - 14 Not assigned. Page 15 Receiver Ident (ROM) 8 bytes. */ enum PAGE_e { NONE = -1, WORKING = 0, BBRAM = 1, EEPROM1 = 2, EEPROM2 = 3, EEPROM3 = 4, ROM = 15 }; /* The ident is divided into model number (5 bytes), software revision (2 bytes) and type letter (1 byte). e.g. 7030_14A => Model AR-7030, revision 1.4, type letter A. 8) Lock levels. Level 0 Normal operation. Level 1 IR remote control disabled. Front panel buttons ignored. Front panel spin-wheels logged but not actioned. Display update (frequency & S-meter) continues. Level 2 As level 1, but display update suspended. In revisions before 1.4 squelch operation is inhibited, which results in no audio output after a mode change. In revision 1.4 squelch operation continues and mode changing is as expected. Level 3 Remote operation exclusively. Lock level 1 is recommended during any multi-byte reads or writes of the receiver's memory to prevent data contention between internal and remote memory access. See also EEPROM notes in section (6) */ enum LOCK_LVL_e { LOCK_0 = 0, LOCK_1 = 1, LOCK_2 = 2, LOCK_3 = 3, LOCK_NONE = 4 }; /* 8) Routines. Routine 0 Reset Setup receiver as at switch-on. Routine 1 Set frequency Program local oscillator from frequ area and setup RF filters and oscillator range. Routine 2 Set mode Setup from mode byte in memory and display mode, select preferred filter and PBS, BFO values etc. Routine 3 Set passband Setup all IF parameters from filter, pbsval and bfoval bytes. Routine 4 Set all Set all receiver parameters from current memory values. Routine 5 <2> Set audio Setup audio controller from memory register values. Routine 6 <2> Set RF-IF Setup RF Gain, IF Gain and AGC speed. Also sets Notch Filter and Noise Blanker if these options are fitted. Routine 7 Not assigned Routine 8 Not assigned Routine 9 Direct Rx control Program control register from rxcon area. Routine 10 Direct DDS control Program local oscillator and carrier oscillator DDS systems from wbuff area. The 32-bits at wbuff control the carrier frequency, value is 385674.4682 / kHz. The 32 bits at wbuff+4 control the local osc frequency, value is 753270.4456 / MHz. Routine 11 Display menus Display menus from menu1 and menu2 bytes. Routine 12 Display frequency Display frequency from frequ area. Routine 13 Display buffer Display ASCII data in wbuff area. First byte is display address, starting at 128 for the top line and 192 for the bottom line. An address value of 1 clears the display. Data string (max length 24 characters) ends with a zero byte. Routine 14 Read signal strength Transmits byte representing received signal strength (read from AGC voltage). Output is 8-bit binary in range 0 to 255. Routine 15 Read buttons Transmits byte indicating state of front panel buttons. Output is 8-bit binary with an offset of +48 (i.e. ASCII numbers). Buttons held continuously will only be registered once. */ enum ROUTINE_e { RESET = 0, SET_FREQ = 1, SET_MODE = 2, SET_PASS = 3, SET_ALL = 4, SET_AUDIO = 5, SET_RFIF = 6, DIR_RX_CTL = 9, DIR_DDS_CTL = 10, DISP_MENUS = 11, DISP_FREQ = 12, DISP_BUFF = 13, READ_SIGNAL = 14, READ_BTNS = 15 }; /* Button codes :- 0 = None pressed 5 = RF-IF button 1 = Mode up button 6 = Memory button 2 = Mode down button 7 = * button 3 = Fast button 8 = Menu button 4 = Filter button 9 = Power button */ enum BUTTON_e { BTN_NONE = 0, BTN_UP = 1, BTN_DOWN = 2, BTN_FAST = 3, BTN_FILTER = 4, BTN_RFIF = 5, BTN_MEMORY = 6, BTN_STAR = 7, BTN_MENU = 8, BTN_POWER = 9 }; /* Note that the work buffer wbuff area in memory is used continuously by the receiver unless lock levels 2 or 3 are invoked. Lock levels of 1 or more should be used when reading any front panel controls to prevent erratic results. 10) Battery sustained RAM (Memory page 1) Address Ident Length Description 0 0x000 13 bytes Real time clock / timer registers :- 0 0x000 rt_con 1 byte Clock control register 2 0x002 rt_sec 1 byte Clock seconds (2 BCD digits) 3 0x003 rt_min 1 byte Clock minutes (2 BCD digits) 4 0x004 rt_hrs 1 byte Clock hours (2 BCD digits - 24 hr format) 5 0x005 rt_dat 1 byte Clock year (2 bits) and date (2 BCD digits) 6 0x006 rt_mth 1 byte Clock month (2 BCD digits - low 5 bits only) 8 0x008 tm_con 1 byte Timer control register 10 0x00A tm_sec 1 byte Timer seconds (2 BCD digits) 11 0x00B tm_min 1 byte Timer minutes (2 BCD digits) 12 0x00C tm_hrs 1 byte Timer hours (2 BCD digits - 24 hr format) 13 0x00D 15 bytes Power-down save area :- 13 0x00D ph_cal 1 byte Sync detector phase cal value 14 0x00E pd_slp 1 byte Timer run / sleep time in minutes 15 0x00F pd_dly 1 byte Scan delay value x 0.125 seconds 16 0x010 pd_sst 1 byte Scan start channel 17 0x011 pd_ssp 1 byte Scan stop channel 18 0x012 pd_stp 2 bytes Channel step size 20 0x014 pd_sql 1 byte Squelch 21 0x015 pd_ifg 1 byte IF gain 22 0x016 pd_flg 1 byte Flags (from pdflgs) 23 0x017 pd_frq 3 bytes Frequency 26 0x01A pd_mod <3> 1 byte Mode (bits 0-3) and NB threshold (bits 4-7) 27 0x01B pd_vol <3> 1 byte Volume (bits 0-5) and rx memory hundreds (bits 6&7) 28 0x01C 26 bytes Receiver setup save area :- 28 0x01C md_flt 1 byte AM mode : Filter (bits 0-3) and AGC speed (bits 4-7) 29 0x01D md_pbs 1 byte AM mode : PBS value 30 0x01E md_bfo 1 byte AM mode : BFO value 31 0x01F 3 bytes Ditto for Sync mode 34 0x022 3 bytes Ditto for NFM mode - except Squelch instead of BFO 37 0x025 3 bytes Ditto for Data mode 40 0x028 3 bytes Ditto for CW mode 43 0x02B 3 bytes Ditto for LSB mode 46 0x02E 3 bytes Ditto for USB mode 49 0x031 st_aud <3> 1 byte Audio bass setting (bits 0-4) bit 5 Notch auto track enable bit 6 Ident search enable bit 7 Ident preview enable 50 0x032 1 byte Audio treble setting (bits 0-3) and RF Gain (bits 4-7) 51 0x033 1 byte Aux output level - left channel 52 0x034 1 byte Aux output level - right channel 53 0x035 st_flg 1 byte Flags (from stflgs) 54 0x036 26 bytes Setup memory A (configured as above) 80 0x050 26 bytes Setup memory B (configured as above) 106 0x06A 26 bytes Setup memory C (configured as above) 132 0x084 24 bytes Filter data area :- 132 0x084 fl_sel 1 byte Filter 1 : selection bits and IF bandwidth 133 0x085 fl_bw 1 byte Filter 1 : bandwidth (2 BCD digits, x.x kHz) 134 0x086 fl_uso 1 byte Filter 1 : USB offset value x 33.19Hz 135 0x087 fl_lso 1 byte Filter 1 : LSB offset value x 33.19Hz 136 0x088 4 bytes Ditto for filter 2 140 0x08C 4 bytes Ditto for filter 3 144 0x090 4 bytes Ditto for filter 4 148 0x094 4 bytes Ditto for filter 5 152 0x098 4 bytes Ditto for filter 6 156 0x09C mem_sq 100 bytes Squelch / BFO values for frequency memories 0 to 99 (BFO for Data and CW modes, Squelch for others) */ #define MAX_MEM_SQL_PAGE0 (99) enum FILTER_e { FILTER_1 = 1, FILTER_2 = 2, FILTER_3 = 3, FILTER_4 = 4, FILTER_5 = 5, FILTER_6 = 6 }; enum BBRAM_mem_e { RT_CON = 0, RT_SEC = 2, RT_MIN = 3, RT_HRS = 4, RT_DAT = 5, RT_MTH = 6, TM_CON = 8, TM_SEC = 10, TM_MIN = 11, TM_HRS = 12, PH_CAL = 13, PD_SLP = 14, PD_DLY = 15, PD_SST = 16, PD_SSP = 17, PD_STP = 18, PD_SQL = 20, PD_IFG = 21, PD_FLG = 22, PD_FRQ = 23, PD_MOD = 26, PD_VOL = 27, MD_FLT = 28, MD_PBS = 29, MD_BFO = 30, ST_AUD = 49, ST_FLG = 53, FL_SEL = 132, FL_BW = 133, FL_USO = 134, FL_LSO = 135, MEM_SQ = 156 }; /* 11) EEPROM (Memory page 2) Address Ident Length Description 0 0x000 4 bytes Frequency memory data :- 0 0x000 mem_fr 3 bytes Memory 00 : 24-bit frequency 3 0x003 mem_md 1 byte bits 0 - 3 mode bits 4 - 6 filter bit 7 scan lockout 4 0x004 396 bytes Ditto for memories 01 to 99 400 0x190 mem_pb 100 bytes PBS values for frequency memories 0 to 99 500 0x1F4 sm_cal 8 bytes S-meter calibration values :- 500 0x1F4 1 byte RSS offset for S1 level 501 0x1F5 1 byte RSS steps up to S3 level 502 0x1F6 1 byte RSS steps up to S5 level 503 0x1F7 1 byte RSS steps up to S7 level 504 0x1F8 1 byte RSS steps up to S9 level 505 0x1F9 1 byte RSS steps up to S9+10 level 506 0x1FA 1 byte RSS steps up to S9+30 level 507 0x1FB 1 byte RSS steps up to S9+50 level 508 0x1FC if_cal 2 bytes RSS offsets for -20dB and -8dB filter alignment 510 0x1FE if_def 1 byte Default filter numbers for narrow and wide (2 BCD digits) 511 0x1FF option <1> 1 byte Option information :- bit 0 Noise blanker bit 1 Notch filter bit 2 10 dB step attenuator (DX version) */ #define MAX_MEM_FREQ_PAGE2 (99) #define MAX_MEM_PBS_PAGE2 (99) enum EEPROM1_mem_e { MEM_FR = 0, MEM_MD = 3, MEM_PB = 400, SM_CAL = 500, IF_CAL = 508, IF_DEF = 510, OPTION = 511 }; /* 12) EEPROM (Memory page 3) . Address Ident Length Description 0 0x000 4 bytes Frequency memory data :- 0 0x000 mex_fr 3 bytes Memory 100 : 24-bit frequency 3 0x003 mex_md 1 byte bits 0 - 3 mode bits 4 - 6 filter bit 7 scan lockout 4 0x004 1196 bytes Ditto for memories 101 to 399 1200 0x4B0 8 bytes Timer memory data :- 1200 0x4B0 mtm_mn 1 byte Timer memory 0 : minutes (2 BCD digits) 1201 0x4B1 mtm_hr 1 byte hours (2 BCD digits) 1202 0x4B2 mtm_dt 1 byte date (2 BCD digits) 1203 0x4B3 mtm_mt 1 byte month (2 BCD digits) 1204 0x4B4 mtm_ch 2 bytes rx channel (hundreds and 0-99) 1206 0x4B6 mtm_rn 1 byte run time 1207 0x4B7 mtm_ac 1 byte active (0 = not active) 1208 0x4B8 72 bytes Ditto for timer memories 1 to 9 1280 0x500 16 bytes Frequency memory data :- 1280 0x500 mex_sq 1 byte Memory 0 : Squelch / BFO (not used for mems 0 to 99) (BFO for Data and CW modes) 1281 0x501 mex_pb 1 byte PBS value (not used for mems 0 to 99) 1282 0x502 mex_id 14 bytes Text Ident 1296 0x510 2800 bytes Ditto for memories 1 to 175 */ #define MAX_MEM_FREQ_PAGE3 (399) #define MAX_MEM_SQL_PAGE3 (175) #define MAX_MEM_PBS_PAGE3 (175) #define MAX_MEM_ID_PAGE3 (175) enum EEPROM2_mem_e { MEX_FR = 0, MEX_MD = 3, MEM_MN = 1200, MTM_HR = 1201, MTM_DT = 1202, MTM_MT = 1203, MTM_CH = 1204, MTM_RN = 1206, MTM_AC = 1207, MEX_SQ = 1280, MEX_PB = 1281, MEX_ID = 1282 }; /* 13) EEPROM (Memory page 4) <1> Address Ident Length Description 0 0x000 16 bytes Frequency memory data :- 0 0x000 mey_sq 1 byte Memory 176 : Squelch / BFO (BFO for Data and CW modes) 1 0x001 mey_pb 1 byte PBS value 2 0x002 mey_id 14 bytes Text Ident 16 0x010 3568 bytes Ditto for memories 177 to 399 3584 0xE00 mex_hx 400 bytes Frequency fast find index (1 byte for each memory 0 to 399) Index value is bits 9 to 16 of 24-bit frequency stored in each memory. Empty memories (frequency zero) should have a random index byte. 3984 0xF90 112 bytes spare */ enum EEPROM3_mem_e { MEY_SQ = 0, MEY_PB = 1, MEY_ID = 2, MEX_HX = 3584 }; /* 14) Working memory (Memory page 0) Areas not specifically addressed are used as workspace by the internal processor. - Keep out (by order). Address Ident Length Description 16 0x010 snphs 1 byte Sync detector phase offset cal value 17 0x011 slptim 1 byte Sleep time (minutes) 18 0x012 scnst 1 byte Scan start channel 19 0x013 scnsp 1 byte Scan stop channel 20 0x014 scndly 1 byte Scan delay time value x 0.125 seconds 21 0x015 chnstp 2 bytes 16-bit channel step size, value is 376.6352 / kHz 23 0x017 sqlsav 1 byte Squelch save value (non-fm mode) 24 0x018 ifgain 1 byte IF gain value (zero is max gain) 26 0x01A frequ 3 bytes 24-bit tuned frequency, value is 376635.2228 / MHz. 29 0x01D mode 1 byte Current mode :- 1 = AM 4 = Data 2 = Sync 5 = CW 3 = NFM 6 = LSB 7 = USB 30 0x01E 10 bytes Audio control registers :- 30 0x01E af_vol 1 byte Main channel volume (6-bits, values 15 to 63) 31 0x01F af_vll 1 byte Left channel balance (5-bits, half of volume value above) 32 0x020 af_vlr 1 byte Right channel balance (as above) 33 0x021 af_bas <1> 1 byte Main channel bass (bits 0-4, values 6 to 25, 15 is flat) bit 5 nchtrk Notch auto track enable bit 6 idauto Ident auto search enable bit 7 idprev Ident auto preview enable 34 0x022 af_trb <3> 1 byte Main channel treble (bits 0-3, values 2 to 10, 6 is flat) bit 4 nb_opt Noise blanker menus enabled bit 5 nt_opt Notch Filter menus enabled bit 6 step10 10 dB RF attenuator fitted 35 0x023 af_axl 1 byte Left aux channel level (bits 0-5, values 27 to 63) 36 0x024 af_axr <3> 1 byte Right aux channel level (bits 0-5, values 27 to 63) bit 7 nchsr Notch search running 37 0x025 af_axs <3> 1 byte Aux channel source (bits 0-3) bit 4 nchen Notch filter active bit 5 nchsig Notch filter signal detected bit 6 axmut Aux output mute bit 7 nchato Notch auto tune active 38 0x026 af_opt <3> 1 byte Option output source (bits 0-3) bit 4 idover Ident on LCD over frequency bit 5 idsrdn Ident search downwards bit 7 idsrch Ident search in progress 39 0x027 af_src 1 byte Main channel source bit 6 afmut Main output mute 40 0x028 rxcon 3 bytes Receiver control register mapping :- byte 1 bit 0 rx_fs3 Filter select : FS3 byte 1 bit 1 rx_fs2 Filter select : FS2 byte 1 bit 2 rx_fs1 Filter select : FS1 byte 1 bit 3 rx_fs4 Filter select : FS4 byte 1 bit 4 rx_pre Preamplifier enable byte 1 bit 5 rx_atr Atten : 0 = 20dB / 1 = 40dB byte 1 bit 6 rx_rff Input filter : 0 = HF / 1 = LF byte 1 bit 7 rx_atn Attenuator enable byte 2 bit 0 rx_as1 AGC speed : 00 = Slow byte 2 bit 1 rx_as2 10 = Med 11 = Fast byte 2 bit 2 rx_agi AGC inhibit byte 2 bit 3 rx_en LO and HET enable byte 2 bit 4 rx_aux Aux relay enable byte 2 bit 5 rx_fs5 Filter select : FS5 byte 2 bit 6 rx_fs6 Filter select : FS6 byte 2 bit 7 rx_ibw IF b/w : 0 = 4kHz / 1 = 10kHz byte 3 bit 0 rx_chg Fast charge enable byte 3 bit 1 rx_pwr PSU enable byte 3 bit 2 rx_svi Sync VCO inhibit byte 3 bit 3 rx_agm AGC mode : 0 = peak / 1 = mean byte 3 bit 4 rx_lr1 LO range : 00 = 17 - 30 MHz byte 3 bit 5 rx_lr2 10 = 10 - 17 MHz 01 = 4 - 10 MHz 11 = 0 - 4 MHz byte 3 bit 6 rx_sbw Sync b/w : 0 = Wide / 1 = Narrow byte 3 bit 7 rx_car Car sel : 0 = AM / 1 = DDS 43 0x02B bits 3 bytes General flags :- byte 1 bit 6 lock1 Level 1 lockout byte 1 bit 7 lock2 Level 2 lockout byte 2 bit 0 upfred Update frequency display byte 2 bit 1 upmend Update menus byte 2 bit 2 tune4x Tune 4 times faster (AM & NFM) byte 2 bit 3 quickly Quick tuning (fast AGC, Sync) byte 2 bit 4 fast Fast tuning mode byte 2 bit 5 sncpt1 Auto sync - frequency lock byte 2 bit 6 sncpt2 Auto sync - phase lock byte 2 bit 7 sncal Sync detector calibrating byte 3 bit 0 sqlch Squelch active (i.e. low signal) byte 3 bit 1 mutsql Mute on squelch (current setting) byte 3 bit 2 bscnmd Scan mode for VFO B byte 3 bit 3 dualw Dual watch active byte 3 bit 4 scan Scan active byte 3 bit 5 memlk Current memory scan lockout byte 3 bit 6 pbsclr Enable PBS CLR from IR remote <2> byte 3 bit 7 memodn MEM button scans downwards 46 0x02E pdflgs 1 byte Flags saved at power-down :- bit 0 power Power on bit 1 flock Tuning locked bit 2 batop Battery operation (for fast chg) <1> bit 3 nben Noise blanker active <1> bit 4 nblong Noise blanker long pulse 47 0x02F stflgs 1 byte Flags saved in setup memories :- bit 0 mutsav Mute on squelch (non-fm mode) bit 1 mutaux Mute aux output on squelch bit 2 axren Aux relay on timer bit 3 axrsql Aux relay on squelch bit 4 snauto Auto sync mode bit 5 snarr Sync detector narrow bandwidth bit 6 scanmd Scan runs irrespective of squelch bit 7 autorf RF gain auto controlled 48 0x030 rfgain 1 byte Current RF gain setting (0 to 5) (0=max gain) 49 0x031 rfagc 1 byte Current RF AGC setting (added to above) 50 0x032 agcspd 1 byte Current AGC speed : 0 = Fast 2 = Slow 1 = Medium 3 = Off 51 0x033 sqlval 1 byte Squelch value (current setting) 52 0x034 filter 1 byte Current filter number (1 to 6) 53 0x035 pbsval 1 byte PBS offset (x33.19Hz) 54 0x036 bfoval 1 byte BFO offset (x33.19Hz) 55 0x037 fltofs 1 byte Filter centre frequency offset (x33.19Hz) 56 0x038 fltbw 1 byte Filter bandwidth (2 BCD digits : x.x kHz) 57 0x039 ircode: 2 bytes Current / last IR command code 59 0x03B spnpos 1 byte Misc spin-wheel movement } 0 = no movement 60 0x03C volpos 1 byte Volume control movement } +ve = clockwise 61 0x03D tunpos 1 byte Tuning control movement } -ve = anti-clockwise 62 0x03E lstbut 1 byte Last button pressed 63 0x03F smval 2 bytes Last S-meter reading (bars + segments) 65 0x041 mestmr 1 byte Message time-out timer 66 0x042 rfgtmr 1 byte RF gain delay timer 67 0x043 updtmr 1 byte Sustained RAM update timer 68 0x044 agctmr 1 byte AGC speed restore delay timer 69 0x045 snctmr 1 byte Auto sync refresh timer 70 0x046 scntmr 1 byte Scan delay timer 71 0x047 irdly 1 byte IR remote auto repeat delay counter 72 0x048 runtmr 1 byte Sleep mode timer 73 0x049 snfrq 1 byte Sync detector frequency offset cal value 74 0x04A frange 1 byte Input / LO range 75 0x04B menu1 <3> 1 byte Current left menu (type A and B menu numbers are different) 76 0x04C menu2 <3> 1 byte Current right menu (type A and B menu numbers are different) 77 0x04D memno 1 byte Current memory number 78 0x04E setno 1 byte Setup / config selection - load / save 85 0x055 mempg <1> 1 byte Memory page (hundreds - value 0 to 3) 86 0x056 nbthr <1> 1 byte Noise blanker threshold (values 0 to 15) 87 0x057 hshfr <1> 1 byte Current tuned frequ index value (during ident search) 88 0x058 nchtmr <1> 1 byte Notch filter auto tune / search timer 90 0x059 wbuff 26 bytes Work buffer 115 0x073 keymd 1 byte IR remote +/- keys function 116 0x074 keybuf 20 bytes IR remote key input buffer 136 0x088 frofs: 4 bytes 32-bit local osc offset 140 0x08C carofs 4 bytes 32-bit carrier osc offset 144 0x090 smofs 1 byte S-meter starting offset 145 0x091 smscl 7 bytes S-meter segment values 152 0x098 ifcal 2 bytes RSS offsets for -20 dB and -5 dB filter alignment 154 0x09A ifdef 1 byte Default filter numbers for narrow and wide (2 digits) 155 0x09B vfo_b 22 bytes VFO B storage area :- 155 0x09B 1 byte B : Scan delay time 156 0x09C 2 bytes B : Channel step size 158 0x09E 1 byte B : Squelch save value (non-fm mode) 159 0x09F 1 byte B : IF gain value 160 0x0A0 1 byte not used 161 0x0A1 3 bytes B : Tuned frequency 164 0x0A4 1 byte B : Mode 165 0x0A5 1 byte B : Volume 166 0x0A6 1 byte B : Left channel balance 167 0x0A7 1 byte B : Right channel balance 168 0x0A8 1 byte B : Bass response 169 0x0A9 1 byte B : Treble response 170 0x0AA 1 byte B : RF gain 171 0x0AB 1 byte B : RF AGC 172 0x0AC 1 byte B : AGC speed 173 0x0AD 1 byte B : Squelch value 174 0x0AE 1 byte B : Filter number 175 0x0AF 1 byte B : PBS offset 176 0x0B0 1 byte B : BFO offset 218 0x0DA savmnu <1> 1 byte Saved menu 1 number during ident display 219 0x0DB srchm <1> 2 bytes Ident search memory (page and number) 222 0x0DD idtmr <1> 1 byte Auto ident search start timer 223 0x0DE nchfr <1> 2 bytes 16-bit notch filter frequency, value is 6553.6 / kHz */ #define HZ_PBS_STEP \ ((44545000.0 * 25.0)/(16777216.0 * 2.0)) /* 33.1886 Hz/Step */ #define NOTCH_STEP_HZ (6.5536) /* 6.5536 Hz/Step */ #define VOL_MIN (15) #define VOL_MAX (63) #define BASS_MIN (6) #define BASS_MAX (25) #define TREB_MIN (2) #define TREB_MAX (10) #define AUX_MIN (27) #define AUX_MAX (63) enum MODE_e { MODE_NONE = 0, AM = 1, SAM = 2, FM = 3, DATA = 4, CW = 5, LSB = 6, USB = 7 }; enum AGC_decay_e { DECAY_SLOW = 0, DECAY_MED = 2, DECAY_FAST = 3 }; enum LO_range_e { LO_17_30 = 0, LO_4_10 = 1, LO_10_17 = 2, LO_0_4 = 3 }; enum AGC_spd_e { AGC_NONE = -1, AGC_FAST = 0, AGC_MED = 1, AGC_SLOW = 2, AGC_OFF = 3 }; enum WORKING_mem_e { SNPHS = 16, SLPTIM = 17, SCNST = 18, SCNSP = 19, SCNDLY = 20, CHNSTP = 21, SQLSAV = 23, IFGAIN = 24, FREQU = 26, MODE = 29, AF_VOL = 30, AF_VLL = 31, AF_VLR = 32, AF_BAS = 33, AF_TRB = 34, AF_AXL = 35, AF_AXR = 36, AF_AXS = 37, AF_OPT = 38, AF_SRC = 39, RXCON = 40, BITS = 43, PDFLGS = 46, STFLGS = 47, RFGAIN = 48, RFAGC = 49, AGCSPD = 50, SQLVAL = 51, FILTER = 52, PBSVAL = 53, BFOVAL = 54, FLTOFS = 55, FLTBW = 56, IRCODE = 57, SPNPOS = 59, VOLPOS = 60, TUNPOS = 61, LSTBUT = 62, SMVAL = 63, MESTMR = 65, RFGTMR = 66, UPDTMR = 67, AGCTMR = 68, SNCTMR = 69, SCNTMR = 70, IRDLY = 71, RUNTMR = 72, SNFRQ = 73, FRANGE = 74, MENU1 = 75, MENU2 = 76, MEMNO = 77, SETNO = 78, MEMPG = 85, NBTHR = 86, HSHFR = 87, NCHTMR = 88, WBUFF = 90, KEYMD = 115, KEYBUF = 116, FROFS = 136, CAROFS = 140, SMOFS = 144, SMSCL = 145, IFCAL = 152, IFDEF = 154, VFO_B = 155, SCNDLY_B = 155, CHNSTP_B = 156, SQLSAV_B = 158, IFGAIN_B = 159, FREQU_B = 161, MODE_B = 164, AF_VOL_B = 165, AF_VLL_B = 166, AF_VLR_B = 167, AF_BAS_B = 168, AF_TRB_B = 169, RFGAIN_B = 170, RFAGC_B = 171, AGCSPD_B = 172, SQLVAL_B = 173, FILTER_B = 174, PBSVAL_B = 175, BFOVAL_B = 176, SAVMNU = 218, SRCHM = 219, IDTMR = 222, NCHFR = 223 }; enum ROM_mem_e { IDENT = 0 }; #define HZ_PER_STEP ( 44545000.0 / 16777216.0 ) /* 2.655 Hz/Step */ #define STEPS_PER_HZ ( 16777216.0 / 44545000.0 ) /* 0.3766 Steps/Hz */ #define MAX_FREQ (32010000.0) #define MIN_FREQ (10000.0) /* RS232 signal meter reading - additional comments Several commercial organisations are using the AR7030 for signal monitoring purposes and wish to accurately log signal meter level. The information is given in the RS232 PROTOCOL LISTING but the subject is fairly complex. A summary of the required process is given here, the text has been generated by John Thorpe in response to a commercial request for more detailed guidance (November 2001). Reading the input signal strength from the AR7030 is not too difficult, but some maths is needed to convert the level into dBm. Each set is calibrated after manufacture and a set of S-meter calibration values stored in EEPROM in the receiver. This means that the signal strength readings should be quite good and consistent. I think that you should get less than 2dB change with frequency and maybe 3dB with temperature. Initial calibration error should be less than +/- 2dB. I think the sets that you use have been modified for DRM use have some changes in the IF stage. This will require that the sets are re-calibrated if you are to get accurate results. The SM7030 service kit has a calibration program (for PC) and is available from AOR. The signal strength is read from the AGC voltage within the 7030 so AGC should be switched on and RF Gain set to maximum. To read AGC voltage send opcode 02EH (execute routine 14) and the receiver will return a single byte value between 0 and 255 which is the measured AGC voltage. The calibration table is stored in EEPROM, so the control software should read this when connection to the receiver is established and store the data in an array for computing. Calibration data is 8 bytes long and is stored in Page2 at locations 500 (0x01F4) to 507 (0x01FB). Use the PaGE opcode (0x52) then SRH, ADR, ADH to setup the address, then 8 RDD opcodes to read the data, as below :- Opcode Hex Operation PGE 2 0x52 Set page 2 SRH 15 0x3F H register = 15 ADR 4 0x44 Set address 0x0F4 ADH 1 0x11 Set address 0x1F4 RDD +1 0x71 Read byte 1 of cal data RDD +1 0x71 Read byte 2 of cal data . . . RDD +1 0x71 Read byte 8 of cal data PGE 0 0x50 Return to page 0 for subsequent control operations The first byte of calibration data holds the value of the AGC voltage for a signal level of -113dBm (S1). Successive bytes hold the incremental values for 10dB increases in signal level :- Cal data Typical Value RF signal level byte 1 64 -113dBm byte 2 10 -103dBm byte 3 10 -93dBm byte 4 12 -83dBm byte 5 12 -73dBm byte 6 15 -63dBm byte 7 30 -43dBm (note 20dB step) byte 8 20 -23dBm (note 20dB step) */ #define CAL_TAB_LENGTH (8) #define STEP_SIZE_LOW (10) #define STEP_SIZE_HIGH (20) /* To calculate the signal level, table values should be subtracted from the AGC voltage in turn until a negative value would result. This gives the rough level from the table position. The accuracy can be improved by proportioning the remainder into the next table step. See the following example :- A read signal strength operation returns a value of 100 Subtract cal byte 1 (64) leaves 36 level > -113dBm Subtract cal byte 2 (10) leaves 26 level > -103dBm Subtract cal byte 3 (10) leaves 16 level > -93dBm Subtract cal byte 4 (12) leaves 4 level > -83dBm Test cal byte 5 (12) - no subtraction Fine adjustment value = (remainder) / (cal byte 5) * (level step) = 4 / 12 * 10 = 3dB Signal level = -83dBm + 3dB = -80dB The receiver can operate the RF attenuator automatically if the signal level is likely to overload the RF stages. Reading the RFAGC byte (page 0, location 49) gives the attenuation in 10dB steps. This value should be read and added to the value calculated above. Further discussion has taken place on the subject of PC control with the designer, the comments may be of assistance to other operators... As far as I can tell all of the commands and operations work exactly as documented so when the client talks of "the set frequency command doesn't work" they are obviously doing something wrong. Similarly, I am unable to duplicate the effects that they notice with changing audio settings after changing modes. There are some issues with the parameters that they are changing which I will address later, but first they must sort out the basic communication so that the receiver control is as expected. Further issues cannot really be sorted until this is working properly. Programming issues... Since I have no Knowledge of what programming system the client is using these are only general comments. The receiver control is in 8-bit binary code so any communication must maintain all 8 bits (and not truncate bit 7 as some printer outputs do). It is also essential that no extra characters are added to the output stream so check that the software is not adding carriage returns, line feeds, nulls or end-of-file markers to the output. If this might be a problem, monitor the computer to receiver communication with a serial line monitor or another computer running a simple RS-232 reading program. There is some sample BASIC code in the "AR-7030 Computer remote control protocol" document which gives subroutines that cover the commonly used receiver settings. Use this as a starting point for your own routines. The published routines have been thoroughly tested and work without problems. http://www.aoruk.com/pdf/comp.pdf http://www.aoruk.com/7030bulletin.htm#7030_rs232_s-meter With all "buffered" RS-232 connections it is possible for the computer and receiver to get out of step when using two-way communication. For this reason I included some "flush input buffer" routines in the sample code. Using these ensures that missed characters or extra characters inserted due to noise or disconnection do not disrupt communication between the computer and receiver, and a recovery after communications failure can be automatic. Because the receiver's remote control is by direct access to memory and processor it is a very flexible system but is also able to disrupt receiver operation if incorrectly used. Only a few bytes of information stored in the receiver's memory affect S-meter calibration and AOR (UK) hold records of this data for each receiver made so that in the event of corruption it can be re-programmed. See the note that follows regarding AGC calibration. All other working memory contents can be set to sensible values by a "Set defaults" operation from the front panel. Most, but not all, of the working memory is re-established by executing a remote "Reset" command (0x20) which can be done as a last resort after control failure. Specific parameter settings... The client describes the correct operations for setting mode and frequency but if, as he states, the set frequency command (021h) does not work then this needs to be investigated. This may lead to discovering the cause of other problems suffered by the client. Note that changing the frequency in this way re-tunes the receiver but does not update the display on the front panel. A "Display frequency" command is included for this purpose. To set the receiver main volume, three locations need to be written - Page 0, addr 0x1e, 0x1f & 0x20. Details are in the protocol document, note the minimum value (for zero volume) is 15. The aux channel level change is as described by the client and after writing new values into the RAM will need either a "Set audio" command or a "Set all" command to make the change. I can find no reason for, nor duplicate, the effect of changing mode altering the aux level so this effect also needs investigating - maybe the clients "write to memory" is writing too many locations ? To initialise several receiver parameters I would recommend locking the receiver, writing all of the required memory data, sending a "Set all" command and then unlocking if required. There is no need to send individual "Set" commands after each parameter. Unless very special requirements are needed (mainly test, setup and alignment ) the 3 rxcon locations should not be written. When a "Set all" command is sent these will be programmed by the receiver firmware to appropriate values for the mode, frequency and filters selected. Only the parameters that need changing need to be written, all other values will be maintained. The locations that the client needs to program for the parameters he lists are as follows:- (all Page 0) frequency frequ 0x1a 0x1b 0x1c mode mode 0x1d volume af_vol 0x1e 0x1f 0x20 (values=0x0f 0x07 0x07 for min volume) aux level af_axl 0x23 0x24 agc speed agcspd 0x32 squelch sqlval 0x33 filter filter 0x34 IF gain ifgain 0x18 RF gain rfgain 0x30 (value=0x01 for no pre-amp) message wbuff 0x59 (max 26 bytes) If the required parameter values are unknown, I recommend setting the receiver as required through the front panel controls and then reading the value of the memory locations affected using the "read data" operation. 15) Sample routines (in MS QBASIC) REM Sample subroutines for communication with the AR-7030 A-type REM These subroutines use the following variables :- REM rx.freq# frequency in kHz (double precision) REM rx.mode mode number (1 to 7) REM rx.filt filter number (1 to 6) REM rx.mem memory number (0 to 99) REM rx.pbs passband shift value (-4.2 to +4.2 in kHz) REM rx.sql squelch value (0 to 255) REM ident$ -model number, revision and type REM Subroutine to open comms link to receiver open.link: open "com1:1200,n,8,1,cd0,cs0,ds0,rs" for random as #1 len = 1 field #1, 1 as input.byte$ return REM Subroutine to flush QBASIC serial input buffer flush.buffer: print #1,"//"; do time.mark# = timer do while timer - time.mark# < 0.2 loop if eof(1) then exit do get #1 loop return REM Subroutines to lock and unlock receiver controls lock.rx: print #1,chr$(&H81); ' Set lockout level 1 return unlock.rx: print #1,chr$(&H80); ' Lockout level 0 (not locked) return REM Subroutine to read byte from comms link read.byte: read.value = -1 ' Value assigned for read error time.mark# = timer print #1,chr$(&H71); ' Read byte command do while timer - time.mark# < 0.3 if eof(1) = 0 then get #1 read.value = asc(input.byte$) exit do end if loop return REM Subroutine to set receiver frequency and mode tune.rx: gosub lock.rx print #1,chr$(&H50); ' Select working mem (page 0) print #1,chr$(&H31);chr$(&H4A); ' Frequency address = 01AH gosub send.freq ' Write frequency print #1,chr$(&H60+rx.mode); ' Write mode print #1,chr$(&H24); ' Tune receiver gosub unlock.rx return REM Subroutine to store data into receiver's frequency memory set.memory: mem.loc = rx.mem+156 ' Squelch memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H51); ' Select squelch memory (page 1) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H30+int(rx.sql/16)) print #1,chr$(&H60+rx.sql mod 16) ' Write squelch value mem.loc = rx.mem*4 ' Frequency memory origin mem.t = int(mem.loc/256) mem.loc = mem.loc mod 256 mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H52); ' Select frequency memory (page 2) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H10+mem.t); gosub send.freq ' Write frequency print #1,chr$(&H30+rx.filt); print #1,chr$(&H60+rx.mode); ' Write filter and mode mem.loc = rx.mem+400-256 ' PBS memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 pbs.val = 255 and int(rx.pbs/0.033189+0.5) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H11); print #1,chr$(&H30+int(pbs.val/16)) print #1,chr$(&H60+pbs.val mod 16) ' Write passband value return REM Subroutine to read data from receiver's frequency memory read.memory: mem.loc = rx.mem+156 ' Squelch memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H51); ' Select squelch memory (page 1) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address gosub read.byte ' Read squelch value rx.sql = read.value mem.loc = rx.mem*4 ' Frequency memory origin mem.t = int(mem.loc/256) mem.loc = mem.loc mod 256 mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H52); ' Select frequency memory (page 2) print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H10+mem.t); gosub read.freq ' Read frequency gosub read.byte ' Read filter and mode if read.value < 0 then return rx.filt = int(read.value/16) rx.mode = read.value mod 16 mem.loc = rx.mem+400-256 ' PBS memory origin mem.h = int(mem.loc/16) mem.l = mem.loc mod 16 print #1,chr$(&H30+mem.h); print #1,chr$(&H40+mem.l); ' Set memory address print #1,chr$(&H11); gosub read.byte ' Read passband value if read.value < 0 then return if read.value > 127 then read.value = 256-read.value rx.pbs = read.value*0.033189 return REM Subroutine to read receiver ident string read.ident: print #1,chr$(&H5F); ' Select ident memory (page 15) print #1,chr$(&H40); ' Set address 0 ident$="" for read.loop = 1 to 8 gosub read.byte ' Read 8-byte ident if read.value < 0 then exit for ident$ = ident$+chr$(read.value) next read.loop return REM Subroutine to send frequency (Called only from other routines) send.freq: fr.val# = int(rx.freq#*376.635223+0.5) ' Convert kHz to steps ' Exact multiplicand is ' (2^24)/44545 print #1,chr$(&H30+int(fr.val#/1048576)); fr.val# = fr.val# mod 1048576 ' Write frequency as 6 hex digits print #1,chr$(&H60+int(fr.val#/65536)); fr.val# = fr.val# mod 65536 print #1,chr$(&H30+int(fr.val#/4096)); fr.val# = fr.val# mod 4096 print #1,chr$(&H60+int(fr.val#/256)); fr.val# = fr.val# mod 256 print #1,chr$(&H30+int(fr.val#/16)); print #1,chr$(&H60+(fr.val# mod 16)); return REM Subroutine to read frequency (Called only from other routines) read.freq: fr.val# = 0 for read.loop = 1 to 3 gosub read.byte ' Read frequency as 3 bytes if read.value < 0 then exit for fr.val# = fr.val#*256+read.value next read.loop rx.freq# = fr.val#/376.635223 ' Convert steps to kHz return */ /* * (from http://www.aoruk.com/archive/pdf/ir.pdf) * * AOR AR7030 receiver infrared protocol listing * * There have been two types of IR7030 infrared hand controller employed * by the AR7030. Late in 2005 a VERSION 2 handset (IR7030-2) was adopted * in production. The protocol is slightly different, so a matching CPU * must be employed (firmware 1xA or 1xB uses the original IR7030, * firmware 2xA or 2xB uses the later IR7030-2). * * IR7030 IR7030-2 * NEC protocol 16 bit NEC protocol 16 bit * * Address 026 HEX Address 04D HEX * I.R key Hex value I.R key Hex value * 1 0C 1 11 * 2 11 2 13 * 3 12 3 1C * 4 10 4 15 * 5 19 5 16 * 6 1A 6 14 * 7 18 7 19 * 8 1D 8 17 * 9 1E 9 1B * 0 15 0 1D * . DECIMAL 16 . DECIMAL 12 * CLEAR 13 CLEAR 07 * BACKSPACE 1C BACKSPACE 1F * kHz 17 kHz 1A * MHz 1F MHz 1E * CW/NFM 8 CW/NFM 0F * LSB/USB 0D LSB/USB 10 * AM/SYNC 0E AM/SYNC 18 * + MODIFY 2 + MODIFY 01 * - MODIFY 6 - MODIFY 0B * TUNE UP 3 TUNE UP 04 * TUNE DOWN 7 TUNE DOWN 05 * VOLUME UP 0B VOLUME UP 02 * VOLUME DOWN 0F VOLUME DOWN 03 * PASSBAND MODIFY 0 PASSBAND MODIFY 09 * FILTER MODIFY 1 FILTER MODIFY 08 * BASS MODIFY 5 BASS MODIFY 0A * TREBLE MODIFY 14 TREBLE MODIFY 0C * VFO SELECT A/B 0A VFO SELECT A/B 0E * MEMORY STORE 4 MEMORY STORE 0D * MEMORY PREVIEW 9 MEMORY PREVIEW 00 * MEMORY RECALL 1B MEMORY RECALL 06 * * www.aoruk.com - 25.07.2006 */ /* * These are the translated key codes shown in the last IR code * address 58 in page 0. */ enum IR_CODE_e { IR_ONE = 0x12, IR_TWO = 0x14, IR_THREE = 0x1d, IR_FOUR = 0x16, IR_FIVE = 0x17, IR_SIX = 0x15, IR_SEVEN = 0x1a, IR_EIGHT = 0x18, IR_NINE = 0x1c, IR_ZERO = 0x1e, IR_DOT = 0x13, IR_CLR = 0x08, IR_BS = 0x20, IR_KHZ = 0x1b, IR_MHZ = 0x1f, IR_CWFM = 0x10, IR_LSBUSB = 0x11, IR_AMSYNC = 0x19, IR_PLUS = 0x02, IR_MINUS = 0x0c, IR_TUN_UP = 0x05, IR_TUN_DWN = 0x06, IR_VOL_UP = 0x03, IR_VOL_DWN = 0x04, IR_PBS = 0x0a, IR_TREBLE = 0x0d, IR_BASS = 0x0b, IR_VFO = 0x0f, IR_MEM_STO = 0x0e, IR_MEM_PRE = 0x01, IR_MEM_RCL = 0x07, IR_NONE = -1 }; /* backend conf */ #define TOK_CFG_MAGICCONF TOKEN_BACKEND(1) /* ext_level's and ext_parm's tokens */ #define TOK_EL_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_MAGICPARM TOKEN_BACKEND(4) /* Utility function prototypes */ #if 0 int NOP( RIG *rig, unsigned char x ); int SRH( RIG *rig, unsigned char x ); int PGE( RIG *rig, enum PAGE_e page ); int ADR( RIG *rig, unsigned char x ); int ADH( RIG *rig, unsigned char x ); int WRD( RIG *rig, unsigned char out ); int MSK( RIG *rig, unsigned char mask ); int EXE( RIG *rig, enum ROUTINE_e routine ); int RDD( RIG *rig, unsigned char len ); int LOC( RIG *rig, enum LOCK_LVL_e level ); int BUT( RIG *rig, enum BUTTON_e button ); #endif // 0 int execRoutine( RIG * rig, enum ROUTINE_e rtn ); int writeByte( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char x ); int writeShort( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short x ); int write3Bytes( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x ); int writeInt( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x ); int readByte( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char *x ); int readShort( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short *x ); int read3Bytes( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x ); int readInt( RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x ); int readSignal( RIG * rig, unsigned char *x ); int flushBuffer( RIG * rig ); int lockRx( RIG * rig, enum LOCK_LVL_e level ); int bcd2Int( const unsigned char bcd ); unsigned char int2BCD( const unsigned int val ); int getCalLevel( RIG * rig, unsigned char rawAgc, int *dbm ); int getFilterBW( RIG *rig, enum FILTER_e filter ); freq_t ddsToHz( const unsigned int steps ); unsigned int hzToDDS( const freq_t freq ); float pbsToHz( const unsigned char steps ); unsigned char hzToPBS( const float freq ); rmode_t modeToHamlib( const unsigned char mode ); unsigned char modeToNative( const rmode_t mode ); enum agc_level_e agcToHamlib( const unsigned char agc ); unsigned char agcToNative( const enum agc_level_e agc ); int pageSize( const enum PAGE_e page ); int sendIRCode( RIG *rig, enum IR_CODE_e code ); #endif /* _AR7030P_H */ hamlib-4.6.2/rigs/aor/Makefile.am0000644000175000017500000000045614752216205013472 00000000000000AORSRCLIST = ar8200.c ar8000.c ar5000.c ar3000.c ar7030.c ar3030.c \ ar2700.c ar8600.c ar7030p.c ar7030p.h ar7030p_utils.c \ sr2200.c aor.c aor.h noinst_LTLIBRARIES = libhamlib-aor.la libhamlib_aor_la_SOURCES = $(AORSRCLIST) EXTRA_DIST = README.aor README.ar5000 README.ar7030 Android.mk hamlib-4.6.2/rigs/aor/Makefile.in0000644000175000017500000005634114752216216013511 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/aor ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_aor_la_LIBADD = am__objects_1 = ar8200.lo ar8000.lo ar5000.lo ar3000.lo ar7030.lo \ ar3030.lo ar2700.lo ar8600.lo ar7030p.lo ar7030p_utils.lo \ sr2200.lo aor.lo am_libhamlib_aor_la_OBJECTS = $(am__objects_1) libhamlib_aor_la_OBJECTS = $(am_libhamlib_aor_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/aor.Plo ./$(DEPDIR)/ar2700.Plo \ ./$(DEPDIR)/ar3000.Plo ./$(DEPDIR)/ar3030.Plo \ ./$(DEPDIR)/ar5000.Plo ./$(DEPDIR)/ar7030.Plo \ ./$(DEPDIR)/ar7030p.Plo ./$(DEPDIR)/ar7030p_utils.Plo \ ./$(DEPDIR)/ar8000.Plo ./$(DEPDIR)/ar8200.Plo \ ./$(DEPDIR)/ar8600.Plo ./$(DEPDIR)/sr2200.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_aor_la_SOURCES) DIST_SOURCES = $(libhamlib_aor_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AORSRCLIST = ar8200.c ar8000.c ar5000.c ar3000.c ar7030.c ar3030.c \ ar2700.c ar8600.c ar7030p.c ar7030p.h ar7030p_utils.c \ sr2200.c aor.c aor.h noinst_LTLIBRARIES = libhamlib-aor.la libhamlib_aor_la_SOURCES = $(AORSRCLIST) EXTRA_DIST = README.aor README.ar5000 README.ar7030 Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/aor/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/aor/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-aor.la: $(libhamlib_aor_la_OBJECTS) $(libhamlib_aor_la_DEPENDENCIES) $(EXTRA_libhamlib_aor_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_aor_la_OBJECTS) $(libhamlib_aor_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar2700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar3000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar3030.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar7030.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar7030p.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar7030p_utils.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar8000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar8200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar8600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sr2200.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/aor.Plo -rm -f ./$(DEPDIR)/ar2700.Plo -rm -f ./$(DEPDIR)/ar3000.Plo -rm -f ./$(DEPDIR)/ar3030.Plo -rm -f ./$(DEPDIR)/ar5000.Plo -rm -f ./$(DEPDIR)/ar7030.Plo -rm -f ./$(DEPDIR)/ar7030p.Plo -rm -f ./$(DEPDIR)/ar7030p_utils.Plo -rm -f ./$(DEPDIR)/ar8000.Plo -rm -f ./$(DEPDIR)/ar8200.Plo -rm -f ./$(DEPDIR)/ar8600.Plo -rm -f ./$(DEPDIR)/sr2200.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/aor.Plo -rm -f ./$(DEPDIR)/ar2700.Plo -rm -f ./$(DEPDIR)/ar3000.Plo -rm -f ./$(DEPDIR)/ar3030.Plo -rm -f ./$(DEPDIR)/ar5000.Plo -rm -f ./$(DEPDIR)/ar7030.Plo -rm -f ./$(DEPDIR)/ar7030p.Plo -rm -f ./$(DEPDIR)/ar7030p_utils.Plo -rm -f ./$(DEPDIR)/ar8000.Plo -rm -f ./$(DEPDIR)/ar8200.Plo -rm -f ./$(DEPDIR)/ar8600.Plo -rm -f ./$(DEPDIR)/sr2200.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/aor/sr2200.c0000644000175000017500000004622714752216205012540 00000000000000/* * Hamlib AOR backend - SR2200 description * * Copyright (c) 2000-2011 by Stephane Fillod * * Author: Stefano Speretta, Innovative Solutions In Space BV * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "serial.h" #include "aor.h" #define SR2200_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define SR2200_FUNC_ALL () #define SR2200_LEVEL_GET (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH | RIG_LEVEL_AF | RIG_LEVEL_PREAMP ) #define SR2200_LEVEL_SET (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_AF | RIG_LEVEL_PREAMP) #define SR2200_PARM (RIG_PARM_NONE) #define SR2200_VFO_OPS (RIG_OP_MCL | RIG_OP_UP | RIG_OP_DOWN) #define SR2200_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define SR2200_VFO (RIG_VFO_A | RIG_VFO_B | RIG_VFO_C | RIG_VFO_N(3) | RIG_VFO_N(4) \ | RIG_VFO_N(5) | RIG_VFO_N(6) | RIG_VFO_N(7) | RIG_VFO_N(8) \ | RIG_VFO_N(9)) #define SR2200_PREAMP 10 /* The data available on http://www.aoruk.com did not match very well on HF */ #define SR2200_STR_CAL { 16, { \ { 0, -60 }, \ { 3, -48 }, \ { 14, -42 }, \ { 26, -36 }, \ { 34, -30 }, \ { 42, -24 }, \ { 52, -18 }, \ { 62, -12 }, \ { 74, -6 }, \ { 87, 0 }, \ { 101, 10 }, \ { 117, 20 }, \ { 135, 30 }, \ { 152, 40 }, \ { 202, 50 }, \ { 255, 60 }, \ } } #define SR2200_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT | RIG_LEVEL_AGC, \ .funcs = RIG_FUNC_ABM, \ } #define CR '\r' #define LF '\n' #define EOM "\r" #define BUFSZ 256 static int sr2200_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int parse_s2200_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); static int sr2200_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); static int sr2200_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int sr2200_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int sr2200_get_vfo(RIG *rig, vfo_t *vfo); static int sr2200_set_vfo(RIG *rig, vfo_t vfo); static int sr2200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int sr2200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const struct aor_priv_caps sr2200_priv_caps = { .bank_base1 = '0', .bank_base2 = '0', }; // Derived from AOR AR8200 backend /* * sr2200 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/ * * TODO: retrieve BW info, and rest of commands */ struct rig_caps sr2200_caps = { RIG_MODEL(RIG_MODEL_SR2200), .model_name = "SR2200", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 19200, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = SR2200_LEVEL_GET, .has_set_level = SR2200_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { SR2200_PREAMP, RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 8, .vfo_ops = SR2200_VFO_OPS, .scan_ops = SR2200_SCAN_OPS, .str_cal = SR2200_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, SR2200_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(3000), SR2200_MODES, -1, -1, SR2200_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(3000), SR2200_MODES, -1, -1, SR2200_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {SR2200_MODES, 1}, {SR2200_MODES, 100}, {SR2200_MODES, 500}, {SR2200_MODES, kHz(1)}, {SR2200_MODES, kHz(2)}, {SR2200_MODES, kHz(5)}, {SR2200_MODES, kHz(6.25)}, {SR2200_MODES, kHz(9)}, {SR2200_MODES, kHz(10)}, {SR2200_MODES, kHz(12.5)}, {SR2200_MODES, kHz(20)}, {SR2200_MODES, kHz(25)}, {SR2200_MODES, kHz(30)}, {SR2200_MODES, kHz(50)}, {SR2200_MODES, kHz(100)}, #if 0 {SR2200_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM, kHz(15)}, /* narrow */ {RIG_MODE_FM, kHz(6)}, {RIG_MODE_WFM, kHz(300)}, /* wide */ RIG_FLT_END, }, .priv = (void *)& sr2200_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = NULL, .set_freq = sr2200_set_freq, .get_freq = aor_get_freq, .set_mode = sr2200_set_mode, .get_mode = sr2200_get_mode, .set_vfo = sr2200_set_vfo, .get_vfo = sr2200_get_vfo, .set_level = sr2200_set_level, .get_level = sr2200_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * modes in use by the "MD" command of SR2200 */ #define SR2200_FM '0' #define SR2200_WFM '1' #define SR2200_AM '2' #define SR2200_SFM '3' #define SR2200_WAM '4' /* * sr2200_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise * TODO: error case handling */ static int sr2200_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char ackbuf[BUFSZ]; int ack_len; rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } if (!data) { data = ackbuf; } if (!data_len) { data_len = &ack_len; } /* * Do wait for a reply */ retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } *data_len = retval; if (*data_len < BUFSZ) { data[*data_len] = '\0'; } else { data[BUFSZ - 1] = '\0'; } if (data[0] == '?') { /* command failed? resync with radio */ write_block(rp, (unsigned char *) EOM, 1); return -RIG_EPROTO; } return RIG_OK; } /* * sr2200_set_freq * Assumes rig!=NULL */ int sr2200_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ], ackbuf[BUFSZ], *rfp; int freq_len, ret_freq_len; int retval; ret_freq_len = BUFSZ; if (freq < sr2200_caps.rx_range_list1[0].startf) { rig_debug(RIG_DEBUG_WARN, "Error in %s: frequency is lower than minimum supported value (%.0f Hz)\n", __func__, sr2200_caps.rx_range_list1[0].startf); return -RIG_EPROTO; } if (freq > sr2200_caps.rx_range_list1[0].endf) { rig_debug(RIG_DEBUG_WARN, "Error in %s: frequency is higher than maximum supported value (%.0f Hz)\n", __func__, sr2200_caps.rx_range_list1[0].endf); return -RIG_EPROTO; } SNPRINTF(freqbuf, sizeof(freqbuf), "RF%010.0f"EOM, freq); freq_len = strlen(freqbuf); strcpy(freqbuf + freq_len, EOM); freq_len += strlen(EOM); retval = sr2200_transaction(rig, freqbuf, freq_len, ackbuf, &ret_freq_len); if (retval != RIG_OK) { return retval; } rfp = strstr(ackbuf, "RF"); if (!rfp) { rig_debug(RIG_DEBUG_WARN, "NO RF in returned string in %s: '%s'\n", __func__, freqbuf); return -RIG_EPROTO; } sscanf(rfp + 2, "%"SCNfreq, &freq); return RIG_OK; } /* * sr2200_set_mode * Assumes rig!=NULL */ int sr2200_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int aormode, retval; pbwidth_t normal_width; normal_width = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL) { width = normal_width; } switch (mode) { case RIG_MODE_AM: aormode = width > normal_width ? SR2200_WAM : SR2200_AM; break; case RIG_MODE_FM: aormode = width >= normal_width ? SR2200_FM : SR2200_SFM; break; case RIG_MODE_WFM: aormode = SR2200_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), "MD%c" EOM, aormode); retval = sr2200_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * sr2200_get_mode * Assumes rig!=NULL, mode!=NULL */ int sr2200_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char ackbuf[BUFSZ], *mdp; int ack_len, retval; retval = sr2200_transaction(rig, "MD" EOM, 3, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } mdp = strstr(ackbuf, "MD"); if (!mdp) { rig_debug(RIG_DEBUG_ERR, "%s: no MD in returned string: '%s'\n", __func__, ackbuf); return -RIG_EPROTO; } retval = parse_s2200_aor_mode(rig, mdp[2], mdp[2], mode, width); return retval; } int parse_s2200_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { switch (aormode) { case SR2200_FM: *mode = RIG_MODE_FM; break; case SR2200_AM: *mode = RIG_MODE_AM; break; case SR2200_SFM: *mode = RIG_MODE_FM; break; case SR2200_WAM: *mode = RIG_MODE_AM; break; case SR2200_WFM: *mode = RIG_MODE_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EPROTO; } switch (aorwidth) { case SR2200_FM: *width = s_kHz(15); break; case SR2200_AM: *width = s_kHz(6); break; case SR2200_SFM: *width = s_kHz(6); break; case SR2200_WAM: *width = s_kHz(15); break; case SR2200_WFM: *width = s_kHz(300); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, aorwidth); return -RIG_EPROTO; } return RIG_OK; } /* * sr2200_set_vfo * Assumes rig!=NULL */ int sr2200_set_vfo(RIG *rig, vfo_t vfo) { char *vfocmd; switch (vfo) { case RIG_VFO_A: vfocmd = "VA" EOM; break; case RIG_VFO_B: vfocmd = "VB" EOM; break; case RIG_VFO_C: vfocmd = "VC" EOM; break; case RIG_VFO_N(3): vfocmd = "VD" EOM; break; case RIG_VFO_N(4): vfocmd = "VE" EOM; break; case RIG_VFO_N(5): vfocmd = "VF" EOM; break; case RIG_VFO_N(6): vfocmd = "VG" EOM; break; case RIG_VFO_N(7): vfocmd = "VH" EOM; break; case RIG_VFO_N(8): vfocmd = "VI" EOM; break; case RIG_VFO_N(9): vfocmd = "VJ" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_set_vfo: unsupported vfo %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } return sr2200_transaction(rig, vfocmd, strlen(vfocmd), NULL, NULL); } /* * sr2200_get_vfo * Assumes rig!=NULL, freq!=NULL */ int sr2200_get_vfo(RIG *rig, vfo_t *vfo) { int vfo_len, retval; char vfobuf[BUFSZ]; retval = sr2200_transaction(rig, "RX" EOM, 3, vfobuf, &vfo_len); if (retval != RIG_OK) { return retval; } switch (vfobuf[1]) { case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; case 'C': *vfo = RIG_VFO_C; break; case 'D': *vfo = RIG_VFO_N(3); break; case 'E': *vfo = RIG_VFO_N(4); break; case 'F': *vfo = RIG_VFO_N(5); break; case 'G': *vfo = RIG_VFO_N(6); break; case 'H': *vfo = RIG_VFO_N(7); break; case 'I': *vfo = RIG_VFO_N(8); break; case 'J': *vfo = RIG_VFO_N(9); break; default: rig_debug(RIG_DEBUG_ERR, "aor_get_vfo: unknown vfo %c\n", vfobuf[1]); return -RIG_EINVAL; } return RIG_OK; } /* * sr2200_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int sr2200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *rs; char lvlbuf[BUFSZ]; unsigned i; int agc; unsigned att = 0; rs = STATE(rig); switch (level) { case RIG_LEVEL_AF: if (val.f > 255.0F) { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AG255" EOM); } else { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AG%03d" EOM, (int)val.f); } break; case RIG_LEVEL_PREAMP: if (val.f > 0) { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AM1" EOM); } else { SNPRINTF(lvlbuf, sizeof(lvlbuf), "AM0" EOM); } break; case RIG_LEVEL_ATT: for (i = 0; i < HAMLIB_MAXDBLSTSIZ && !RIG_IS_DBLST_END(rs->attenuator[i]); i++) { if (rs->attenuator[i] == val.i) { att = i + 1; break; } } /* should be caught by the front end */ if ((val.i != 0) && (i >= HAMLIB_MAXDBLSTSIZ || RIG_IS_DBLST_END(rs->attenuator[i]))) { return -RIG_EINVAL; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT%u" EOM, att); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: agc = '1'; break; case RIG_AGC_MEDIUM: agc = '3'; break; case RIG_AGC_SLOW: agc = '2'; break; case RIG_AGC_OFF: default: agc = '0'; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC%c" EOM, agc); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported aor_set_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return sr2200_transaction(rig, lvlbuf, strlen(lvlbuf), NULL, NULL); } /* * sr2200_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int sr2200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *rs; char lvlbuf[BUFSZ], ackbuf[BUFSZ]; int ack_len, retval; rs = STATE(rig); switch (level) { case RIG_LEVEL_STRENGTH: SNPRINTF(lvlbuf, sizeof(lvlbuf), "LB" EOM); break; case RIG_LEVEL_ATT: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT" EOM); break; case RIG_LEVEL_AGC: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC" EOM); break; case RIG_LEVEL_AF: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AG" EOM); break; case RIG_LEVEL_PREAMP: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AM" EOM); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = sr2200_transaction(rig, lvlbuf, strlen(lvlbuf), ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } switch (level) { float tmp; case RIG_LEVEL_STRENGTH: if (ack_len < 7 || ackbuf[0] != 'L' || ackbuf[1] != 'B') { return -RIG_EPROTO; } sscanf(ackbuf + 3, "%d", &val->i); // calibrate the S-meter -> values should be referred to S9 (-73 dBm) val->i += 73; break; case RIG_LEVEL_ATT: { unsigned att; if (ack_len < 4 || ackbuf[0] != 'A' || ackbuf[1] != 'T') { return -RIG_EPROTO; } att = ackbuf[2] - '0'; if (att == 0) { val->i = 0; break; } if (att > HAMLIB_MAXDBLSTSIZ || rs->attenuator[att - 1] == 0) { rig_debug(RIG_DEBUG_ERR, "Unsupported att %s %u\n", __func__, att); return -RIG_EPROTO; } val->i = rs->attenuator[att - 1]; break; } case RIG_LEVEL_AGC: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'C') { return -RIG_EPROTO; } switch (ackbuf[2]) { case '1': val->i = RIG_AGC_FAST; break; case '3': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; case '0': default: val->i = RIG_AGC_OFF; } break; case RIG_LEVEL_AF: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'G') { return -RIG_EPROTO; } sscanf(ackbuf + 2, "%f", &val->f); break; case RIG_LEVEL_PREAMP: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'M') { return -RIG_EPROTO; } sscanf(ackbuf + 2, "%f", &tmp); if (tmp != 0.0) { val->i = SR2200_PREAMP; } else { val->i = 0; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.2/rigs/aor/ar5000.c0000644000175000017500000003371714752216205012517 00000000000000/* * Hamlib AOR backend - AR5000 description * * Copyright (c) 2000-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "aor.h" #define AR5000_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM| \ RIG_MODE_WFM|RIG_MODE_SAM|RIG_MODE_SAL|RIG_MODE_SAH) #define AR5000_FUNC_ALL (RIG_FUNC_TSQL | RIG_FUNC_ABM) #define AR5000_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RAWSTR) #define AR5000_PARM (RIG_PARM_NONE) #define AR5000_VFO_OPS (RIG_OP_MCL | RIG_OP_UP | RIG_OP_DOWN) #define AR5000_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR5000_VFO (RIG_VFO_A | RIG_VFO_B | RIG_VFO_C | RIG_VFO_N(3) | RIG_VFO_N(4)) /* As reported with rigctl 'l RAWSTR' for AR5000A S/n: 171218 on 7040kHz / CW / 3kHz Bw. The data available on http://www.aoruk.com did not match very well on HF */ #define AR5000_STR_CAL { 16, { \ { 0, -60 }, \ { 3, -48 }, \ { 14, -42 }, \ { 26, -36 }, \ { 34, -30 }, \ { 42, -24 }, \ { 52, -18 }, \ { 62, -12 }, \ { 74, -6 }, \ { 87, 0 }, \ { 101, 10 }, \ { 117, 20 }, \ { 135, 30 }, \ { 152, 40 }, \ { 202, 50 }, \ { 255, 60 }, \ } } #define AR5000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT | RIG_LEVEL_AGC, \ .funcs = RIG_FUNC_ABM, \ } static int format5k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); static int parse5k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); static const struct aor_priv_caps ar5k_priv_caps = { .format_mode = format5k_mode, .parse_aor_mode = parse5k_aor_mode, .bank_base1 = '0', .bank_base2 = '0', }; /* * ar5000 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/5000.htm * * TODO: retrieve BW info, and rest of commands */ struct rig_caps ar5000_caps = { RIG_MODEL(RIG_MODEL_AR5000), .model_name = "AR5000", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR5000_FUNC_ALL, .has_get_level = AR5000_LEVEL, .has_set_level = RIG_LEVEL_SET(AR5000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 8, .vfo_ops = AR5000_VFO_OPS, .scan_ops = AR5000_SCAN_OPS, .str_cal = AR5000_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR5000_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(2600), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(2600), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR5000_MODES, 1}, {AR5000_MODES, 10}, {AR5000_MODES, 50}, {AR5000_MODES, 100}, {AR5000_MODES, 500}, {AR5000_MODES, kHz(1)}, {AR5000_MODES, kHz(5)}, {AR5000_MODES, kHz(6.25)}, {AR5000_MODES, kHz(9)}, {AR5000_MODES, kHz(10)}, {AR5000_MODES, kHz(12.5)}, {AR5000_MODES, kHz(20)}, {AR5000_MODES, kHz(25)}, {AR5000_MODES, kHz(30)}, {AR5000_MODES, kHz(50)}, {AR5000_MODES, kHz(100)}, {AR5000_MODES, kHz(500)}, #if 0 {AR5000_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_SAL | RIG_MODE_SAH | RIG_MODE_CW, kHz(3)}, {RIG_MODE_CW, Hz(500)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_SAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_SAM, kHz(3)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SAM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, /* narrow */ {RIG_MODE_FM, kHz(30)}, /* wide */ {RIG_MODE_WFM, kHz(110)}, {RIG_MODE_WFM, kHz(30)}, /* narrow */ {RIG_MODE_WFM, kHz(220)}, /* wide */ RIG_FLT_END, }, .priv = (void *)& ar5k_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ar5000a rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/5000.htm * * TODO: retrieve BW info, and rest of commands */ struct rig_caps ar5000a_caps = { RIG_MODEL(RIG_MODEL_AR5000A), .model_name = "AR5000A", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR5000_FUNC_ALL, .has_get_level = AR5000_LEVEL, .has_set_level = RIG_LEVEL_SET(AR5000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 8, .vfo_ops = AR5000_VFO_OPS, .scan_ops = AR5000_SCAN_OPS, .str_cal = AR5000_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR5000_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(3000), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(3000), AR5000_MODES, -1, -1, AR5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR5000_MODES, 1}, {AR5000_MODES, 10}, {AR5000_MODES, 50}, {AR5000_MODES, 100}, {AR5000_MODES, 500}, {AR5000_MODES, kHz(1)}, {AR5000_MODES, kHz(5)}, {AR5000_MODES, kHz(6.25)}, {AR5000_MODES, kHz(9)}, {AR5000_MODES, kHz(10)}, {AR5000_MODES, kHz(12.5)}, {AR5000_MODES, kHz(20)}, {AR5000_MODES, kHz(25)}, {AR5000_MODES, kHz(30)}, {AR5000_MODES, kHz(50)}, {AR5000_MODES, kHz(100)}, {AR5000_MODES, kHz(500)}, #if 0 {AR5000_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_SAL | RIG_MODE_SAH | RIG_MODE_CW, kHz(3)}, {RIG_MODE_CW, Hz(500)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_SAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_SAM, kHz(3)}, /* narrow */ {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SAM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, /* narrow */ {RIG_MODE_FM, kHz(30)}, /* wide */ {RIG_MODE_WFM, kHz(110)}, {RIG_MODE_WFM, kHz(30)}, /* narrow */ {RIG_MODE_WFM, kHz(220)}, /* wide */ RIG_FLT_END, }, .priv = (void *)& ar5k_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, }; /* * Function definitions below */ /* * modes in use by the "MD" command of AR5000 */ #define AR5K_FM '0' #define AR5K_AM '1' #define AR5K_LSB '2' #define AR5K_USB '3' #define AR5K_CW '4' #define AR5K_SAM '5' #define AR5K_SAL '6' #define AR5K_SAH '7' int format5k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width) { int aormode; switch (mode) { case RIG_MODE_AM: aormode = AR5K_AM; break; case RIG_MODE_WFM: case RIG_MODE_FM: aormode = AR5K_FM; break; case RIG_MODE_LSB: aormode = AR5K_LSB; break; case RIG_MODE_USB: aormode = AR5K_USB; break; case RIG_MODE_CW: aormode = AR5K_CW; break; case RIG_MODE_SAM: aormode = AR5K_SAM; break; case RIG_MODE_SAL: aormode = AR5K_SAL; break; case RIG_MODE_SAH: aormode = AR5K_SAH; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { int aorwidth; if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } switch (width) { case 500: aorwidth = '0'; break; case s_kHz(3): aorwidth = '1'; break; case s_kHz(6): aorwidth = '2'; break; case s_kHz(15): aorwidth = '3'; break; case s_kHz(30): aorwidth = '4'; break; case s_kHz(110): aorwidth = '5'; break; case s_kHz(220): aorwidth = '6'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } SNPRINTF(buf, buf_len, "MD%c BW%c", aormode, aorwidth); return strlen(buf); } else { SNPRINTF(buf, buf_len, "MD%c", aormode); return strlen(buf); } } int parse5k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { switch (aormode) { case AR5K_FM: *mode = RIG_MODE_FM; break; case AR5K_AM: *mode = RIG_MODE_AM; break; case AR5K_LSB: *mode = RIG_MODE_LSB; break; case AR5K_USB: *mode = RIG_MODE_USB; break; case AR5K_CW: *mode = RIG_MODE_CW; break; case AR5K_SAM: *mode = RIG_MODE_SAM; break; case AR5K_SAL: *mode = RIG_MODE_SAL; break; case AR5K_SAH: *mode = RIG_MODE_SAH; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EPROTO; } switch (aorwidth) { case '0': *width = 500; break; case '1': *width = s_kHz(3); break; case '2': *width = s_kHz(6); break; case '3': *width = s_kHz(15); break; case '4': *width = s_kHz(30); break; case '5': *width = s_kHz(110); break; case '6': *width = s_kHz(220); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, aorwidth); return -RIG_EPROTO; } return RIG_OK; } hamlib-4.6.2/rigs/aor/ar8200.c0000644000175000017500000001411414752216205012512 00000000000000/* * Hamlib AOR backend - AR8200 description * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "aor.h" #define AR8200_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR8200_FUNC (RIG_FUNC_TSQL|RIG_FUNC_ABM|RIG_FUNC_AFC) #define AR8200_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define AR8200_PARM (RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define AR8200_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN|RIG_OP_LEFT|RIG_OP_RIGHT) #define AR8200_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR8200_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* TODO: measure and report real values */ /* series-2 (black cabinet), from AR8200 Bulletin page */ #define AR8200_STR_CAL { 12, \ { \ { 0,-54 }, \ { 27,-32 }, \ { 42,-27 }, \ { 55,-22 }, \ { 68,-17 }, \ { 86, -7 }, \ { 97, 3 }, \ { 103, 13 }, \ { 106, 23 }, \ { 109, 33 }, \ { 112, 43 }, \ { 139, 53 }, \ } } #define AR8200_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .channel_desc = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT, \ .funcs = RIG_FUNC_ABM, \ } static const struct aor_priv_caps ar8k_priv_caps = { .format_mode = format8k_mode, .parse_aor_mode = parse8k_aor_mode, .bank_base1 = 'A', .bank_base2 = 'a', }; /* * ar8200 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/8200.htm */ struct rig_caps ar8200_caps = { RIG_MODEL(RIG_MODEL_AR8200), .model_name = "AR8200", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR8200_FUNC, .has_get_level = AR8200_LEVEL, .has_set_level = RIG_LEVEL_SET(AR8200_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 20, /* A through J, and a through j */ .chan_desc_sz = 12, .vfo_ops = AR8200_VFO_OPS, .scan_ops = AR8200_SCAN_OPS, .str_cal = AR8200_STR_CAL, .chan_list = { { 0, 999, RIG_MTYPE_MEM, AR8200_MEM_CAP }, /* flat space */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(2040), AR8200_MODES, -1, -1, AR8200_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(2040), AR8200_MODES, -1, -1, AR8200_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR8200_MODES, 50}, {AR8200_MODES, 100}, {AR8200_MODES, kHz(1)}, {AR8200_MODES, kHz(5)}, {AR8200_MODES, kHz(9)}, {AR8200_MODES, kHz(10)}, {AR8200_MODES, 12500}, {AR8200_MODES, kHz(20)}, {AR8200_MODES, kHz(25)}, {AR8200_MODES, kHz(100)}, {AR8200_MODES, MHz(1)}, #if 0 {AR8200_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM, kHz(9)}, {RIG_MODE_WFM, kHz(230)}, /* 50kHz at -3dB, 380kHz at -20dB */ RIG_FLT_END, }, .priv = (void *)& ar8k_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/aor/Android.mk0000644000175000017500000000054714752216205013350 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ar8200.c ar8000.c ar5000.c ar3000.c ar7030.c ar3030.c \ ar2700.c ar8600.c ar7030p.c ar7030p_utils.c sr2200.c aor.c LOCAL_MODULE := aor LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/aor/aor.h0000644000175000017500000000561014752216205012365 00000000000000/* * Hamlib AOR backend - main header * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _AOR_H #define _AOR_H 1 #include #define BACKEND_VER "20220630" int format8k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); int parse8k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); struct aor_priv_caps { int (*format_mode)(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); int (*parse_aor_mode)(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); char bank_base1; char bank_base2; }; int aor_close(RIG *rig); int aor_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int aor_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int aor_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int aor_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int aor_set_vfo(RIG *rig, vfo_t vfo); int aor_get_vfo(RIG *rig, vfo_t *vfo); int aor_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int aor_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int aor_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int aor_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); int aor_set_powerstat(RIG *rig, powerstat_t status); int aor_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int aor_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); const char *aor_get_info(RIG *rig); int aor_set_mem(RIG *rig, vfo_t vfo, int ch); int aor_get_mem(RIG *rig, vfo_t vfo, int *ch); int aor_set_bank(RIG *rig, vfo_t vfo, int bank); int aor_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int aor_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int aor_get_chan_all_cb (RIG * rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t); extern struct rig_caps ar2700_caps; extern struct rig_caps ar8200_caps; extern struct rig_caps ar8000_caps; extern struct rig_caps ar8600_caps; extern struct rig_caps ar5000_caps; extern struct rig_caps ar3000a_caps; extern struct rig_caps ar7030_caps; extern struct rig_caps ar3030_caps; extern struct rig_caps ar5000a_caps; extern struct rig_caps ar7030p_caps; extern struct rig_caps sr2200_caps; #endif /* _AOR_H */ hamlib-4.6.2/rigs/aor/ar8000.c0000644000175000017500000001261114752216205012510 00000000000000/* * Hamlib AOR backend - AR8000 description * Copyright (c) 2000-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "aor.h" #define AR8000_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR8000_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_ABM|RIG_FUNC_AFC) #define AR8000_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define AR8000_PARM (RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define AR8000_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN|RIG_OP_LEFT|RIG_OP_RIGHT) #define AR8000_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define AR8000_VFO (RIG_VFO_A|RIG_VFO_B) /* TODO: measure and report real values */ #define AR8000_STR_CAL { 2, \ { \ { 0x00, -60 }, \ { 0xff, 60 } \ } } static const struct aor_priv_caps ar8000_priv_caps = { .format_mode = format8k_mode, .parse_aor_mode = parse8k_aor_mode, .bank_base1 = 'A', .bank_base2 = 'a', }; /* * ar8000 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/8000.htm */ struct rig_caps ar8000_caps = { RIG_MODEL(RIG_MODEL_AR8000), .model_name = "AR8000", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR8000_FUNC_ALL, .has_get_level = AR8000_LEVEL, .has_set_level = RIG_LEVEL_SET(AR8000_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 20, .chan_desc_sz = 12, .vfo_ops = AR8000_VFO_OPS, .scan_ops = AR8000_SCAN_OPS, .str_cal = AR8000_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 1000 memories */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(1900), AR8000_MODES, -1, -1, AR8000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR8000_MODES, 50}, {AR8000_MODES, 100}, {AR8000_MODES, 200}, {AR8000_MODES, 500}, {AR8000_MODES, kHz(1)}, {AR8000_MODES, kHz(2)}, {AR8000_MODES, kHz(5)}, {AR8000_MODES, kHz(6.25)}, {AR8000_MODES, kHz(9)}, {AR8000_MODES, kHz(10)}, {AR8000_MODES, 12500}, {AR8000_MODES, kHz(20)}, {AR8000_MODES, kHz(25)}, {AR8000_MODES, kHz(30)}, {AR8000_MODES, kHz(50)}, {AR8000_MODES, kHz(100)}, {AR8000_MODES, kHz(200)}, {AR8000_MODES, kHz(250)}, {AR8000_MODES, kHz(500)}, #if 0 {AR8000_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(2)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_WFM, kHz(180)}, /* 50kHz at -3dB, 380kHz at -20dB */ RIG_FLT_END, }, .priv = (void *)& ar8000_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/aor/README.ar50000000644000175000017500000000142314752216205013217 00000000000000hamlib-1.2.5 aor.c ar5000.c 2006-10-29 The previous AR5000 could: - get and set frequency. - read mode if radio were not set to SAH, SAL or SAM. - not set mode. Radio did not accept two commands to be sent at once. - not return VFO-name if rig were set to VFO D or VFO E. - not set VFO D or VFO E. - vfo_op Up and Down works, but radio returns a "?", resulting in "Protocol error". - get_info does not work. - not read AGC-level. Now, it: - can get and set frequency. - can read and set (all) modes. - still does not support VFO D & E. I probably have not understood how VFO_N(3) and VFO_N(4) are meant to be used :-( - can read AGC-level. - corrected channel description size from 12 to 8. - filter-list mode/bw rearranged. - list of tuning steps corrected. Göran Sandin, SM6PPS hamlib-4.6.2/rigs/aor/aor.c0000644000175000017500000010245014752216205012360 00000000000000/* * Hamlib AOR backend - main file * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "idx_builtin.h" #include "aor.h" /* * acknowledge is CR * Is \r portable enough? */ #define CR '\r' #define EOM "\r" #define BUFSZ 256 /* * modes in use by the "MD" command of AR8000 and AR8200 */ #define AR8K_WFM '0' #define AR8K_NFM '1' #define AR8K_AM '2' #define AR8K_USB '3' #define AR8K_LSB '4' #define AR8K_CW '5' #define AR8K_SFM '6' #define AR8K_WAM '7' #define AR8K_NAM '8' /* * aor_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise * TODO: error case handling */ static int aor_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char ackbuf[BUFSZ]; int ack_len; rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } if (!data) { data = ackbuf; } if (!data_len) { data_len = &ack_len; } /* * Do wait for a reply */ retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } /* chop LF head when present */ if (retval >= 1 && data[0] == '\x0a') { retval--; memmove(data, data + 1, retval); } *data_len = retval; if (*data_len < BUFSZ) { data[*data_len] = '\0'; } else { data[BUFSZ - 1] = '\0'; } if (retval >= 1 && data[0] == '?') { /* command failed? resync with radio */ write_block(rp, (unsigned char *) EOM, 1); return -RIG_EPROTO; } return RIG_OK; } /* * aor_close * Assumes rig!=NULL */ int aor_close(RIG *rig) { /* * terminate remote operation via the RS-232 * Note: use write_block() instead of aor_transaction * since no reply is to be expected. */ return write_block(RIGPORT(rig), (unsigned char *) "EX" EOM, 3); } static int format_freq(char *buf, int buf_len, freq_t freq) { int lowhz; int64_t f = (int64_t)freq; /* * actually, frequency must be like nnnnnnnnm0, * where m must be 0 or 5 (for 50Hz). */ lowhz = f % 100; f /= 100; if (lowhz < 25) { lowhz = 0; } else if (lowhz < 75) { lowhz = 50; } else { lowhz = 100; } f = f * 100 + lowhz; SNPRINTF(buf, buf_len, "RF%010"PRIll, f); return strlen(buf); } /* * aor_set_freq * Assumes rig!=NULL */ int aor_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; int freq_len; freq_len = format_freq(freqbuf, sizeof(freqbuf), freq); strcpy(freqbuf + freq_len, EOM); freq_len += strlen(EOM); return aor_transaction(rig, freqbuf, freq_len, NULL, NULL); } /* * aor_get_freq * Assumes rig!=NULL, freq!=NULL */ int aor_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; retval = aor_transaction(rig, "RX" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } rfp = strstr(freqbuf, "RF"); if (!rfp && rig->caps->rig_model == RIG_MODEL_AR8000) { rfp = strstr(freqbuf, "VA"); } if (!rfp && rig->caps->rig_model == RIG_MODEL_AR8000) { rfp = strstr(freqbuf, "VB"); } if (!rfp) { rig_debug(RIG_DEBUG_WARN, "NO RF in returned string in aor_get_freq: '%s'\n", freqbuf); return -RIG_EPROTO; } sscanf(rfp + 2, "%"SCNfreq, freq); return RIG_OK; } /* * aor_set_vfo * Assumes rig!=NULL */ int aor_set_vfo(RIG *rig, vfo_t vfo) { char *vfocmd; switch (vfo) { case RIG_VFO_VFO: if (rig->caps->rig_model == RIG_MODEL_AR8000) { vfocmd = "RF" EOM; } else { vfocmd = "VF" EOM; } break; case RIG_VFO_A: vfocmd = "VA" EOM; break; case RIG_VFO_B: vfocmd = "VB" EOM; break; case RIG_VFO_C: vfocmd = "VC" EOM; break; case RIG_VFO_N(3): vfocmd = "VD" EOM; break; case RIG_VFO_N(4): vfocmd = "VE" EOM; break; case RIG_VFO_MEM: vfocmd = "MR" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_set_vfo: unsupported vfo %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } return aor_transaction(rig, vfocmd, strlen(vfocmd), NULL, NULL); } /* * aor_get_vfo * Assumes rig!=NULL, freq!=NULL */ int aor_get_vfo(RIG *rig, vfo_t *vfo) { int vfo_len, retval; char vfobuf[BUFSZ]; retval = aor_transaction(rig, "RX" EOM, 3, vfobuf, &vfo_len); if (retval != RIG_OK) { return retval; } if (rig->caps->rig_model == RIG_MODEL_AR8000) { switch (vfobuf[0]) { case 'S': case 'D': *vfo = RIG_VFO_VFO; break; case 'V': *vfo = RIG_VFO_N(vfobuf[4] - 'A'); break; case 'M': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_get_vfo: unknown vfo %s\n", vfobuf); return -RIG_EINVAL; } } else { switch (vfobuf[1]) { case 'S': case 'V': case 'F': *vfo = RIG_VFO_VFO; break; case 'A': *vfo = RIG_VFO_A; break; case 'B': *vfo = RIG_VFO_B; break; case 'C': *vfo = RIG_VFO_C; break; case 'D': *vfo = RIG_VFO_N(3); break; case 'E': *vfo = RIG_VFO_N(4); break; case 'R': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_get_vfo: unknown vfo %c\n", vfobuf[1]); return -RIG_EINVAL; } } return RIG_OK; } int format8k_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width) { int aormode; switch (mode) { case RIG_MODE_AM: if (rig->caps->rig_model == RIG_MODEL_AR8000) { aormode = AR8K_AM; } else { switch (width) { case RIG_PASSBAND_NORMAL: case s_kHz(9): aormode = AR8K_AM; break; case s_kHz(12): aormode = AR8K_WAM; break; case s_kHz(3): aormode = AR8K_NAM; break; case RIG_PASSBAND_NOCHANGE: aormode = AR8K_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported passband %s %d\n", __func__, rig_strrmode(mode), (int)width); return -RIG_EINVAL; } } break; case RIG_MODE_CW: aormode = AR8K_CW; break; case RIG_MODE_USB: aormode = AR8K_USB; break; case RIG_MODE_LSB: aormode = AR8K_LSB; break; case RIG_MODE_WFM: aormode = AR8K_WFM; break; case RIG_MODE_FM: if (rig->caps->rig_model == RIG_MODEL_AR8000) { aormode = AR8K_NFM; } else { switch (width) { case RIG_PASSBAND_NORMAL: case s_kHz(12): aormode = AR8K_NFM; break; case s_kHz(9): aormode = AR8K_SFM; break; case RIG_PASSBAND_NOCHANGE: aormode = AR8K_NFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported passband %s %d\n", __func__, rig_strrmode(mode), (int)width); return -RIG_EINVAL; } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, buf_len, "MD%c", aormode); return strlen(buf); } /* * aor_set_mode * Assumes rig!=NULL */ int aor_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char mdbuf[9]; char mdbuf2[16] = ""; int mdbuf2_len, retval; if (priv->format_mode(rig, mdbuf, sizeof(mdbuf), mode, width) <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: format_mode=%s failed?\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } strcat(mdbuf, EOM); switch (rig->caps->rig_model) { case RIG_MODEL_AR5000: case RIG_MODEL_AR5000A: SNPRINTF(mdbuf2, sizeof(mdbuf2), "%.3s", mdbuf); /* Extract first 'MD' part */ mdbuf2_len = strlen(mdbuf2); strcpy(mdbuf2 + mdbuf2_len, EOM); /* Add delimiter */ mdbuf2_len = strlen(mdbuf2); retval = aor_transaction(rig, mdbuf2, mdbuf2_len, NULL, NULL); if (retval != RIG_OK) { return retval; } strncpy(mdbuf2, mdbuf + 4, 3); /* Extract first 'BW' part */ mdbuf2[3] = '\0'; // in case strnpy produces and un-terminated string mdbuf2_len = strlen(mdbuf2); retval = aor_transaction(rig, mdbuf2, mdbuf2_len, NULL, NULL); if (retval != RIG_OK) { return retval; } break; default: retval = aor_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); } return retval; } /* * parse8k_aor_mode * don't care about aorwidth, * because there's no such BW command */ int parse8k_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { *width = RIG_PASSBAND_NORMAL; switch (aormode) { case AR8K_AM: *mode = RIG_MODE_AM; break; case AR8K_NAM: *mode = RIG_MODE_AM; *width = rig_passband_narrow(rig, *mode); break; case AR8K_WAM: *mode = RIG_MODE_AM; *width = rig_passband_wide(rig, *mode); break; case AR8K_CW: *mode = RIG_MODE_CW; break; case AR8K_USB: *mode = RIG_MODE_USB; break; case AR8K_LSB: *mode = RIG_MODE_LSB; break; case AR8K_WFM: *mode = RIG_MODE_WFM; break; case AR8K_NFM: *mode = RIG_MODE_FM; break; case AR8K_SFM: *mode = RIG_MODE_FM; *width = rig_passband_narrow(rig, *mode); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EINVAL; } if (*width == RIG_PASSBAND_NORMAL) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * aor_get_mode * Assumes rig!=NULL, mode!=NULL */ int aor_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char ackbuf[BUFSZ]; char ackbuf2[BUFSZ]; char *mdp, *mdp2; int ack_len, ack2_len, retval; retval = aor_transaction(rig, "MD" EOM, 3, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } /* * search MD, because on the AR5000, AU is also returned * by MD request */ mdp = strstr(ackbuf, "MD"); if (!mdp) { rig_debug(RIG_DEBUG_ERR, "%s: no MD in returned string: '%s'\n", __func__, ackbuf); return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR5000 || rig->caps->rig_model == RIG_MODEL_AR5000A) { retval = aor_transaction(rig, "BW" EOM, 3, ackbuf2, &ack2_len); if (retval != RIG_OK) { return retval; } mdp2 = strstr(ackbuf2, "BW"); } else { mdp2 = mdp; } retval = priv->parse_aor_mode(rig, mdp[2], mdp2[2], mode, width); return retval; } /* * aor_set_ts * Assumes rig!=NULL */ int aor_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { char tsbuf[BUFSZ]; /* * actually, tuning step must be like nnnnm0, * where m must be 0 or 5 (for 50Hz). */ SNPRINTF(tsbuf, sizeof(tsbuf), "ST%06ld" EOM, ts); return aor_transaction(rig, tsbuf, strlen(tsbuf), NULL, NULL); } /* * aor_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int aor_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *rs; char lvlbuf[BUFSZ]; int agc; rs = STATE(rig); switch (level) { case RIG_LEVEL_ATT: { unsigned att = 0; unsigned i; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && !RIG_IS_DBLST_END(rs->attenuator[i]); i++) { if (rs->attenuator[i] == val.i) { att = i + 1; break; } } /* should be caught by the front end */ if ((val.i != 0) && (i >= HAMLIB_MAXDBLSTSIZ || RIG_IS_DBLST_END(rs->attenuator[i]))) { return -RIG_EINVAL; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT%u" EOM, att); break; } case RIG_LEVEL_AGC: /* AR5000 & AR5000A */ switch (val.i) { case RIG_AGC_FAST: agc = '0'; break; case RIG_AGC_MEDIUM: agc = '1'; break; case RIG_AGC_SLOW: agc = '2'; break; case RIG_AGC_OFF: default: agc = 'F'; } SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC%c" EOM, agc); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported aor_set_level %d\n", (int)level); return -RIG_EINVAL; } return aor_transaction(rig, lvlbuf, strlen(lvlbuf), NULL, NULL); } /* * aor_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int aor_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *rs = STATE(rig); char lvlbuf[BUFSZ], ackbuf[BUFSZ]; int ack_len, retval; switch (level) { case RIG_LEVEL_RAWSTR: SNPRINTF(lvlbuf, sizeof(lvlbuf), "LM" EOM); break; case RIG_LEVEL_ATT: SNPRINTF(lvlbuf, sizeof(lvlbuf), "AT" EOM); break; case RIG_LEVEL_AGC: /* AR5000 & AR5000A */ SNPRINTF(lvlbuf, sizeof(lvlbuf), "AC" EOM); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported %s %d\n", __func__, (int)level); return -RIG_EINVAL; } retval = aor_transaction(rig, lvlbuf, strlen(lvlbuf), ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RAWSTR: if (ack_len < 4 || ackbuf[0] != 'L' || ackbuf[1] != 'M') { return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR8000) { sscanf(ackbuf + 2, "%x", &val->u); val->i &= ~0x80; /* mask squelch status */ } else if (rig->caps->rig_model == RIG_MODEL_AR8200 || rig->caps->rig_model == RIG_MODEL_AR8600) { sscanf(ackbuf + 3, "%d", &val->i); } else { sscanf(ackbuf + 3, "%x", &val->u); } break; case RIG_LEVEL_ATT: { unsigned att; if (ack_len < 4 || ackbuf[0] != 'A' || ackbuf[1] != 'T') { return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR8000) { att = ackbuf[2] - '0'; } else { att = ackbuf[3] - '0'; } if (att == 0) { val->i = 0; break; } if (att > HAMLIB_MAXDBLSTSIZ || rs->attenuator[att - 1] == 0) { rig_debug(RIG_DEBUG_ERR, "Unsupported att %s %u\n", __func__, att); return -RIG_EPROTO; } val->i = rs->attenuator[att - 1]; break; } case RIG_LEVEL_AGC: if (ack_len < 3 || ackbuf[0] != 'A' || ackbuf[1] != 'C') { return -RIG_EPROTO; } if (rig->caps->rig_model == RIG_MODEL_AR5000 || rig->caps->rig_model == RIG_MODEL_AR5000A) { /* AR5000A requires switching to be made on 3rd returned character. SM6PPS */ switch (ackbuf[2]) { case '0': val->i = RIG_AGC_FAST; break; case '1': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; case 'F': default: val->i = RIG_AGC_OFF; } } else { /* Left the switching on 4th position in case models other than AR5000(A) use this. SM6PPS */ switch (ackbuf[3]) { case '0': val->i = RIG_AGC_FAST; break; case '1': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; case 'F': default: val->i = RIG_AGC_OFF; } } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported %s %d\n", __func__, (int)level); return -RIG_EINVAL; } return RIG_OK; } /* * aor_get_dcd * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int aor_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char ackbuf[BUFSZ]; int ack_len, retval; retval = aor_transaction(rig, "LM" EOM, 3, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len < 2 || ackbuf[0] != 'L' || ackbuf[1] != 'M') { return -RIG_EPROTO; } *dcd = ackbuf[2] == '%' ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } /* * aor_set_powerstat * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int aor_set_powerstat(RIG *rig, powerstat_t status) { if (status == RIG_POWER_ON) { return aor_transaction(rig, "X" EOM, 2, NULL, NULL); } /* turn off power */ return aor_transaction(rig, "QP" EOM, 3, NULL, NULL); } /* * aor_vfo_op * Assumes rig!=NULL */ int aor_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char *aorcmd; switch (op) { case RIG_OP_UP: aorcmd = "\x1e" EOM; break; case RIG_OP_DOWN: aorcmd = "\x1f" EOM; break; case RIG_OP_RIGHT: aorcmd = "\x1c" EOM; break; case RIG_OP_LEFT: aorcmd = "\x1d" EOM; break; case RIG_OP_MCL: aorcmd = "MQ" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "aor_vfo_op: unsupported op %d\n", op); return -RIG_EINVAL; } return aor_transaction(rig, aorcmd, strlen(aorcmd), NULL, NULL); } /* * aor_scan, scan operation * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int aor_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { char *aorcmd; switch (scan) { case RIG_SCAN_STOP: /* Not sure how to stop the scanning. * Maye by going by to MEM/VFO mode? * Any clue? */ if (vfo == RIG_VFO_CURR) { vfo = RIG_VFO_MEM; /* supported by all the AOR rigs */ } return rig_set_vfo(rig, vfo); case RIG_SCAN_MEM: aorcmd = "MS" EOM; break; case RIG_SCAN_SLCT: aorcmd = "SM" EOM; break; case RIG_SCAN_PROG: aorcmd = "VS" EOM; break; /* edges are VFO A & VFO B */ case RIG_SCAN_VFO: aorcmd = "VV1" EOM; break; /* VFO scan mode, VV0 for 2-VFO mode */ default: rig_debug(RIG_DEBUG_ERR, "aor_scan: unsupported scan %d\n", scan); return -RIG_EINVAL; } return aor_transaction(rig, aorcmd, strlen(aorcmd), NULL, NULL); } /* * aor_set_mem * Assumes rig!=NULL */ int aor_set_mem(RIG *rig, vfo_t vfo, int ch) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char membuf[BUFSZ]; int mem_num; char bank_base; /* * FIXME: we're assuming the banks are split 50/50. * MW should be called the first time instead, * and sizing memorized. */ mem_num = ch % 100; if (mem_num >= 50 && priv->bank_base1 != priv->bank_base2) { bank_base = priv->bank_base2; mem_num -= 50; } else { bank_base = priv->bank_base1; } SNPRINTF(membuf, sizeof(membuf), "MR%c%02d" EOM, bank_base + ch / 100, mem_num); return aor_transaction(rig, membuf, strlen(membuf), NULL, NULL); } /* * aor_get_mem * Assumes rig!=NULL, freq!=NULL */ int aor_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; int mem_len, retval; char membuf[BUFSZ]; retval = aor_transaction(rig, "MR" EOM, 3, membuf, &mem_len); if (retval != RIG_OK) { return retval; } if (membuf[0] == '?' || membuf[2] == '?') { return -RIG_ENAVAIL; } sscanf(membuf + 3, "%d", ch); /* * FIXME: we're assuming the banks are split 50/50. * MW should be called the first time instead, * and sizing memorized. */ if (membuf[2] >= priv->bank_base2) { *ch += 100 * (membuf[2] - priv->bank_base2) + 50; } else { *ch += 100 * (membuf[2] - priv->bank_base1); } return RIG_OK; } /* * aor_set_bank * Assumes rig!=NULL */ int aor_set_bank(RIG *rig, vfo_t vfo, int bank) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char membuf[BUFSZ]; SNPRINTF(membuf, sizeof(membuf), "MR%c" EOM, (bank % 10) + (bank < 10 ? priv->bank_base1 : priv->bank_base2)); return aor_transaction(rig, membuf, strlen(membuf), NULL, NULL); } int aor_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char aorcmd[BUFSZ]; int cmd_len; SNPRINTF(aorcmd, sizeof(aorcmd), "MX%c%02d ", chan->bank_num, chan->channel_num % 100); cmd_len = strlen(aorcmd); cmd_len += format_freq(aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, chan->freq); /* * FIXME: automode */ cmd_len += snprintf(aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, " AU%d ST%06d ", 0, (int)chan->tuning_step); cmd_len += priv->format_mode(rig, aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, chan->mode, chan->width); cmd_len += snprintf(aorcmd + cmd_len, sizeof(aorcmd) - cmd_len, " AT%d TM%12s%s", chan->levels[LVL_ATT].i ? 1 : 0, chan->channel_desc, EOM); return aor_transaction(rig, aorcmd, cmd_len, NULL, NULL); } static int parse_chan_line(RIG *rig, channel_t *chan, char *basep, const channel_cap_t *mem_caps) { struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char *tagp; int ts; /* * search for attribute tags in the line. * Using strstr enable support for various models * which may or may not have tag support. */ tagp = strstr(basep, "---"); if (tagp) { vfo_t vfo_save = chan->vfo; int ch_save = chan->channel_num; rig_debug(RIG_DEBUG_WARN, "%s: skipping, channel is empty: '%s'\n", __func__, basep); memset(chan, 0, sizeof(channel_t)); chan->vfo = vfo_save; chan->channel_num = ch_save; return -RIG_ENAVAIL; } /* bank_num */ if (mem_caps->bank_num) { tagp = strstr(basep, "MX"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no MX in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->bank_num = tagp[2] - (tagp[2] >= priv->bank_base2 ? priv->bank_base2 + 10 : priv->bank_base1); } /* pass */ if (mem_caps->flags) { tagp = strstr(basep, "MP"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no MP in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->flags = tagp[2] == '0' ? 0 : RIG_CHFLAG_SKIP; } /* frequency */ if (mem_caps->freq) { tagp = strstr(basep, "RF"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no RF in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } sscanf(tagp + 2, "%"SCNfreq, &chan->freq); } /* channel desc */ if (mem_caps->tuning_step) { tagp = strstr(basep, "ST"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no ST in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } ts = chan->tuning_step; sscanf(tagp + 2, "%d", &ts); } /* mode and width */ if (mem_caps->mode && mem_caps->width) { int retval; char *tag2p; tagp = strstr(basep, "MD"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no MD in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } /* "BW" only on AR5000 */ tag2p = strstr(basep, "BW"); if (!tag2p) { tag2p = tagp; } retval = priv->parse_aor_mode(rig, tagp[2], tag2p[2], &chan->mode, &chan->width); if (retval != RIG_OK) { return retval; } } /* auto-mode */ if (mem_caps->funcs & RIG_FUNC_ABM) { tagp = strstr(basep, "AU"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no AU in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->funcs = tagp[2] == '0' ? 0 : RIG_FUNC_ABM; } /* attenuator */ if (mem_caps->levels & LVL_ATT) { tagp = strstr(basep, "AT"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no AT in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } chan->levels[LVL_ATT].i = tagp[2] == '0' ? 0 : rig->caps->attenuator[tagp[2] - '0' - 1]; } /* channel desc */ if (mem_caps->channel_desc) { int i; tagp = strstr(basep, "TM"); if (!tagp) { rig_debug(RIG_DEBUG_WARN, "%s: no TM in returned string: '%s'\n", __func__, basep); return -RIG_EPROTO; } strncpy(chan->channel_desc, tagp + 2, 12); chan->channel_desc[12] = '\0'; /* chop off trailing spaces */ for (i = 11; i > 0 && chan->channel_desc[i] == ' '; i--) { chan->channel_desc[i] = '\0'; } } return RIG_OK; } int aor_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; char aorcmd[BUFSZ]; int chan_len; char chanbuf[BUFSZ]; int retval; channel_cap_t *mem_caps = NULL; chan_t *chan_list; int channel_num = chan->channel_num; chan_list = rig->caps->chan_list; if (chan->vfo == RIG_VFO_CURR) { /* * curr VFO mem_caps same as memory caps */ mem_caps = &chan_list[0].mem_caps; } else { int mem_num; char bank_base; /* * find mem_caps in caps, we'll need it later */ int i; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (channel_num >= chan_list[i].startc && channel_num <= chan_list[i].endc) { mem_caps = &chan_list[i].mem_caps; break; } } if (!mem_caps) { return -RIG_EINVAL; } /* * FIXME: we're assuming the banks are split 50/50. * MW should be called the first time instead, * and sizing memorized. */ mem_num = channel_num % 100; if (mem_num >= 50 && priv->bank_base1 != priv->bank_base2) { bank_base = priv->bank_base2; mem_num -= 50; } else { bank_base = priv->bank_base1; } SNPRINTF(aorcmd, sizeof(aorcmd), "MR%c%02d" EOM, bank_base + channel_num / 100, mem_num); retval = aor_transaction(rig, aorcmd, strlen(aorcmd), chanbuf, &chan_len); /* is the channel empty? */ if (retval == -RIG_EPROTO && chanbuf[0] == '?') { chan->freq = RIG_FREQ_NONE; return -RIG_ENAVAIL; } if (retval != RIG_OK) { return retval; } } SNPRINTF(aorcmd, sizeof(aorcmd), "RX" EOM); retval = aor_transaction(rig, aorcmd, strlen(aorcmd), chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } retval = parse_chan_line(rig, chan, chanbuf, mem_caps); if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return retval; } #define LINES_PER_MA 10 int aor_get_chan_all_cb(RIG *rig, vfo_t vfo, chan_cb_t chan_cb, rig_ptr_t arg) { const struct aor_priv_caps *priv = (struct aor_priv_caps *)rig->caps->priv; int i, j, retval; chan_t *chan_list = STATE(rig)->chan_list; channel_t *chan; int chan_count; char aorcmd[BUFSZ]; int chan_len; char chanbuf[BUFSZ]; int chan_next = chan_list[0].startc; chan_count = chan_list[0].endc - chan_list[0].startc + 1; /* * setting chan to NULL means the application * has to provide a struct where to store data * future data for channel channel_num */ chan = NULL; retval = chan_cb(rig, vfo, &chan, chan_next, chan_list, arg); if (retval != RIG_OK) { return retval; } if (chan == NULL) { return -RIG_ENOMEM; } SNPRINTF(aorcmd, sizeof(aorcmd), "MA%c" EOM, priv->bank_base1); for (i = 0; i < chan_count / LINES_PER_MA; i++) { retval = aor_transaction(rig, aorcmd, strlen(aorcmd), chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } for (j = 0; j < LINES_PER_MA; j++) { chan->vfo = RIG_VFO_MEM; chan->channel_num = i * LINES_PER_MA + j; retval = parse_chan_line(rig, chan, chanbuf, &chan_list[0].mem_caps); if (retval == -RIG_ENAVAIL) { retval = RIG_OK; } if (retval != RIG_OK) { return retval; } /* notify the end? */ chan_next = chan_next < chan_list[i].endc ? chan_next + 1 : chan_next; /* * provide application with channel data, * and ask for a new channel structure */ chan_cb(rig, vfo, &chan, chan_next, chan_list, arg); if (j >= LINES_PER_MA - 1) { break; } /* * get next line */ retval = read_string(RIGPORT(rig), (unsigned char *) chanbuf, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } } SNPRINTF(aorcmd, sizeof(aorcmd), "MA" EOM); } return RIG_OK; } /* * aor_get_info * Assumes rig!=NULL */ const char *aor_get_info(RIG *rig) { static char infobuf[BUFSZ]; int id_len, frm_len, retval; char idbuf[BUFSZ]; char frmbuf[32]; // only expect 6 chars...please check retval = aor_transaction(rig, "\001" EOM, 2, idbuf, &id_len); if (retval != RIG_OK) { return NULL; } // never executed -- if (retval > 2) { idbuf[2] = '\0'; } retval = aor_transaction(rig, "VR" EOM, 3, frmbuf, &frm_len); if (retval != RIG_OK || frm_len > 16) { return NULL; } frmbuf[frm_len] = '\0'; SNPRINTF(infobuf, sizeof(infobuf), "Remote ID %c%c, Firmware version %s", idbuf[0], idbuf[1], frmbuf); return infobuf; } /* * initrigs_aor is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(aor) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&sr2200_caps); rig_register(&ar2700_caps); rig_register(&ar8200_caps); rig_register(&ar8000_caps); rig_register(&ar8600_caps); rig_register(&ar5000_caps); rig_register(&ar3000a_caps); rig_register(&ar7030_caps); rig_register(&ar3030_caps); rig_register(&ar5000a_caps); rig_register(&ar7030p_caps); return RIG_OK; } hamlib-4.6.2/rigs/aor/ar3030.c0000644000175000017500000004512714752216205012516 00000000000000/* * Hamlib AOR backend - AR3030 description * Copyright (c) 2000-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "idx_builtin.h" #include "misc.h" static int ar3030_set_vfo(RIG *rig, vfo_t vfo); static int ar3030_get_vfo(RIG *rig, vfo_t *vfo); static int ar3030_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ar3030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ar3030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ar3030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ar3030_set_mem(RIG *rig, vfo_t vfo, int ch); static int ar3030_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ar3030_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ar3030_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ar3030_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int ar3030_init(RIG *rig); static int ar3030_cleanup(RIG *rig); static int ar3030_close(RIG *rig); static int ar3030_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); struct ar3030_priv_data { int curr_ch; int curr_vfo; }; /* * TODO: * set_channel(emulated?),rig_vfo_op * rig_reset(RIG_RESET_MCALL) * quit the remote control mode on close? */ #define AR3030_MODES (RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_FAX) #define AR3030_FUNC_ALL (RIG_FUNC_NONE) #define AR3030_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define AR3030_PARM (RIG_PARM_NONE) #define AR3030_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_MCL) #define AR3030_VFO (RIG_VFO_A|RIG_VFO_MEM) /* * FIXME: */ #define AR3030_STR_CAL { 2, \ { \ { 0x00, -60 }, \ { 0x3f, 60 } \ } } #define AR3030_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_SET(AR3030_LEVEL), \ .flags = 1, \ } /* * Data was obtained from AR3030 pdf on http://www.aoruk.com * * ar3030 rig capabilities. */ struct rig_caps ar3030_caps = { RIG_MODEL(RIG_MODEL_AR3030), .model_name = "AR3030", .mfg_name = "AOR", .version = "20200113.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 50, /* ms */ .timeout = 500, .retry = 0, .has_get_func = AR3030_FUNC_ALL, .has_set_func = AR3030_FUNC_ALL, .has_get_level = AR3030_LEVEL, .has_set_level = RIG_LEVEL_SET(AR3030_LEVEL), .has_get_parm = AR3030_PARM, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = AR3030_VFO_OPS, .str_cal = AR3030_STR_CAL, .chan_list = { { 0, 99, RIG_MTYPE_MEM, AR3030_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), AR3030_MODES, -1, -1, AR3030_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), AR3030_MODES, -1, -1, AR3030_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a receiver! */ .tuning_steps = { {AR3030_MODES, 10}, {AR3030_MODES, 100}, {AR3030_MODES, kHz(1)}, {AR3030_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW, 500}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .rig_init = ar3030_init, .rig_cleanup = ar3030_cleanup, .rig_close = ar3030_close, .set_freq = ar3030_set_freq, .get_freq = ar3030_get_freq, .set_mode = ar3030_set_mode, .get_mode = ar3030_get_mode, .set_vfo = ar3030_set_vfo, .get_vfo = ar3030_get_vfo, .set_level = ar3030_set_level, .get_level = ar3030_get_level, .set_mem = ar3030_set_mem, .get_mem = ar3030_get_mem, .get_channel = ar3030_get_channel, .vfo_op = ar3030_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* is LF really needed? */ #define CR "\x0d" #define EOM "\x0d\x0a" #define BUFSZ 64 /* * ar3030_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise */ static int ar3030_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); int retry = 3; char tmpdata[BUFSZ]; if (data == NULL) { data = tmpdata; } rig_flush(rp); do { retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block error=%d\n", __func__, retval); return retval; } if (data) { /* expecting 0x0d0x0a on all commands so wait for the 0x0a */ retval = read_string(rp, (unsigned char *) data, BUFSZ, "\x0a", 1, 0, 1); if (retval == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_ERR, "%s:timeout retry=%d\n", __func__, retry); hl_usleep(50000); } } rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d retry=%d\n", __func__, retval, retry); } while ((retval <= 0) && (--retry > 0)); hl_usleep(1000); // 1ms sleep per manual if (data_len != NULL && retval > 0) { *data_len = 0; /* only set data_len non-zero if not a command response */ if (data[0] != 0x00 && data[0] != 0x0d) { *data_len = retval; } } rig_debug(RIG_DEBUG_TRACE, "%s: return data_len=%d retry=%d\n", __func__, data_len ? *data_len : 0, retry); return RIG_OK; } int ar3030_init(RIG *rig) { struct ar3030_priv_data *priv; struct rig_state *rs = STATE(rig); rs->priv = calloc(1, sizeof(struct ar3030_priv_data)); if (!rs->priv) { return -RIG_ENOMEM; } priv = rs->priv; priv->curr_ch = 99; /* huh! FIXME: get_mem in open() ? */ priv->curr_vfo = RIG_VFO_A; return RIG_OK; } int ar3030_cleanup(RIG *rig) { struct ar3030_priv_data *priv = STATE(rig)->priv; free(priv); return RIG_OK; } int ar3030_close(RIG *rig) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); rig_flush(RIGPORT(rig)); retval = ar3030_transaction(rig, "Q" CR, strlen("Q" CR), NULL, NULL); rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval); return retval; } int ar3030_set_vfo(RIG *rig, vfo_t vfo) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char *cmd = ""; int retval; switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_VFO: case RIG_VFO_A: cmd = "D" CR; break; case RIG_VFO_MEM: cmd = "M" CR; break; default: return -RIG_EINVAL; } retval = ar3030_transaction(rig, cmd, strlen(cmd), NULL, NULL); if (retval == RIG_OK) { priv->curr_vfo = vfo; } return retval; } int ar3030_get_vfo(RIG *rig, vfo_t *vfo) { const struct ar3030_priv_data *priv = (struct ar3030_priv_data *) STATE(rig)->priv; *vfo = priv->curr_vfo; return RIG_OK; } /* * ar3030_set_freq * Assumes rig!=NULL */ int ar3030_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char freqbuf[BUFSZ]; int retval; SNPRINTF(freqbuf, sizeof(freqbuf), "%03.6f" CR, ((double)freq) / MHz(1)); retval = ar3030_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; return RIG_OK; } /* * ar3030_get_freq * Assumes rig!=NULL, freq!=NULL */ int ar3030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; long lfreq; /* * D Rn Gn Bn Tn Fnnnnnnnn C * Note: spaces are transmitted. */ retval = ar3030_transaction(rig, "D" CR, 2, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; rfp = strchr(freqbuf, 'F'); if (!rfp) { return -RIG_EPROTO; } sscanf(rfp + 1, "%ld", &lfreq); *freq = lfreq; rig_debug(RIG_DEBUG_ERR, "%s: read lfreq=%ld, freq=%.6f\n", __func__, lfreq, *freq); return RIG_OK; } /* * ar3030_set_mode * Assumes rig!=NULL */ int ar3030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int aormode, retval; switch (mode) { case RIG_MODE_AM: aormode = 'A'; break; case RIG_MODE_CW: aormode = 'C'; break; case RIG_MODE_USB: aormode = 'U'; break; case RIG_MODE_LSB: aormode = 'L'; break; case RIG_MODE_FM: aormode = 'N'; break; case RIG_MODE_AMS: aormode = 'S'; break; case RIG_MODE_FAX: aormode = 'X'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "%c" CR, aormode); } else { SNPRINTF(mdbuf, sizeof(mdbuf), "%dB%c" CR, width < rig_passband_normal(rig, mode) ? 1 : 0, aormode); } retval = ar3030_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * ar3030_get_mode * Assumes rig!=NULL, mode!=NULL */ int ar3030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; int buf_len, retval; char buf[BUFSZ]; /* * D Rn Gn Bn Tn Fnnnnnnnn C * Note: spaces are transmitted */ retval = ar3030_transaction(rig, "D" CR, 2, buf, &buf_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; switch (buf[25]) { case 'A': *mode = RIG_MODE_AM; break; case 'L': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'C': *mode = RIG_MODE_CW; break; case 'S': *mode = RIG_MODE_AMS; break; case 'N': *mode = RIG_MODE_FM; break; case 'X': *mode = RIG_MODE_FAX; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, buf[25]); return -RIG_EPROTO; } *width = buf[9] == '1' ? rig_passband_narrow(rig, *mode) : rig_passband_normal(rig, *mode); return RIG_OK; } int ar3030_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; int retval = RIG_OK; if (priv->curr_vfo == RIG_VFO_MEM) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%02dM" CR, ch); retval = ar3030_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } if (retval == RIG_OK) { priv->curr_ch = ch; } return retval; } int ar3030_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char infobuf[BUFSZ]; int info_len, retval; if (priv->curr_vfo != RIG_VFO_MEM) { *ch = priv->curr_ch; } retval = ar3030_transaction(rig, "M" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } /* * MnnPnRnGnBnTnFnnnnnnnnC */ if (infobuf[0] != 'M') { return -RIG_EPROTO; } /* * Is it a blank mem channel ? */ if (infobuf[1] == '-' && infobuf[2] == '-') { *ch = -1; /* FIXME: return error instead? */ return RIG_OK; } *ch = priv->curr_ch = atoi(infobuf + 1); return RIG_OK; } int ar3030_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char *cmd; int retval; switch (level) { case RIG_LEVEL_AGC: /* SLOW otherwise */ cmd = val.i == RIG_AGC_FAST ? "1G" CR : "0G" CR; break; case RIG_LEVEL_ATT: cmd = val.i == 0 ? "0R" CR : (val.i == 1 ? "1R" CR : "2R" CR); break; default: return -RIG_EINVAL; } retval = ar3030_transaction(rig, cmd, strlen(cmd), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } int ar3030_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; int info_len, retval; char infobuf[BUFSZ], *p; switch (level) { case RIG_LEVEL_ATT: /* * DRnGnBnTnFnnnnnnnnC */ retval = ar3030_transaction(rig, "D" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; p = strchr(infobuf, 'R'); if (!p) { return -RIG_EPROTO; } val->i = p[1] == '0' ? 0 : rig->caps->attenuator[p[1] - '1']; return RIG_OK; case RIG_LEVEL_AGC: /* * DRnGnBnTnFnnnnnnnnC */ retval = ar3030_transaction(rig, "D" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; p = strchr(infobuf, 'G'); if (!p) { return -RIG_EPROTO; } val->i = p[1] == '0' ? RIG_AGC_SLOW : RIG_AGC_FAST; return RIG_OK; case RIG_LEVEL_RAWSTR: retval = ar3030_transaction(rig, "Y" CR, 2, infobuf, &info_len); if (retval != RIG_OK) { return retval; } infobuf[3] = '\0'; val->i = strtol(infobuf, (char **)NULL, 16); return RIG_OK; default: return -RIG_EINVAL; } return RIG_OK; } int ar3030_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char cmdbuf[BUFSZ], infobuf[BUFSZ]; int info_len, retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%02dM" CR, chan->channel_num); retval = ar3030_transaction(rig, cmdbuf, strlen(cmdbuf), infobuf, &info_len); if (retval != RIG_OK) { return retval; } priv->curr_vfo = RIG_VFO_A; /* * MnnPnRnGnBnTnFnnnnnnnnC */ if (infobuf[0] != 'M') { return -RIG_EPROTO; } /* * Is it a blank mem channel ? */ if (infobuf[1] == '-' && infobuf[2] == '-') { chan->freq = RIG_FREQ_NONE; return RIG_OK; } sscanf(infobuf + 14, "%"SCNfreq, &chan->freq); chan->freq *= 10; switch (infobuf[22]) { case 'A': chan->mode = RIG_MODE_AM; break; case 'L': chan->mode = RIG_MODE_LSB; break; case 'U': chan->mode = RIG_MODE_USB; break; case 'C': chan->mode = RIG_MODE_CW; break; case 'S': chan->mode = RIG_MODE_AMS; break; case 'N': chan->mode = RIG_MODE_FM; break; case 'X': chan->mode = RIG_MODE_FAX; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, infobuf[22]); return -RIG_EPROTO; } chan->width = infobuf[10] == '1' ? rig_passband_narrow(rig, chan->mode) : rig_passband_normal(rig, chan->mode); chan->levels[LVL_ATT].i = infobuf[6] == '0' ? 0 : rig->caps->attenuator[infobuf[4] - '1']; chan->levels[LVL_AGC].i = infobuf[8] == '0' ? RIG_AGC_SLOW : RIG_AGC_FAST; chan->flags = infobuf[4] == '1' ? RIG_CHFLAG_SKIP : RIG_CHFLAG_NONE; if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ar3030_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ar3030_priv_data *priv = (struct ar3030_priv_data *)STATE(rig)->priv; char buf[16]; int retval; switch (op) { case RIG_OP_MCL: SNPRINTF(buf, sizeof(buf), "%02d%%" CR, priv->curr_ch); break; case RIG_OP_FROM_VFO: SNPRINTF(buf, sizeof(buf), "%02dW" CR, priv->curr_ch); priv->curr_vfo = RIG_VFO_MEM; break; default: return -RIG_EINVAL; } retval = ar3030_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } hamlib-4.6.2/rigs/aor/ar3000.c0000644000175000017500000002764514752216205012520 00000000000000/* * Hamlib AOR backend - AR3000 description * Copyright (c) 2000-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include static int ar3k_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ar3k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ar3k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ar3k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ar3k_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int ar3k_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); static int ar3k_set_mem(RIG *rig, vfo_t vfo, int ch); static int ar3k_set_bank(RIG *rig, vfo_t vfo, int bank); static int ar3k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ar3k_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #define AR3000A_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define AR3000A_FUNC_ALL (RIG_FUNC_MUTE|RIG_FUNC_SQL) #define AR3000A_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define AR3000A_VFO_OPS (RIG_OP_NONE) #define AR3000A_VFO (RIG_VFO_A) #define AR3000A_STR_CAL { 3, \ { \ { '%', -60 }, /* mute */ \ { 'A', -54 }, /* S1 */ \ { 'P', 20 } /* +20 */ \ } } /* * AR3000A rig capabilities. * * info coming from A3000A pdf manual from http://www.aoruk.com/ * * TODO: * set_channel, get_channel, set_func MUTE,SQL, get_dcd, ... */ struct rig_caps ar3000a_caps = { RIG_MODEL(RIG_MODEL_AR3000A), .model_name = "AR3000A", .mfg_name = "AOR", .version = "20061007.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = AR3000A_FUNC_ALL, .has_get_level = AR3000A_LEVEL, .has_set_level = RIG_LEVEL_SET(AR3000A_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 4, .chan_desc_sz = 0, .vfo_ops = AR3000A_VFO_OPS, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 4x100 memories */ .rx_range_list1 = { {kHz(100), MHz(2036), AR3000A_MODES, -1, -1, AR3000A_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(2036), AR3000A_MODES, -1, -1, AR3000A_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR3000A_MODES, 50}, {AR3000A_MODES, kHz(999.95)}, #if 0 {AR3000A_MODES, 0}, /* any tuning step */ #endif RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_WFM, kHz(180)}, RIG_FLT_END, }, .str_cal = AR3000A_STR_CAL, .priv = NULL, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = NULL, .set_freq = ar3k_set_freq, .get_freq = ar3k_get_freq, .set_mode = ar3k_set_mode, .get_mode = ar3k_get_mode, .set_ts = ar3k_set_ts, .get_ts = ar3k_get_ts, .set_mem = ar3k_set_mem, .set_bank = ar3k_set_bank, .set_level = ar3k_set_level, .get_level = ar3k_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * acknowledge is CR * Is \r portable enough? */ #define CR '\r' #define EOM "\x0a\x0d" #define BUFSZ 64 /* * ar3k_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL * Otherwise, you'll get a nice seg fault. You've been warned! * return value: RIG_OK if everything's fine, negative value otherwise * TODO: error case handling */ static int ar3k_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* will flush data on next transaction */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * ar3k_set_freq * Assumes rig!=NULL */ int ar3k_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; int retval; unsigned lowhz; /* * actually, frequency must be like nnnn.nnnnm, * where m must be 0 or 5 (for 50Hz). */ lowhz = ((unsigned)freq) % 100; freq /= 100; if (lowhz < 25) { lowhz = 0; } else if (lowhz < 75) { lowhz = 50; } else { lowhz = 100; } freq = freq * 100 + lowhz; SNPRINTF(freqbuf, sizeof(freqbuf), "%04.5f" EOM, ((double)freq) / MHz(1)); retval = ar3k_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * ar3k_get_freq * Assumes rig!=NULL, freq!=NULL */ int ar3k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } rfp = strchr(freqbuf, 'Y'); if (!rfp) { return -RIG_EPROTO; } sscanf(rfp + 1, "%"SCNfreq, freq); *freq *= 10; return RIG_OK; } /* * ar3k_set_mode * Assumes rig!=NULL */ int ar3k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int aormode, retval; switch (mode) { case RIG_MODE_AM: aormode = 'A'; break; case RIG_MODE_CW: aormode = 'C'; break; case RIG_MODE_USB: aormode = 'U'; break; case RIG_MODE_LSB: aormode = 'L'; break; case RIG_MODE_WFM: aormode = 'W'; break; case RIG_MODE_FM: aormode = 'N'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), "%c" EOM, aormode); retval = ar3k_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * ar3k_get_mode * Assumes rig!=NULL, mode!=NULL */ int ar3k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *rfp; int buf_len, retval; char buf[BUFSZ]; /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, buf, &buf_len); if (retval != RIG_OK) { return retval; } rfp = strchr(buf, 'Y'); if (!rfp) { return -RIG_EPROTO; } rfp += 11; switch (*rfp) { case 'Q': *mode = RIG_MODE_FM; break; case 'R': *mode = RIG_MODE_WFM; break; case 'S': *mode = RIG_MODE_AM; break; case 'T': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'V': *mode = RIG_MODE_CW; break; default: rig_debug(RIG_DEBUG_ERR, "ar3k_get_mode: unsupported mode '%c'\n", *rfp); return -RIG_EPROTO; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* * ar3k_set_ts * Assumes rig!=NULL */ int ar3k_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { char freqbuf[BUFSZ]; int retval; int lowhz; /* * actually, frequency must be like nnn.nm, * where m must be 0 or 5 (for 50Hz). */ lowhz = ts % 100; ts /= 100; if (lowhz < 25) { lowhz = 0; } else if (lowhz < 75) { lowhz = 50; } else { lowhz = 100; } ts = ts * 100 + lowhz; SNPRINTF(freqbuf, sizeof(freqbuf), "%03.2fS" EOM, ((double)ts) / kHz(1)); retval = ar3k_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * ar3k_get_ts * Assumes rig!=NULL, ts!=NULL */ int ar3k_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { char *rfp; int freq_len, retval; char freqbuf[BUFSZ]; /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } rfp = strchr(freqbuf, 'Z'); if (!rfp) { return -RIG_EPROTO; } sscanf(rfp + 1, "%ld", ts); *ts *= 10; return RIG_OK; } int ar3k_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; int retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%02dM" EOM, ch); retval = ar3k_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } int ar3k_set_bank(RIG *rig, vfo_t vfo, int bank) { char cmdbuf[BUFSZ]; int retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "%dX" EOM, bank); retval = ar3k_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } int ar3k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char *cmd; int retval; switch (level) { case RIG_LEVEL_ATT: cmd = val.i ? "R" EOM : "T" EOM; break; default: return -RIG_EINVAL; } retval = ar3k_transaction(rig, cmd, strlen(cmd), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } int ar3k_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int info_len, retval; char infobuf[BUFSZ]; switch (level) { case RIG_LEVEL_ATT: /* * #--J0WZ-----Y---------Q * X R,S,T,U,V */ retval = ar3k_transaction(rig, "D" EOM, 3, infobuf, &info_len); if (retval != RIG_OK) { return retval; } val->i = strchr(infobuf, 'W') ? rig->caps->attenuator[1] : 0; return RIG_OK; case RIG_LEVEL_RAWSTR: retval = ar3k_transaction(rig, "Y" EOM, 3, infobuf, &info_len); if (retval != RIG_OK) { return retval; } val->i = infobuf[0]; return RIG_OK; default: return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.2/rigs/aor/ar2700.c0000644000175000017500000001563314752216205012520 00000000000000/* * Hamlib AOR backend - AR2700 description * Copyright (c) 2000-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "aor.h" #define AR2700_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define AR2700_FUNC (RIG_FUNC_ABM) #define AR2700_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define AR2700_PARM (RIG_PARM_APO) #define AR2700_VFO_OPS (RIG_OP_MCL|RIG_OP_UP|RIG_OP_DOWN) #define AR2700_SCAN_OPS (RIG_SCAN_MEM) #define AR2700_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) /* TODO: measure and report real values */ #define AR2700_STR_CAL { 2, \ { \ { 0x00, -60 }, \ { 0x3f, 60 } \ } } #define AR2700_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .bank_num = 1, \ .tuning_step = 1, \ .flags = 1, \ .levels = RIG_LEVEL_ATT, \ .funcs = RIG_FUNC_ABM, \ } static int format2700_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width); static int parse2700_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width); static const struct aor_priv_caps ar2700_priv_caps = { .format_mode = format2700_mode, .parse_aor_mode = parse2700_aor_mode, .bank_base1 = '0', .bank_base2 = '0', }; /* * ar2700 rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! * * part of info from http://www.aoruk.com/2700.htm * Interface unit: CU-8232 (or equivalent) */ struct rig_caps ar2700_caps = { RIG_MODEL(RIG_MODEL_AR2700), .model_name = "AR2700", .mfg_name = "AOR", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 2400, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = AR2700_FUNC, .has_set_func = AR2700_FUNC, .has_get_level = AR2700_LEVEL, .has_set_level = RIG_LEVEL_SET(AR2700_LEVEL), .has_get_parm = AR2700_PARM, .has_set_parm = AR2700_PARM, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 10, .chan_desc_sz = 0, .vfo_ops = AR2700_VFO_OPS, .scan_ops = AR2700_SCAN_OPS, .str_cal = AR2700_STR_CAL, .chan_list = { { 0, 499, RIG_MTYPE_MEM, AR2700_MEM_CAP }, /* flat space */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(1300), AR2700_MODES, -1, -1, AR2700_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(1300), AR2700_MODES, -1, -1, AR2700_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {RIG_MODE_AM | RIG_MODE_FM, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(9)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, 12500}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {AR2700_MODES, kHz(50)}, {AR2700_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = (void *)& ar2700_priv_caps, .rig_init = NULL, .rig_cleanup = NULL, .rig_open = NULL, .rig_close = aor_close, .set_freq = aor_set_freq, .get_freq = aor_get_freq, .set_vfo = aor_set_vfo, .get_vfo = aor_get_vfo, .set_mode = aor_set_mode, .get_mode = aor_get_mode, .set_level = aor_set_level, .get_level = aor_get_level, .get_dcd = aor_get_dcd, .set_ts = aor_set_ts, .set_powerstat = aor_set_powerstat, .vfo_op = aor_vfo_op, .scan = aor_scan, .get_info = aor_get_info, .set_mem = aor_set_mem, .get_mem = aor_get_mem, .set_bank = aor_set_bank, .set_channel = aor_set_channel, .get_channel = aor_get_channel, .get_chan_all_cb = aor_get_chan_all_cb, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * modes in use by the "MD" command of AR2700 */ #define AR2700_WFM '0' #define AR2700_NFM '1' #define AR2700_AM '2' int format2700_mode(RIG *rig, char *buf, int buf_len, rmode_t mode, pbwidth_t width) { int aormode; switch (mode) { case RIG_MODE_AM: aormode = AR2700_AM; break; case RIG_MODE_WFM: aormode = AR2700_WFM; break; case RIG_MODE_FM: aormode = AR2700_NFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, buf_len, "MD%c", aormode); return strlen(buf); } int parse2700_aor_mode(RIG *rig, char aormode, char aorwidth, rmode_t *mode, pbwidth_t *width) { switch (aormode) { case AR2700_NFM: *mode = RIG_MODE_FM; break; case AR2700_WFM: *mode = RIG_MODE_WFM; break; case AR2700_AM: *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, aormode); return -RIG_EPROTO; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } hamlib-4.6.2/rigs/aor/ar7030p_utils.c0000644000175000017500000007573114752216205014126 00000000000000/* * Hamlib AOR backend - AR7030 Plus utility functions * Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Version 2009.12.31 Larry Gadallah (VE6VQ) */ #include #include #include #include #include #include "ar7030p.h" #include "serial.h" static enum PAGE_e curPage = NONE; /* Current memory page */ static unsigned int curAddr = 65535; /* Current page address */ static enum LOCK_LVL_e curLock = LOCK_0; /* Current lock level */ static const unsigned int AR7030_PAGE_SIZE[] = { 256, 256, 512, 4096, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; /* Page size table */ #if 0 /* * Code Ident Operation * 0x NOP No Operation */ int NOP(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_NOP); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 3x SRH Set H-register x -> H-register (4-bits) */ int SRH(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_SRH); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 5x PGE Set page x -> Page register (4-bits) */ int PGE(RIG *rig, enum PAGE_e page) { int rc = RIG_OK; unsigned char op = ((0x0f & page) | op_PGE); assert(NULL != rig); switch (page) { case WORKING: case BBRAM: case EEPROM1: case EEPROM2: case EEPROM3: case ROM: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; case NONE: default: rig_debug(RIG_DEBUG_VERBOSE, "PGE: invalid page %d\n", page); rc = -RIG_EINVAL; break; }; return (rc); } /* * Code Ident Operation * 4x ADR Set address 0Hx -> Address register (12-bits) * 0 -> H-register */ int ADR(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_ADR); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 1x ADH Set address high x -> Address register (high 4-bits) */ int ADH(RIG *rig, unsigned char x) { int rc = RIG_OK; unsigned char op = ((0x0f & x) | op_ADH); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 6x WRD Write data Hx -> [Page, Address] * Address register + 1 -> Address register * 0 -> H-register, 0 -> Mask register */ int WRD(RIG *rig, unsigned char out) { int rc = RIG_OK; unsigned char op = ((0x0f & out) | op_WRD); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 9x MSK Set mask Hx -> Mask register <1> * 0 -> H-register */ int MSK(RIG *rig, unsigned char mask) { int rc = RIG_OK; unsigned char op = ((0x0f & mask) | op_MSK); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } return (rc); } /* * Code Ident Operation * 2x EXE Execute routine x */ int EXE(RIG *rig, enum ROUTINE_e routine) { int rc = RIG_OK; unsigned char op = ((0x0f & routine) | op_EXE); assert(NULL != rig); switch (routine) { case RESET: case SET_FREQ: case SET_MODE: case SET_PASS: case SET_ALL: case SET_AUDIO: case SET_RFIF: case DIR_RX_CTL: case DIR_DDS_CTL: case DISP_MENUS: case DISP_FREQ: case DISP_BUFF: case READ_SIGNAL: case READ_BTNS: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "EXE: invalid routine %d\n", routine); rc = -RIG_EINVAL; break; }; return (rc); } /* * Code Ident Operation * 7x RDD Read data [Page, Address] -> Serial output * Address register + x -> Address register */ int RDD(RIG *rig, unsigned char len) { int rc = RIG_OK; unsigned char inChr = 0; unsigned char op = ((0x0f & len) | op_RDD); assert(NULL != rig); rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } else { rc = read_block(RIGPORT(rig), (char *) &inChr, len); if (1 != rc) { rc = -RIG_EIO; } else { rc = (int) inChr; } } return (rc); } /* * Code Ident Operation * 8x LOC Set lock level x */ int LOC(RIG *rig, enum LOCK_LVL_e level) { int rc = RIG_OK; unsigned char op = ((0x0f & level) | op_LOC); assert(NULL != rig); switch (level) { case LOCK_0: case LOCK_1: case LOCK_2: case LOCK_3: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "LOC: invalid lock level %d\n", level); rc = -RIG_EINVAL; break; }; return (rc); } /* * Code Ident Operation * Ax BUT Operate button x <1> */ int BUT(RIG *rig, enum BUTTON_e button) { int rc = RIG_OK; unsigned char op = ((0x0f & button) | op_BUT); assert(NULL != rig); switch (button) { case BTN_NONE: break; case BTN_UP: case BTN_DOWN: case BTN_FAST: case BTN_FILTER: case BTN_RFIF: case BTN_MEMORY: case BTN_STAR: case BTN_MENU: case BTN_POWER: rc = write_block(RIGPORT(rig), (char *) &op, 1); if (0 != rc) { rc = -RIG_EIO; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "BUT: invalid button %d\n", button); rc = -RIG_EINVAL; break; }; return (rc); } #endif // 0 /* * /brief Execute routine * * /param rig Pointer to rig struct * /param rtn Receiver routine to execute * * \return RIG_OK on success, error code on failure * */ int execRoutine(RIG *rig, enum ROUTINE_e rtn) { int rc = -RIG_EIO; unsigned char v = EXE((rtn & 0x0f)); assert(NULL != rig); if (0 == write_block(RIGPORT(rig), &v, 1)) { rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: routine %2d\n", __func__, rtn); } return (rc); } /* * /brief Set address for I/O with radio * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * * \return RIG_OK on success, error code on failure * * Statics curPage and curAddr shadow radio's copies so that * page and address are only set when needed */ static int setAddr(RIG *rig, enum PAGE_e page, unsigned int addr) { int rc = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); unsigned char v; assert(NULL != rig); if ((EEPROM3 >= page) || (ROM == page)) { if (AR7030_PAGE_SIZE[page] > addr) { if (curPage != page) { v = PGE(page); if (0 == write_block(rp, &v, 1)) { curPage = page; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: set page %2d\n", __func__, page); } else { rc = -RIG_EIO; } } if (curAddr != addr) { v = SRH((0x0f0 & addr) >> 4); rc = write_block(rp, &v, 1); if (rc != RIG_OK) { return -RIG_EIO; } v = ADR((0x00f & addr)); if (0 == write_block(rp, &v, 1)) { if (0xff < addr) { v = ADH((0xf00 & addr) >> 8); if (0 == write_block(rp, &v, 1)) { curAddr = addr; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: set addr 0x%04x\n", __func__, addr); } else { rc = -RIG_EIO; } } else { curAddr = addr; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: set addr 0x%04x\n", __func__, addr); } } else { rc = -RIG_EIO; } } } else { rc = -RIG_EINVAL; /* invalid address */ } } else { rc = -RIG_EINVAL; /* invalid page */ } return (rc); } /* * /brief Write one byte to the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Value to write to radio * * \return RIG_OK on success, error code on failure * */ int writeByte(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char x) { int rc; hamlib_port_t *rp = RIGPORT(rig); unsigned char hi = SRH((x & 0xf0) >> 4); unsigned char lo = WRD(x & 0x0f); assert(NULL != rig); rc = setAddr(rig, page, addr); if (RIG_OK == rc) { rc = -RIG_EIO; if (0 == write_block(rp, &hi, 1)) { if (0 == write_block(rp, &lo, 1)) { rc = RIG_OK; curAddr++; rig_debug(RIG_DEBUG_VERBOSE, "%s: wrote byte 0x%02x\n", __func__, x); } } } return (rc); } /* * /brief Write two bytes to the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Value to write to radio * * \return Number of bytes written, 0 on error. Get error code with getErrno. * */ int writeShort(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short x) { int rc; unsigned char v = (unsigned char)((x & 0xff00) >> 8); rc = writeByte(rig, page, addr, v); if (RIG_OK == rc) { v = (unsigned char)(x & 0x00ff); rc = writeByte(rig, page, addr + 1, v); } return (rc); } /* * /brief Write three bytes to the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Value to write to radio * * \return Number of bytes written, 0 on error. Get error code with getErrno. * */ int write3Bytes(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x) { int rc; unsigned char v = (unsigned char)((x & 0xff0000) >> 16); rc = writeByte(rig, page, addr, v); if (RIG_OK == rc) { v = (unsigned char)((x & 0x00ff00) >> 8); rc = writeByte(rig, page, addr + 1, v); if (RIG_OK == rc) { v = (unsigned char)(x & 0x0000ff); rc = writeByte(rig, page, addr + 2, v); } } return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * /brief Write unsigned int (4 bytes) to the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Value to write to radio * * \return Number of bytes written, 0 on error. Get error code with getErrno. * */ int writeInt(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int x) { int rc; unsigned char v = (unsigned char)((x & 0xff000000) >> 24); rc = writeByte(rig, page, addr, v); if (RIG_OK == rc) { v = (unsigned char)((x & 0x00ff0000) >> 16); rc = writeByte(rig, page, addr + 1, v); if (RIG_OK == rc) { v = (unsigned char)((x & 0x0000ff00) >> 8); rc = writeByte(rig, page, addr + 2, v); if (RIG_OK == rc) { v = (unsigned char)(x & 0x000000ff); rc = writeByte(rig, page, addr + 3, v); } } } return (rc); } #endif /* * /brief Read one byte from the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int readByte(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned char *x) { int rc = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); unsigned char v = RDD(1); // Read command assert(NULL != rig); assert(NULL != x); rc = setAddr(rig, page, addr); if (RIG_OK == rc) { rc = -RIG_EIO; if (0 == write_block(rp, &v, 1)) { if (1 == read_block(rp, x, 1)) { curAddr++; rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%02x\n", __func__, *x); } } } return (rc); } /* * /brief Read an unsigned short (two bytes) from the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int readShort(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned short *x) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); assert(NULL != x); rc = readByte(rig, page, addr, &v); if (RIG_OK == rc) { *x = (unsigned short) v << 8; rc = readByte(rig, page, addr + 1, &v); if (RIG_OK == rc) { *x += (unsigned short) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%04x\n", __func__, *x); } } return (rc); } /* * /brief Read an unsigned int (three bytes) from the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int read3Bytes(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); assert(NULL != x); rc = readByte(rig, page, addr, &v); if (RIG_OK == rc) { *x = (unsigned int) v << 16; rc = readByte(rig, page, addr + 1, &v); if (RIG_OK == rc) { *x += (unsigned int) v << 8; rc = readByte(rig, page, addr + 2, &v); if (RIG_OK == rc) { *x += (unsigned int) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%06x\n", __func__, *x); } } } return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * /brief Read an unsigned int (four bytes) from the receiver * * /param rig Pointer to rig struct * /param page Memory page number (0-4, 15) * /param addr Address offset within page (0-4095, depending on page) * /param x Pointer to value to read from radio * * \return RIG_OK on success, error code on failure * */ int readInt(RIG *rig, enum PAGE_e page, unsigned int addr, unsigned int *x) { int rc = 0; unsigned char v; assert(NULL != rig); assert(NULL != x); rc = readByte(rig, page, addr, &v); if (RIG_OK == rc) { *x = (unsigned int) v << 24; rc = readByte(rig, page, addr + 1, &v); if (RIG_OK == rc) { *x += (unsigned int) v << 16; rc = readByte(rig, page, addr + 2, &v); if (RIG_OK == rc) { *x += (unsigned int) v << 8; rc = readByte(rig, page, addr + 3, &v); { *x += (unsigned int) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: read 0x%08x\n", __func__, *x); } } } } return (rc); } #endif /* * /brief Read raw AGC value from the radio * * /param rig Pointer to rig struct * * \return RIG_OK on success, error code on failure */ int readSignal(RIG *rig, unsigned char *x) { int rc; assert(NULL != rig); assert(NULL != x); rc = execRoutine(rig, READ_SIGNAL); // Read raw AGC value if (RIG_OK == rc) { if (1 == read_block(RIGPORT(rig), x, 1)) { rc = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: raw AGC %03d\n", __func__, *x); } } return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * /brief Flush I/O with radio * * /param rig Pointer to rig struct * */ int flushBuffer(RIG *rig) { int rc = -RIG_EIO; char v = '/'; assert(NULL != rig); if (0 == write_block(RIGPORT(rig), &v, 1)) { rc = RIG_OK; } return (rc); } #endif /* * /brief Lock receiver for remote operations * * /param rig Pointer to rig struct * /param level Lock level (0-3) * */ int lockRx(RIG *rig, enum LOCK_LVL_e level) { int rc = -RIG_EIO; unsigned char v; assert(NULL != rig); if (LOCK_NONE > level) /* valid level? */ { if (curLock != level) /* need to change level? */ { v = LOC(level); if (0 == write_block(RIGPORT(rig), &v, 1)) { rc = RIG_OK; curLock = level; } } else { rc = RIG_OK; } } else { rc = -RIG_EINVAL; } return (rc); } /* * \brief Convert one byte BCD value to int * * \param bcd BCD value (0-99) * * \return Integer value of BCD parameter (0-99), -1 on failure */ int bcd2Int(const unsigned char bcd) { int rc = -1; unsigned char hi = ((bcd & 0xf0) >> 4); unsigned char lo = (bcd & 0x0f); if ((unsigned char) 0x0a > hi) { rc = (int) hi * 10; if ((unsigned char) 0x0a > lo) { rc += (int) lo; } else { rc = -1; } } return (rc); } /* * \brief Convert raw AGC value to calibrated level in dBm * * \param rig Pointer to rig struct * \param rawAgc raw AGC value (0-255) * \param tab Pointer to calibration table struct * \param dbm Pointer to value to hold calibrated level (S9 = 0 dBm) * * \return RIG_OK on success, error code on failure * * To calculate the signal level, table values should be subtracted from * the AGC voltage in turn until a negative value would result. This gives * the rough level from the table position. The accuracy can be improved by * proportioning the remainder into the next table step. See the following * example :- * * A read signal strength operation returns a value of 100 * Subtract cal byte 1 (64) leaves 36 level > -113dBm * Subtract cal byte 2 (10) leaves 26 level > -103dBm * Subtract cal byte 3 (10) leaves 16 level > -93dBm * Subtract cal byte 4 (12) leaves 4 level > -83dBm * Test cal byte 5 (12) - no subtraction * Fine adjustment value = (remainder) / (cal byte 5) * (level step) * = 4 / 12 * 10 = 3dB * Signal level = -83dBm + 3dB = -80dB * * The receiver can operate the RF attenuator automatically if the signal * level is likely to overload the RF stages. Reading the RFAGC byte (page 0, * location 49) gives the attenuation in 10dB steps. This value should be * read and added to the value calculated above. */ int getCalLevel(RIG *rig, unsigned char rawAgc, int *dbm) { int rc = RIG_OK; int i; int raw = (int) rawAgc; int step; unsigned char v; struct rig_state *rs; assert(NULL != rig); assert(NULL != dbm); rs = STATE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: raw AGC %03d\n", __func__, rawAgc); for (i = 0; i < rs->str_cal.size; i++) { *dbm = rs->str_cal.table[ i ].val; rig_debug(RIG_DEBUG_VERBOSE, "%s: got cal table[ %d ] dBm value %d\n", __func__, i, *dbm); /* if the remaining difference in the raw value is negative */ if (0 > (raw - rs->str_cal.table[ i ].raw)) { /* calculate step size */ if (0 < i) { step = rs->str_cal.table[ i ].val - rs->str_cal.table[ i - 1 ].val; } else { step = 20; /* HACK - try and fix minimum AGC readings */ } rig_debug(RIG_DEBUG_VERBOSE, "%s: got step size %d\n", __func__, step); /* interpolate the final value */ *dbm -= step; /* HACK - table seems to be off by one index */ *dbm += (int)(((double) raw / (double) rs->str_cal.table[ i ].raw) * (double) step); rig_debug(RIG_DEBUG_VERBOSE, "%s: interpolated dBm value %d\n", __func__, *dbm); /* we're done, stop going through the table */ break; } else { /* calculate the remaining raw value */ raw = raw - rs->str_cal.table[ i ].raw; rig_debug(RIG_DEBUG_VERBOSE, "%s: residual raw value %d\n", __func__, raw); } } /* Factor in Attenuator/preamp settings */ /* 40 0x028 rxcon 3 bytes Receiver control register mapping */ rc = readByte(rig, WORKING, RXCON, &v); if (RIG_OK == rc) { if (0x80 & v) /* byte 1 bit 7 rx_atn Attenuator enable */ { if (0xa0 & v) { /* HACK - Settings menu on radio says Atten step is 10 dB, not 20 dB */ *dbm += 20; /* byte 1 bit 5 rx_atr Atten : 0 = 20dB / 1 = 40dB */ } else { *dbm += 10; /* byte 1 bit 5 rx_atr Atten : 0 = 20dB / 1 = 40dB */ } } if (0x10 & v) /* byte 1 bit 4 rx_pre Preamplifier enable */ { *dbm -= 10; } rig_debug(RIG_DEBUG_VERBOSE, "%s: RXCON 0x%02x, adjusted dBm value %d\n", __func__, (int) v, *dbm); } /* Adjust to S9 == 0 scale */ *dbm += 73; /* S9 == -73 dBm */ rig_debug(RIG_DEBUG_VERBOSE, "%s: S9 adjusted dBm value %d\n", __func__, *dbm); return (rc); } /* * \brief Get bandwidth of given filter * * \param rig Pointer to rig struct * \param filter Filter number (1-6) * * \return Filter bandwidth in Hz, -1 on failure */ int getFilterBW(RIG *rig, enum FILTER_e filter) { int rc; unsigned char bw; rc = readByte(rig, BBRAM, (FL_BW + ((filter - 1) * 4)), &bw); if (RIG_OK == rc) { rc = bcd2Int(bw) * 100; } else { rig_debug(RIG_DEBUG_ERR, "%s: readByte err: %s\n", __func__, strerror(rc)); return rc; } rig_debug(RIG_DEBUG_VERBOSE, "%s: filter %1d BW %5d\n", __func__, filter, rc); return (rc); } /* * /brief Convert DDS steps to frequency in Hz * * /param steps DDS count * * /return Frequency in Hz or 0 on failure */ freq_t ddsToHz(const unsigned int steps) { freq_t rc = 0.0; rc = ((freq_t) steps * 44545000.0 / 16777216.0); return (rc); } /* * /brief Convert frequency in Hz to DDS steps * * /param freq Frequency in Hz * * /return DDS steps (24 bits) or 0 on failure */ unsigned int hzToDDS(const freq_t freq) { unsigned int rc = 0; double err[3] = { 0.0, 0.0, 0.0 }; rc = (unsigned int)(freq * 16777216.0 / 44545000.0); /* calculate best DDS count based on bletcherous, irrational tuning step of 2.65508890151977539062 Hz/step (actual ratio is 44545000.0 / 16777216.0) */ err[ 0 ] = fabs(freq - ddsToHz((rc - 1))); err[ 1 ] = fabs(freq - ddsToHz(rc)); err[ 2 ] = fabs(freq - ddsToHz((rc + 1))); if (err[ 0 ] < err[ 1 ] && err[ 0 ] < err[ 2 ]) { rc--; } else if (err[ 2 ] < err[ 1 ] && err[ 2 ] < err[ 0 ]) { rc++; } rig_debug(RIG_DEBUG_VERBOSE, "%s: err[0 - 2] = %f %f %f rc 0x%08x\n", __func__, err[ 0 ], err[ 1 ], err[ 2 ], rc); return (rc); } /* * /brief Convert PBS/BFO steps to frequency in Hz * * /param steps PBS/BFO offset steps * * /return Frequency in Hz or 0 on failure * * Max +ve offset is 127, max -ve offset is 128 * Min -ve offset is 255 */ float pbsToHz(const unsigned char steps) { freq_t rc = 0.0; /* treat steps as a 1's complement signed 8-bit number */ if (128 > steps) { rc = (((float) steps * 12.5 * 44545000.0) / 16777216.0); } else { rc = (((float)(~steps & 0x7f) * -12.5 * 44545000.0) / 16777216.0); } rig_debug(RIG_DEBUG_VERBOSE, "%s: raw %d hz %f\n", __func__, steps, rc); return (rc); } #ifdef XXREMOVEDXX // this function is not referenced anywhere /* * /brief Convert PBS/BFO offset frequency in Hz to steps * * /param freq Offset frequency in Hz * * /return steps (8 bits) or 0 on failure */ unsigned char hzToPBS(const float freq) { unsigned char rc; int steps; if (0 < freq) { steps = (((freq + 0.5) * 16777216.0) / (44545000.0 * 12.5)); } else { steps = (((freq - 0.5) * 16777216.0) / (44545000.0 * 12.5)); } rig_debug(RIG_DEBUG_VERBOSE, "%s: steps %d\n", __func__, steps); if (0 <= steps) { rc = (unsigned char)(steps & 0x7f); } else if (-128 < steps) { rc = (unsigned char)(steps + 255); } else { rc = (unsigned char) 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: hz %f rc %d\n", __func__, freq, rc); return (rc); } #endif /* * /brief Convert native Mode to Hamlib mode * * /param mode Native mode value * * /return Hamlib mode value */ rmode_t modeToHamlib(const unsigned char mode) { rmode_t rc = RIG_MODE_NONE; switch (mode) { case AM: rc = RIG_MODE_AM; break; case SAM: rc = RIG_MODE_AMS; break; case FM: rc = RIG_MODE_FM; break; case DATA: rc = RIG_MODE_RTTY; break; case CW: rc = RIG_MODE_CW; break; case LSB: rc = RIG_MODE_LSB; break; case USB: rc = RIG_MODE_USB; break; default: break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Native %s, Hamlib %s\n", __func__, rig_strrmode(mode), rig_strrmode(rc)); return (rc); } /* * /brief Convert Hamlib Mode to native mode * * /param mode Hamlib mode value * * /return Native mode value */ unsigned char modeToNative(const rmode_t mode) { unsigned char rc = (unsigned char) MODE_NONE; switch (mode) { case RIG_MODE_AM: rc = (unsigned char) AM; break; case RIG_MODE_AMS: rc = (unsigned char) SAM; break; case RIG_MODE_FM: rc = (unsigned char) FM; break; case RIG_MODE_RTTY: rc = (unsigned char) DATA; break; case RIG_MODE_CW: rc = (unsigned char) CW; break; case RIG_MODE_LSB: rc = (unsigned char) LSB; break; case RIG_MODE_USB: rc = (unsigned char) USB; break; default: break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Hamlib %s, native %d\n", __func__, rig_strrmode(mode), rc); return (rc); } /* * /brief Convert native AGC speed to Hamlib AGC speed * * /param agc Native AGC speed value * * /return Hamlib AGC speed value */ enum agc_level_e agcToHamlib(const unsigned char agc) { enum agc_level_e rc = RIG_AGC_AUTO; switch (agc) { case AGC_FAST: rc = RIG_AGC_FAST; break; case AGC_MED: rc = RIG_AGC_MEDIUM; break; case AGC_SLOW: rc = RIG_AGC_SLOW; break; case AGC_OFF: rc = RIG_AGC_OFF; break; default: break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Native %d, Hamlib %d\n", __func__, agc, rc); return (rc); } /* * /brief Convert Hamlib AGC speed to native AGC speed * * /param agc Hamlib AGC speed value * * /return Native AGC speed value */ unsigned char agcToNative(const enum agc_level_e agc) { unsigned char rc = (unsigned char) AGC_NONE; switch (agc) { case RIG_AGC_OFF: rc = (unsigned char) AGC_OFF; break; case RIG_AGC_FAST: rc = (unsigned char) AGC_FAST; break; case RIG_AGC_SLOW: rc = (unsigned char) AGC_SLOW; break; case RIG_AGC_MEDIUM: rc = (unsigned char) AGC_MED; break; case RIG_AGC_SUPERFAST: case RIG_AGC_USER: case RIG_AGC_AUTO: default: rc = (unsigned char) AGC_NONE; break; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: Hamlib %d, native %d\n", __func__, agc, rc); return (rc); } /* * /brief Get page size * * /param page Page to get size of * * /return Page size, -1 on error */ int pageSize(const enum PAGE_e page) { int rc = -1; if ((WORKING <= page) && (EEPROM3 >= page)) { rc = (int) AR7030_PAGE_SIZE[ page ]; } else if (ROM == page) { rc = (int) AR7030_PAGE_SIZE[ page ]; } else { rc = -1; } return (rc); } /* * /brief Set and execute IR controller code * * /param code IR code to execute * * \return RIG_OK on success, error code on failure */ int sendIRCode(RIG *rig, enum IR_CODE_e code) { int rc; unsigned char v = (unsigned char) code; assert(NULL != rig); rc = writeByte(rig, WORKING, IRCODE, v); if (RIG_OK == rc) { rc = execRoutine(rig, SET_ALL); if (RIG_OK == rc) { rig_debug(RIG_DEBUG_VERBOSE, "%s: set IR code %d\n", __func__, code); } } return (rc); } hamlib-4.6.2/rigs/aor/README.ar70300000644000175000017500000000264214752216205013230 00000000000000hamlib-1.2.3 aor ar7030.c 2004.11.26 Parameteraenderung fuer USB-Serial //.post_write_delay = 0, //Device: /dev/ttyS0 //.post_write_delay = 85, //Device: /dev/tts/USB0 < 85 sec 'timedout after 0 chars' Befehle mit rigctl # rigctl -m 503 -r /dev/ttyS0 # rigctl -m 503 -r /dev/tts/USB0 Rig command: F Frequency: 0 .. 32016718 Hz Rig command: f Rig command: \get_freq Rig command: M Mode: FM, AMS, AM, USB, LSB, CW, RTTY Passband: 1 - 6 Rig command: m Passband: 800, 2100, 3700, 5200, 9500, XXXX (Value from RX) Hz Rig command: L Level: AF Value: 0.0 - 1.0 Level: RF Value: 0.1, 0.0 -0.1, -0.2, -0.3, -0.4 > +10, 0 ,-10 , -20, -30, -40 dB Level: SQL Value: 0.0 - 1.0 Level: AGC Value: 0 > OFF, 2 > FAST, 3 > SLOW, 5 > MEDIUM Level: CWPITCH Value: -4248 .. 0 .. 4215 Hz Rig command: l Level: AF Level: RF Level: SQL Level: AGC Level: CWPITCH Level: RAWSTR Level: STRENGTH Value: -121dBm ... -23dBm > S1 ... S9 + 50 dB Rig command: \set_powerstat Status: 0 > Power off, 1 > Power on Rig command: \get_powerstat Rig command: \reset Reset: 1 > Software reset Rig command: Quit Q q Rig command: Quit Q Q Rig command: 1 Caps dump for model 503 Friedrich Melchert (DC9RP) hamlib-4.6.2/rigs/aor/ar7030p.c0000644000175000017500000013373514752216205012705 00000000000000/* * Hamlib AOR backend - AR7030 Plus description * Copyright (c) 2000-2010 by Stephane Fillod & Fritz Melchert * Copyright (c) 2009-2010 by Larry Gadallah (VE6VQ) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Version 2009.11.21 Larry Gadallah (VE6VQ) */ #include #include #include #include #include "hamlib/rig.h" #include "ar7030p.h" #include "idx_builtin.h" #define AR7030P_MODES ( RIG_MODE_AM | \ RIG_MODE_SSB | \ RIG_MODE_CW | \ RIG_MODE_RTTY | \ RIG_MODE_FM | \ RIG_MODE_AMS ) #define AR7030P_FUNC ( RIG_FUNC_FAGC | \ RIG_FUNC_NB | \ RIG_FUNC_ANF | \ RIG_FUNC_AIP | \ RIG_FUNC_MN | \ RIG_FUNC_RF | \ RIG_FUNC_LOCK | \ RIG_FUNC_MUTE | \ RIG_FUNC_SQL ) #define AR7030P_LEVEL ( RIG_LEVEL_PREAMP | \ RIG_LEVEL_ATT | \ RIG_LEVEL_AF | \ RIG_LEVEL_RF | \ RIG_LEVEL_SQL | \ RIG_LEVEL_PBT_IN | \ RIG_LEVEL_CWPITCH | \ RIG_LEVEL_NOTCHF | \ RIG_LEVEL_AGC | \ RIG_LEVEL_RAWSTR | \ RIG_LEVEL_STRENGTH ) #define AR7030P_PARM ( RIG_PARM_APO | \ RIG_PARM_TIME | \ RIG_PARM_BAT ) #define AR7030P_VFO_OPS ( RIG_OP_CPY | \ RIG_OP_XCHG | \ RIG_OP_TOGGLE ) #define AR7030P_VFO ( RIG_VFO_A | \ RIG_VFO_B) #define AR7030P_STR_CAL { 8, { \ { 10, -113 }, \ { 10, -103 }, \ { 10, -93 }, \ { 10, -83 }, \ { 10, -73 }, \ { 10, -63 }, \ { 20, -43 }, \ { 20, -23 }, \ } } /* Channel capabilities - Frequency - Mode - Width - Scan lockout - PBT - Squelch - ID */ #define AR7030P_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .funcs = RIG_FUNC_NONE, \ .levels = RIG_LEVEL_SQL | RIG_LEVEL_PBT_IN, \ .flags = 1, \ .channel_desc = 1 \ } struct ar7030p_priv_caps { int max_freq_len; int info_len; int mem_len; int pbs_info_len; int pbs_len; int chan_num; }; static const struct ar7030p_priv_caps ar7030p_priv_caps = { .max_freq_len = 3, .info_len = 14, .mem_len = 17, .pbs_info_len = 1, .pbs_len = 1, .chan_num = 0, }; #define NB_CHAN 400 /* see caps->chan_list */ struct ar7030p_priv_data { vfo_t curr_vfo; vfo_t last_vfo; /* VFO A or VFO B, when in MEM mode */ powerstat_t powerstat; int bank; value_t parms[ RIG_SETTING_MAX ]; channel_t *curr; /* points to vfo_a, vfo_b or mem[] */ channel_t vfo_a; channel_t vfo_b; channel_t mem[ NB_CHAN ]; struct ext_list *ext_parms; }; static const struct confparams ar7030p_ext_levels[] = { { TOK_EL_MAGICLEVEL, "MGL", "Magic level", "Magic level, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { TOK_EL_MAGICFUNC, "MGF", "Magic func", "Magic function, as an example", NULL, RIG_CONF_CHECKBUTTON }, { TOK_EL_MAGICOP, "MGO", "Magic Op", "Magic Op, as an example", NULL, RIG_CONF_BUTTON }, { RIG_CONF_END, NULL, } }; static const struct confparams ar7030p_ext_parms[] = { { TOK_EP_MAGICPARM, "MGP", "Magic parm", "Magic parameter, as an example", NULL, RIG_CONF_NUMERIC, { .n = { 0, 1, .001 } } }, { RIG_CONF_END, NULL, } }; /* TODO - move this somewhere where it belongs */ static unsigned int filterTab[ 6 + 1 ] = { 0 }; static void init_chan(RIG *rig, vfo_t vfo, channel_t *chan) { assert(NULL != rig); assert(NULL != chan); chan->channel_num = 0; chan->vfo = vfo; strcpy(chan->channel_desc, rig_strvfo(vfo)); chan->freq = MHz(10); chan->mode = RIG_MODE_AM; chan->width = rig_passband_normal(rig, RIG_MODE_AM); chan->tuning_step = 110; chan->funcs = (setting_t) 0; memset(chan->levels, 0, RIG_SETTING_MAX * sizeof(value_t)); } static struct ext_list *alloc_init_ext(const struct confparams *cfp) { struct ext_list *elp; int i, nb_ext; assert(NULL != cfp); for (nb_ext = 0; !RIG_IS_EXT_END(cfp[nb_ext]); nb_ext++) { ; } elp = calloc((nb_ext + 1), sizeof(struct ext_list)); if (!elp) { return NULL; } for (i = 0; !RIG_IS_EXT_END(cfp[i]); i++) { elp[i].token = cfp[i].token; /* value reset already by calloc */ } /* last token in array is set to 0 by calloc */ return elp; } #if 0 /* unused; re-enabled as needed. */ static struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token) { int i; for (i = 0; elp[ i ].token != 0; i++) { if (elp[ i ].token == token) { return &(elp[ i ]); } } return NULL; } #endif /* unused */ static int ar7030p_init(RIG *rig) { struct ar7030p_priv_data *priv; int rc = RIG_OK; assert(NULL != rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ar7030p_priv_data *) calloc(1, sizeof(struct ar7030p_priv_data)); if (!priv) { rc = -RIG_ENOMEM; } else { int i; STATE(rig)->priv = (void *) priv; RIGPORT(rig)->type.rig = RIG_PORT_SERIAL; priv->powerstat = RIG_POWER_ON; priv->bank = 0; memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); memset(priv->mem, 0, sizeof(priv->mem)); for (i = 0; i < NB_CHAN; i++) { priv->mem[ i ].channel_num = i; priv->mem[ i ].vfo = RIG_VFO_MEM; priv->mem[ i ].ext_levels = alloc_init_ext(ar7030p_ext_levels); if (!priv->mem[ i ].ext_levels) { rc = -RIG_ENOMEM; break; } } if (RIG_OK == rc) { priv->vfo_a.ext_levels = alloc_init_ext(ar7030p_ext_levels); if (!priv->vfo_a.ext_levels) { return -RIG_ENOMEM; } else { priv->vfo_b.ext_levels = alloc_init_ext(ar7030p_ext_levels); } if (!priv->vfo_b.ext_levels) { return -RIG_ENOMEM; } priv->ext_parms = alloc_init_ext(ar7030p_ext_parms); if (!priv->ext_parms) { return -RIG_ENOMEM; } init_chan(rig, RIG_VFO_A, &priv->vfo_a); init_chan(rig, RIG_VFO_B, &priv->vfo_b); priv->curr = &priv->vfo_a; priv->curr_vfo = priv->last_vfo = RIG_VFO_A; } } return (rc); } static int ar7030p_cleanup(RIG *rig) { struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; int rc = RIG_OK; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (priv == NULL) { return RIG_OK; } for (i = 0; i < NB_CHAN; i++) { free(priv->mem[ i ].ext_levels); } free(priv->vfo_a.ext_levels); free(priv->vfo_b.ext_levels); free(priv->ext_parms); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return (rc); } /* * /brief Open I/O to receiver * * /param rig Pointer to rig struct * * /return 0 on success, < 0 on failure */ static int ar7030p_open(RIG *rig) { int rc = RIG_OK; unsigned char v; struct rig_state *rs; assert(NULL != rig); rs = STATE(rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { int i; /* Load calibration table */ rs->str_cal.size = rig->caps->str_cal.size; for (i = 0; i < rs->str_cal.size; i++) { rc = readByte(rig, EEPROM1, SM_CAL + i, &v); if (RIG_OK != rc) { break; } rs->str_cal.table[ i ].val = rig->caps->str_cal.table[ i ].val; rs->str_cal.table[ i ].raw = (int) v; rig_debug(RIG_DEBUG_VERBOSE, "%s: index %d, val %d, raw %d\n", __func__, i, rs->str_cal.table[ i ].val, rs->str_cal.table[ i ].raw); } if (RIG_OK == rc) { /* Load filter BW table */ for (i = 1; i <= 6; i++) { rc = getFilterBW(rig, i); if (rc < 0) { rig_debug(RIG_DEBUG_ERR, "%s: err in getFilterBW: %s\n", __func__, rigerror(rc)); return rc; } else { filterTab[i] = (unsigned int) rc; } } } rc = lockRx(rig, LOCK_0); rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__); } return (rc); } /* * /brief Close I/O to receiver * * /param rig Pointer to rig struct * * /return 0 on success, < 0 on failure */ // cppcheck-suppress * static int ar7030p_close(RIG *rig) { assert(NULL != rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: \n", __func__); return (RIG_OK); } static const char *ar7030p_get_info(RIG *rig) { static char version[10] = ""; unsigned int i; char *p = &(version[ 0 ]); assert(NULL != rig); for (i = 0; i < pageSize(ROM); i++) { if (RIG_OK != readByte(rig, ROM, i, (unsigned char *) p++)) { p = NULL; break; } } if (NULL != p) { *p++ = '\0'; p = &(version[ 0 ]); rig_debug(RIG_DEBUG_VERBOSE, "%s: ident - %s\n", __func__, version); } return (p); } /* * /brief Set receiver frequency * * /param rig Pointer to rig struct * /param vfo VFO to operate on * /param freq Frequency to set * */ static int ar7030p_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int rc = RIG_OK; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { struct rig_caps *caps = rig->caps; if ((caps->rx_range_list1[ 0 ].endf > freq) && (caps->rx_range_list1[ 0 ].startf < freq)) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_A: rc = write3Bytes(rig, WORKING, FREQU, hzToDDS(freq)); break; case RIG_VFO_B: rc = write3Bytes(rig, WORKING, FREQU_B, hzToDDS(freq)); break; default: rc = -RIG_EINVAL; break; } } else { rc = -RIG_EINVAL; } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = execRoutine(rig, SET_ALL); if (rc == RIG_OK) { rc = lockRx(rig, LOCK_0); } } return (rc); } /* * /brief Get receiver frequency * * /param rig Pointer to rig struct * /param vfo VFO to operate on * /param freq Pointer to hold frequency value (in Hz) * */ static int ar7030p_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int rc = RIG_OK; unsigned int x; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_A: rc = read3Bytes(rig, WORKING, FREQU, &x); if (RIG_OK == rc) { *freq = ddsToHz(x); } break; case RIG_VFO_B: rc = read3Bytes(rig, WORKING, FREQU_B, &x); { *freq = ddsToHz(x); } break; default: rc = -RIG_EINVAL; break; } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * /brief Set receiver mode * * /param rig Pointer to rig struct * /param vfo VFO to operate on * /param mode Mode to set * /param width Bandwidth to set * */ static int ar7030p_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int rc = RIG_OK; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ unsigned char ar_mode = modeToNative(mode); rc = writeByte(rig, WORKING, MODE, ar_mode); if (RIG_OK == rc && width != RIG_PASSBAND_NOCHANGE) { int i; /* TODO - get filter BWs at startup */ unsigned char ar_filter = (unsigned char) 6; for (i = 1; i <= 6; i++) { if (width <= filterTab[ i ]) { if (filterTab[ i ] < filterTab[(int) ar_filter ]) { ar_filter = (unsigned char) i; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: width %d ar_filter %d filterTab[%d] %u\n", __func__, (int)width, ar_filter, i, filterTab[i]); } rc = writeByte(rig, WORKING, FILTER, ar_filter); if (RIG_OK == rc) { rc = execRoutine(rig, SET_ALL); } } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * /brief Get receiver mode and bandwidth * * /param rig Pointer to rig struct * /param vfo VFO to operate on * /param mode Pointer to value to hold mode * /param width Pointer to value to hold bandwidth * */ static int ar7030p_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int rc = RIG_OK; unsigned char bcd_bw; unsigned char m; assert(NULL != rig); assert(NULL != mode); assert(NULL != width); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ rc = readByte(rig, WORKING, MODE, &m); if (RIG_OK == rc) { *mode = modeToHamlib(m); rc = readByte(rig, WORKING, FLTBW, &bcd_bw); if (RIG_OK == rc) { *width = (pbwidth_t)((int) bcd2Int(bcd_bw) * 100); } } rc = lockRx(rig, LOCK_0); } return (rc); } /* * /brief Get memory channel parameters * * /param rig Pointer to rig struct * /param chan Channel number (0-399) * /param freq Pointer to frequency value * /param mode Pointer to mode value (1-7) * /param filt Pointer to filter value (1-6) * /param pbs Pointer to passband tuning value * /param sql Pointer to squelch value (0-255) * /param id Pointer to channel ident string (14 chars) * */ #if 0 /* unused; re-enabled as needed. */ static void ar7030p_get_memory(RIG *rig, const unsigned int chan, double *const freq, unsigned char *const mode, unsigned char *const filt, unsigned char *const pbs, unsigned char *const sql, char *const id) { int rc = RIG_OK; unsigned char v; unsigned int f; unsigned char *p = (unsigned char *) id; int i; assert(NULL != rig); assert(NULL != freq); assert(NULL != mode); assert(NULL != filt); assert(NULL != pbs); assert(NULL != sql); assert(NULL != id); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* Squelch values */ if (100 > chan) { rc = readByte(rig, BBRAM, (MEM_SQ + chan), &v); /* mem_sq */ } else if (176 > chan) { rc = readByte(rig, EEPROM2, (MEX_SQ + (chan * 16)), &v); /* mex_sq */ } else { rc = readByte(rig, EEPROM3, (MEY_SQ + ((chan - 176) * 16)), &v); /* mey_sq */ } if (RIG_OK == rc) { *sql = v; } /* Frequency, mode and filter values */ if (100 > chan) { rc = read3Bytes(rig, EEPROM2, (MEM_FR + (chan * 4)), &f); /* mem_fr */ rc = readByte(rig, EEPROM2, (MEM_MD + (chan * 4)), &v); /* mem_md */ } else { rc = read3Bytes(rig, EEPROM3, (MEX_FR + ((chan - 100) * 4)), &f); /* mex_fr */ rc = readByte(rig, EEPROM3, (MEX_MD + ((chan - 100) * 4)), &v); /* mex_md */ } if (RIG_OK == rc) { *freq = ddsToHz(f); *mode = (v & 0x07); *filt = ((v & 0x70) >> 4); /* lockout = ( ( v & 0x80 ) >> 7 ); */ } /* PBT values */ if (100 > chan) { rc = readByte(rig, EEPROM1, (MEM_PB + chan), &v); /* mem_pb */ } else if (176 > chan) { rc = readByte(rig, EEPROM2, (MEX_PB + (chan * 16)), &v); /* mex_pb */ } else { rc = readByte(rig, EEPROM3, (MEY_PB + ((chan - 176) * 16)), &v); /* mey_pb */ } if (RIG_OK == rc) { *pbs = v; } /* Memory ID values */ for (i = 0; i < 14; i++) { if (176 > chan) { rc = readByte(rig, EEPROM2, (MEX_ID + (chan * 16)), p++); /* mex_id */ } else { rc = readByte(rig, EEPROM3, (MEY_ID + ((chan - 176) * 16)), p++); /* mey_id */ } if (RIG_OK != rc) { p = (unsigned char *) id; break; } } *p++ = '\0'; rc = lockRx(rig, LOCK_0); } } #endif /* unused */ /* * /brief Set receiver levels * * /param rig Pointer to rig struct * /param vfo VFO to operate on * /param level Level to set * /param val Value to set level to * * /return RIG_OK on success */ static int ar7030p_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int rc = RIG_OK; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ switch (level) { unsigned char v; case RIG_LEVEL_PREAMP: /* Scale parameter */ if (10 <= val.i) { v = (unsigned char) 0; } else { v = (unsigned char) 1; } rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */ rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_ATT: /* Scale parameter */ if (10 > val.i) { v = (unsigned char) 1; } else if (20 > val.i) { v = (unsigned char) 2; } else if (40 > val.i) { v = (unsigned char) 3; } else if (80 > val.i) { v = (unsigned char) 4; } else { v = (unsigned char) 5; } rc = writeByte(rig, WORKING, RFGAIN, v); /* rfgain */ rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, val.i, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_AF: /* Scale parameter */ v = (unsigned char)((val.f * (VOL_MAX - VOL_MIN)) + VOL_MIN); v = (v & 0x3f); rc = writeByte(rig, WORKING, AF_VOL, v); /* af_vol */ rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %f (%d)\n", __func__, val.f, v); v = ((v >> 1) & 0x1f); /* half value for L/R volume */ if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLL, v); } /* af_vll */ if (rc == RIG_OK) { rc = writeByte(rig, WORKING, AF_VLR, v); } /* af_vlr */ if (rc == RIG_OK) { rc = execRoutine(rig, SET_AUDIO); } break; case RIG_LEVEL_RF: /* Scale parameter, values 0 (99%) to 130 (3%) */ v = (unsigned char)(134U - ((unsigned int)(val.f * 135.0))); rc = writeByte(rig, WORKING, IFGAIN, v); /* ifgain */ rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_SQL: /* Scale parameter */ v = (unsigned char)(val.f * 255.0); rc = writeByte(rig, WORKING, SQLVAL, v); /* sqlval */ rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_PBT_IN: /* Scale parameter */ v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5)); rc = writeByte(rig, WORKING, PBSVAL, v); /* pbsval */ rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_CWPITCH: /* Scale parameter */ v = (unsigned char)(val.f / (HZ_PER_STEP * 12.5)); rc = writeByte(rig, WORKING, BFOVAL, v); /* bfoval */ rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %f (%d)\n", __func__, val.f, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; case RIG_LEVEL_NOTCHF: rc = -RIG_ENIMPL; break; case RIG_LEVEL_AGC: /* Scale parameter */ v = agcToNative(val.i); rc = writeByte(rig, WORKING, AGCSPD, v); /* agcspd */ rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n", __func__, val.i, v); if (rc == RIG_OK) { rc = execRoutine(rig, SET_ALL); } break; default: rc = -RIG_EINVAL; break; } // this RIG_OK check added to clear cppcheck warnings // not sure if it's needed but seem like RIG_OK should be expected // if this debug prints out when things are working need to reexamine if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected error?? %s\n", __func__, rigerror(rc)); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * /brief Get receiver levels * * /param rig Pointer to rig struct * /param vfo VFO to operate on * /param level Level to get * /param val Pointer to value to get * * /return RIG_OK on success */ static int ar7030p_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int rc = RIG_OK; unsigned char v; unsigned short s = 0; int i; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* TODO - deal with selected VFO */ switch (level) { case RIG_LEVEL_PREAMP: rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */ if (RIG_OK == rc) { /* Scale parameter */ if (0 == v) { val->i = 10; } else { val->i = 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, v, val->i); } break; case RIG_LEVEL_ATT: rc = readByte(rig, WORKING, RFGAIN, &v); /* rfgain */ if (RIG_OK == rc) { /* Scale parameter */ switch (v) { case 2: val->i = 10; break; case 3: val->i = 20; break; case 4: val->i = 40; break; default: case 0: case 1: val->i = 0; }; rig_debug(RIG_DEBUG_VERBOSE, "%s: rfgain %d (%d)\n", __func__, v, val->i); } break; case RIG_LEVEL_AF: rc = readByte(rig, WORKING, AF_VOL, &v); /* af_vol */ if (RIG_OK == rc) { /* Scale parameter */ v = (v & 0x3f); val->f = (((float) v - VOL_MIN) / (VOL_MAX - VOL_MIN)); rig_debug(RIG_DEBUG_VERBOSE, "%s: af_vol %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_RF: rc = readByte(rig, WORKING, IFGAIN, &v); /* ifgain */ if (RIG_OK == rc) { /* Scale parameter, values 0 (99%) to 130 (3%) */ val->f = ((float)(134 - v) / 135.0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ifgain %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_SQL: rc = readByte(rig, WORKING, SQLVAL, &v); /* sqlval */ if (RIG_OK == rc) { /* Scale parameter */ val->f = ((float)(v) / 255.0); rig_debug(RIG_DEBUG_VERBOSE, "%s: sqlval %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_PBT_IN: rc = readByte(rig, WORKING, PBSVAL, &v); /* pbsval */ if (RIG_OK == rc) { /* Scale parameter */ if (127 < v) { v = v | 0xffffff00; } val->f = ((float)(v) * HZ_PER_STEP * 12.5); rig_debug(RIG_DEBUG_VERBOSE, "%s: pbsval %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_CWPITCH: rc = readByte(rig, WORKING, BFOVAL, &v); /* bfoval */ if (RIG_OK == rc) { /* Scale parameter */ if (127 < v) { v = v | 0xffffff00; } val->f = ((float)(v) * HZ_PER_STEP * 12.5); rig_debug(RIG_DEBUG_VERBOSE, "%s: bfoval %d (%f)\n", __func__, v, val->f); } break; case RIG_LEVEL_NOTCHF: rc = readShort(rig, WORKING, NCHFR, &s); /* nchfr */ if (RIG_OK == rc) { unsigned int x = (unsigned int) s; /* Scale parameter */ val->i = (int)((float)(x) / NOTCH_STEP_HZ); rig_debug(RIG_DEBUG_VERBOSE, "%s: nchfr %u (%d)\n", __func__, x, val->i); } break; case RIG_LEVEL_AGC: rc = readByte(rig, WORKING, AGCSPD, &v); /* agcspd */ if (RIG_OK == rc) { /* Scale parameter */ val->i = agcToHamlib(v); rig_debug(RIG_DEBUG_VERBOSE, "%s: agcspd %d (%d)\n", __func__, v, val->i); } break; case RIG_LEVEL_RAWSTR: rc = readSignal(rig, &v); if (RIG_OK == rc) { val->i = (int) v; } break; case RIG_LEVEL_STRENGTH: rc = readSignal(rig, &v); if (RIG_OK == rc) { rc = getCalLevel(rig, v, &i); if (RIG_OK == rc) { val->i = i; } } break; default: rc = -RIG_EINVAL; } if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); } } return (rc); } static int ar7030p_set_vfo(RIG *rig, vfo_t vfo) { int rc = RIG_OK; struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; switch (vfo) { case RIG_VFO_B: if (RIG_VFO_B != priv->curr_vfo) { rc = sendIRCode(rig, IR_VFO); if (RIG_OK == rc) { priv->curr_vfo = RIG_VFO_B; priv->last_vfo = RIG_VFO_A; } } break; case RIG_VFO_A: case RIG_VFO_CURR: if (RIG_VFO_A != priv->curr_vfo) { rc = sendIRCode(rig, IR_VFO); if (RIG_OK == rc) { priv->curr_vfo = RIG_VFO_A; priv->last_vfo = RIG_VFO_B; } } break; default: rc = -RIG_EINVAL; break; } return (rc); } static int ar7030p_get_vfo(RIG *rig, vfo_t *vfo) { int rc = RIG_OK; struct ar7030p_priv_data const *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; assert(NULL != vfo); *vfo = priv->curr_vfo; return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_set_parm(RIG *rig, setting_t parm, value_t val) { int rc = -RIG_ENIMPL; assert(NULL != rig); switch (parm) { case RIG_PARM_APO: break; case RIG_PARM_TIME: break; case RIG_PARM_BAT: break; default: break; }; return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_get_parm(RIG *rig, setting_t parm, value_t *val) { int rc = -RIG_ENIMPL; assert(NULL != rig); assert(NULL != val); switch (parm) { case RIG_PARM_APO: break; case RIG_PARM_TIME: break; case RIG_PARM_BAT: break; default: break; }; return (rc); } static int ar7030p_set_mem(RIG *rig, vfo_t vfo, int ch) { int rc = RIG_OK; struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; if (RIG_VFO_MEM == priv->curr_vfo) { priv->curr = &priv->mem[ ch ]; } else { priv->curr->channel_num = ch; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, ch); return (rc); } static int ar7030p_get_mem(RIG *rig, vfo_t vfo, int *ch) { int rc = RIG_OK; struct ar7030p_priv_data const *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; const channel_t *curr = priv->curr; assert(NULL != ch); *ch = curr->channel_num; rig_debug(RIG_DEBUG_VERBOSE, "%s: ch %d\n", __func__, *ch); return (rc); } static int ar7030p_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int rc = -RIG_ENIMPL; assert(NULL != rig); switch (op) { case RIG_OP_CPY: rc = -RIG_ENIMPL; break; case RIG_OP_XCHG: rc = -RIG_ENIMPL; break; case RIG_OP_TOGGLE: rc = sendIRCode(rig, IR_VFO); break; default: break; }; return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { int rc = -RIG_ENIMPL; assert(NULL != rig); return (rc); } static int ar7030p_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); assert(NULL != dcd); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { rc = readByte(rig, WORKING, BITS + 2, &v); if (RIG_OK == rc) { if ((v & 0x02)) { if ((v & 0x01)) /* low bit set if Squelch is NOT active/open */ { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } } else { *dcd = RIG_DCD_ON; } } rc = lockRx(rig, LOCK_0); } return (rc); } static int ar7030p_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int rc = RIG_OK; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { /* Scale parameter */ unsigned short v = (unsigned short)((double)(ts + 1) / HZ_PER_STEP); rc = writeShort(rig, WORKING, CHNSTP, v); /* chnstp */ if (RIG_OK == rc) { rc = execRoutine(rig, SET_ALL); rig_debug(RIG_DEBUG_VERBOSE, "%s: chnstp %d (%d)\n", __func__, (int)ts, v); } if (RIG_OK == rc) { rc = lockRx(rig, LOCK_0); } } return (rc); } /* * /brief Get receiver tuning step size * * /param rig Pointer to rig struct * /param vfo VFO to operate on * /param ts Pointer to tuning step value * * /return RIG_OK on success */ static int ar7030p_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int rc = RIG_OK; unsigned short v; assert(NULL != rig); assert(NULL != ts); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { rc = readShort(rig, WORKING, CHNSTP, &v); /* chnstp */ if (RIG_OK == rc) { double x = (double) v; *ts = (shortfreq_t)(x * HZ_PER_STEP); rig_debug(RIG_DEBUG_VERBOSE, "%s: step= %d\n", __func__, (int)*ts); } rc = lockRx(rig, LOCK_0); } return (rc); } /* * /brief Set receiver power status * * /param rig Pointer to rig struct * /param status Power status to set * * /return RIG_OK on success */ static int ar7030p_set_powerstat(RIG *rig, powerstat_t status) { int rc; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { switch (status) { case RIG_POWER_OFF: break; case RIG_POWER_ON: break; default: break; } lockRx(rig, LOCK_0); } return (-RIG_ENIMPL); } /* * /brief Get receiver power status * * /param rig Pointer to rig struct * /param status Pointer to power status value * * /return RIG_OK on success */ static int ar7030p_get_powerstat(RIG *rig, powerstat_t *status) { int rc = RIG_OK; unsigned char v; assert(NULL != rig); rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { rc = readByte(rig, WORKING, PDFLGS, &v); if (RIG_OK == rc) { if (0 == (v & 0x01)) { *status = RIG_POWER_OFF; } else { *status = RIG_POWER_ON; } } rc = lockRx(rig, LOCK_0); } return (rc); } /* * /brief Reset receiver * * /param rig Pointer to rig struct * /param reset Reset operation to perform * * /return RIG_OK on success */ static int ar7030p_reset(RIG *rig, reset_t reset) { int rc = RIG_OK; assert(NULL != rig); switch (reset) { case RIG_RESET_SOFT: rc = execRoutine(rig, RESET); break; default: rc = -RIG_EINVAL; } return (rc); } // cppcheck-suppress constParameterCallback static int ar7030p_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { assert(NULL != rig); return (-RIG_ENIMPL); } // cppcheck-suppress constParameterCallback static int ar7030p_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { assert(NULL != rig); assert(NULL != status); *status = 0; return (-RIG_ENIMPL); } // cppcheck-suppress constParameterCallback static int ar7030p_decode_event(RIG *rig) { assert(NULL != rig); return (-RIG_ENIMPL); } // cppcheck-suppress constParameterCallback static int ar7030p_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { assert(NULL != rig); assert(NULL != chan); return (-RIG_ENIMPL); } static int ar7030p_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int rc = RIG_OK; unsigned char v; unsigned int f; unsigned char *p = NULL; int ch; const struct ar7030p_priv_data *priv = (struct ar7030p_priv_data *) STATE(rig)->priv; const channel_t *curr = priv->curr; assert(NULL != chan); ch = curr->channel_num; rc = lockRx(rig, LOCK_1); if (RIG_OK == rc) { int i; /* Squelch values */ /* TODO - fix magic numbers */ if (100 > ch) { rc = readByte(rig, BBRAM, (MEM_SQ + ch), &v); /* mem_sq */ } else if (176 > ch) { rc = readByte(rig, EEPROM2, (MEX_SQ + (ch * 16)), &v); /* mex_sq */ } else { rc = readByte(rig, EEPROM3, (MEY_SQ + ((ch - 176) * 16)), &v); /* mey_sq */ } if (RIG_OK == rc) { chan->levels[ LVL_SQL ].f = (float) v / 255.0; } /* Frequency, mode and filter values */ if (100 > ch) { rc = read3Bytes(rig, EEPROM1, (MEM_FR + (ch * 4)), &f); /* mem_fr */ if (RIG_OK == rc) { rc = readByte(rig, EEPROM1, (MEM_MD + (ch * 4)), &v); } /* mem_md */ } else { rc = read3Bytes(rig, EEPROM2, (MEX_FR + ((ch - 100) * 4)), &f); /* mex_fr */ if (RIG_OK == rc) { rc = readByte(rig, EEPROM2, (MEX_MD + ((ch - 100) * 4)), &v); } /* mex_md */ } if (RIG_OK == rc) { chan->freq = ddsToHz(f); chan->mode = modeToHamlib((v & 0x07)); chan->width = getFilterBW(rig, ((v & 0x70) >> 4)); if ((v & 0x80) >> 7) { chan->flags = RIG_CHFLAG_SKIP; } else { chan->flags = RIG_CHFLAG_NONE; } } /* PBT values */ if (100 > ch) { rc = readByte(rig, EEPROM1, (MEM_PB + ch), &v); /* mem_pb */ } else if (176 > ch) { rc = readByte(rig, EEPROM2, (MEX_PB + (ch * 16)), &v); /* mex_pb */ } else { rc = readByte(rig, EEPROM3, (MEY_PB + ((ch - 176) * 16)), &v); /* mey_pb */ } if (RIG_OK == rc) { chan->levels[ LVL_PBT_IN ].f = pbsToHz(v); } /* Memory ID values */ p = (unsigned char *) chan->channel_desc; for (i = 0; i < 14; i++) { if (176 > ch) { rc = readByte(rig, EEPROM2, (MEX_ID + (ch * 16) + i), p++); /* mex_id */ } else { rc = readByte(rig, EEPROM3, (MEY_ID + ((ch - 176) * 16) + i), p++); /* mey_id */ } if (RIG_OK != rc) { p = (unsigned char *) chan->channel_desc; break; } } *p++ = '\0'; rc = lockRx(rig, LOCK_0); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return (rc); } struct rig_caps ar7030p_caps = { RIG_MODEL(RIG_MODEL_AR7030P), .model_name = "AR7030 Plus", .mfg_name = "AOR", .version = "20200319.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 12, .timeout = 650, .retry = 0, .has_get_func = AR7030P_FUNC, .has_set_func = AR7030P_FUNC, .has_get_level = AR7030P_LEVEL, .has_set_level = RIG_LEVEL_SET(AR7030P_LEVEL), .has_get_parm = AR7030P_PARM, .has_set_parm = RIG_PARM_SET(AR7030P_PARM), .level_gran = { [LVL_PREAMP] = {.min = {.i = 0}, .max = {.i = 10} }, [LVL_ATT] = {.min = {.i = 0}, .max = {.i = 20} }, [LVL_RF] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, [LVL_AF] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, [LVL_SQL] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, [LVL_IF] = {.min = {.i = 255}, .max = {.i = 0} }, [LVL_PBT_IN] = {.min = {.f = -4248.0}, .max = {.f = 4248.0} }, [LVL_CWPITCH] = {.min = {.i = -4248}, .max = {.i = 4248} }, [LVL_NOTCHF] = {.min = {.i = 0}, .max = {.i = 10000} }, [LVL_AGC] = {.min = {.i = 0}, .max = {.i = 10} }, [LVL_BALANCE] = {.min = {.f = -1.0}, .max = {.f = 1.0} }, [LVL_RAWSTR] = {.min = {.i = 0}, .max = {.i = 255} }, [LVL_STRENGTH] = {.min = {.i = 0}, .max = {.i = 255} }, }, .extparms = NULL, .extlevels = NULL, .parm_gran = { [PARM_APO] = {.min = {.i = 1}, .max = {.i = 86400} }, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86400} }, [PARM_BAT] = {.min = {.f = 0.0}, .max = {.f = 1.0} }, }, .preamp = {10, RIG_DBLST_END,}, .attenuator = {10, 20, RIG_DBLST_END,}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(4248), .announces = RIG_ANN_NONE, .vfo_ops = AR7030P_VFO_OPS, .scan_ops = RIG_SCAN_STOP | RIG_SCAN_MEM | RIG_SCAN_VFO, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 14, .chan_list = {{0, 399, RIG_MTYPE_MEM, AR7030P_MEM_CAP}, RIG_CHAN_END,}, .rx_range_list1 = { { kHz(10), kHz(32010), AR7030P_MODES, -1, -1, AR7030P_VFO }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { { kHz(10), kHz(32010), AR7030P_MODES, -1, -1, AR7030P_VFO }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {AR7030P_MODES, Hz(10)}, {AR7030P_MODES, Hz(20)}, {AR7030P_MODES, Hz(50)}, {AR7030P_MODES, Hz(100)}, {AR7030P_MODES, Hz(200)}, {AR7030P_MODES, Hz(500)}, {AR7030P_MODES, kHz(1)}, {AR7030P_MODES, kHz(2)}, {AR7030P_MODES, kHz(5)}, {AR7030P_MODES, kHz(6.25)}, {AR7030P_MODES, kHz(9)}, {AR7030P_MODES, kHz(10)}, {AR7030P_MODES, Hz(12500)}, {AR7030P_MODES, kHz(20)}, {AR7030P_MODES, kHz(25)}, RIG_TS_END, }, .filters = { {RIG_MODE_FM, kHz(9.5)}, {RIG_MODE_FM, kHz(0)}, {RIG_MODE_FM, kHz(0)}, {RIG_MODE_AMS, kHz(6.5)}, {RIG_MODE_AMS, kHz(5.3)}, {RIG_MODE_AMS, kHz(9.5)}, {RIG_MODE_AM, kHz(5.3)}, {RIG_MODE_AM, kHz(3.7)}, {RIG_MODE_AM, kHz(6.5)}, {RIG_MODE_SSB, kHz(2.0)}, {RIG_MODE_SSB, kHz(1.4)}, {RIG_MODE_SSB, kHz(3.7)}, {RIG_MODE_CW, kHz(1.4)}, {RIG_MODE_CW, kHz(0)}, {RIG_MODE_CW, kHz(2.0)}, {RIG_MODE_RTTY, kHz(1.4)}, {RIG_MODE_RTTY, kHz(0)}, {RIG_MODE_RTTY, kHz(2.0)}, RIG_FLT_END, }, .str_cal = AR7030P_STR_CAL, .cfgparams = NULL, .priv = (void *)& ar7030p_priv_caps, .rig_init = ar7030p_init, .rig_cleanup = ar7030p_cleanup, .rig_open = ar7030p_open, .rig_close = ar7030p_close, .set_freq = ar7030p_set_freq, .get_freq = ar7030p_get_freq, .set_mode = ar7030p_set_mode, .get_mode = ar7030p_get_mode, .set_vfo = ar7030p_set_vfo, .get_vfo = ar7030p_get_vfo, .get_dcd = ar7030p_get_dcd, .set_ts = ar7030p_set_ts, .get_ts = ar7030p_get_ts, .set_powerstat = ar7030p_set_powerstat, .get_powerstat = ar7030p_get_powerstat, .reset = ar7030p_reset, .set_level = ar7030p_set_level, .get_level = ar7030p_get_level, .set_func = ar7030p_set_func, .get_func = ar7030p_get_func, .set_parm = ar7030p_set_parm, .get_parm = ar7030p_get_parm, .set_ext_level = RIG_FUNC_NONE, .get_ext_level = RIG_FUNC_NONE, .set_ext_parm = RIG_FUNC_NONE, .get_ext_parm = RIG_FUNC_NONE, .set_conf = RIG_FUNC_NONE, .get_conf = RIG_FUNC_NONE, .set_mem = ar7030p_set_mem, .get_mem = ar7030p_get_mem, .vfo_op = ar7030p_vfo_op, .scan = ar7030p_scan, .decode_event = ar7030p_decode_event, .set_channel = ar7030p_set_channel, .get_channel = ar7030p_get_channel, .get_info = ar7030p_get_info, .set_chan_all_cb = RIG_FUNC_NONE, .get_chan_all_cb = RIG_FUNC_NONE, .set_mem_all_cb = RIG_FUNC_NONE, .get_mem_all_cb = RIG_FUNC_NONE, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/aor/ar7030.c0000644000175000017500000006632414752216205012524 00000000000000/* * Hamlib AOR backend - AR7030 description * Copyright (c) 2000-2006 by Stephane Fillod & Fritz Melchert * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // // Version 2004.12.13 F.Melchert (DC9RP) // Version 2004.11.29 F.Melchert (DC9RP) // #include #include #include "serial.h" #include "idx_builtin.h" /* * Maintainer wanted! * * TODO: * - everything: this rig has nothing in common with other aor's. * * set_mem, get_mem, set_channel, get_channel */ #define AR7030_MODES (RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define AR7030_FUNC_ALL (RIG_FUNC_NONE) #define AR7030_LEVEL (RIG_LEVEL_AF | RIG_LEVEL_RF | RIG_LEVEL_SQL | RIG_LEVEL_CWPITCH | RIG_LEVEL_RAWSTR | RIG_LEVEL_AGC | RIG_LEVEL_STRENGTH) #define AR7030_PARM (RIG_PARM_NONE) #define AR7030_VFO_OPS (RIG_OP_NONE) #define AR7030_VFO (RIG_VFO_A|RIG_VFO_B) /* * Data was obtained from AR7030 pdf on http://www.aoruk.com */ /**************************************************************************** * Misc Routines * ****************************************************************************/ static int rxr_writeByte(RIG *rig, unsigned char c) { return write_block(RIGPORT(rig), &c, 1); } static int rxr_readByte(RIG *rig) { unsigned char response[1]; const unsigned char buf[] = {0x71}; // Read command int retval; retval = write_block(RIGPORT(rig), buf, 1); if (retval != RIG_OK) { return retval; } retval = read_block(RIGPORT(rig), response, 1); if (retval != RIG_OK) { return retval; } return response[0]; } /*! Umwandlung von BCD nach char */ static int BCD_To_int(RIG *rig, int c) { if (((c & 0x0F) < 0x0a) && ((c & 0xF0) < 0xa0)) // Test pseudo Tetrade { return (((c >> 4) * 10) + (c & 0x0F)); } return (-1); }// End of method BCD_To_char( /**************************************************************************** * Routines to set receiver lock levels * ****************************************************************************/ /*! Locks, or unlocks if called with argument 0, the receiver, disabling the front panel controls or updates. The level of locking is determined by the argument level which may be in the range 0 (no lock) to 3 (Remote operation exclusively). Calling the method without arguments sets the lock level to 1. It is recommended to lock to this level during any multi byte read or writes to prevent data contention between internal and remote access. Calls with invalid arguments are ignored. */ static void unlock(RIG *rig) { rxr_writeByte(rig, 0x80); } // Level 1 = 0x81 IR remote control disabled. // Front panel buttons ignored. // Front panel spin-wheels logged but not actioned. // Display update (frequency & S-meter) continues. static void setLock(RIG *rig, int level) { if ((0 <= level) && (level <= 3)) { rxr_writeByte(rig, 0x80 + level); } } // Level 2 = 0x82 As level 1, but display update suspended. In revisions before 1.4 // squelch operation is inhibited, which results in no audio output // after a mode change. In revision 1.4 squelch operation continues // and mode changing is as expected. // Level 3 = 0x83 Remote operation exclusively. static void setMemPtr(RIG *rig, int page, int address) { rxr_writeByte(rig, 0x50 + page); //Set Page if (address <= 0xFF) //*** <= 8 Bit Address *** { rxr_writeByte(rig, 0x30 + (address >> 4)); //Set H-Register 4 Bits rxr_writeByte(rig, 0x40 + (address & 0x0F)); //Set Address(12 Bits = (4 Bit H Register) + 8 Bit) } else //*** > 8 Bit Address *** { rxr_writeByte(rig, 0x30 + ((address >> 4) & 0x0F)) ;//Set H-Register 4 Bits rxr_writeByte(rig, 0x40 + (address & 0x0F)); //Set Address(12 Bits = (4 Bit H Register) + 8 Bit) rxr_writeByte(rig, 0x10 + (address >> 8)); //Set Address high(12 Bits=(4 Bit H Register)+8 Bit) } } /**************************************************************************** * Routines * ****************************************************************************/ // Routine 0 Reset Setup receiver as at switch-on. static void Execute_Routine_0(RIG *rig) { //setLock(rig, 1); //Set Lock Level rxr_writeByte(rig, 0x20); //unlock(rig); //Set UnLock Level } // Routine 1 Set frequency Program local oscillator from frequ area and setup // RF filters and oscillator range. // Routine 2 Set mode Setup from mode byte in memory and display mode, // select preferred filter and PBS, BFO values etc. // currently not used #if 0 static void Execute_Routine_2_1(RIG *rig, char mp, char ad, int numSteps) { setLock(rig, 1); //Set Lock Level setMemPtr(rig, mp, ad); //page, address rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 4))); rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); rxr_writeByte(rig, 0x22); unlock(rig); //Set UnLock Level } #endif // Routine 3 Set passband Setup all IF parameters from filter, pbsval and bfoval bytes. static void Execute_Routine_3_1(RIG *rig, char mp, char ad, unsigned int numSteps) { setLock(rig, 1); //Set Lock Level setMemPtr(rig, mp, ad); //page, address rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 4))); rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); rxr_writeByte(rig, 0x23); unlock(rig); //Set UnLock Level } // Routine 4 Set all Set all receiver parameters from current memory values static void Execute_Routine_4_1(RIG *rig, char mp, char ad, int numSteps) { setLock(rig, 1); //Set Lock Level setMemPtr(rig, mp, ad); //page, address // 0x30 = Set H-register x ---> H-register (4-bits) // The high order 4-bits of each byte sent to the receiver is the operation code, // the low order 4-bits is data (shown here as x) rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 4))); // 0x60 = Write data Hx // ---> [Page, Address] Address register + 1 // ---> Address register 0 // ---> H-register, 0 // ---> Mask register rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); //Execute routine //Set all Set all receiver parameters from current memory values rxr_writeByte(rig, 0x24); unlock(rig); //Set UnLock Level } static void Execute_Routine_4_3(RIG *rig, char mp, char ad, int numSteps) { setLock(rig, 1); //Set Lock Level setMemPtr(rig, mp, ad); //page, address rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 20))); rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps >> 16))); rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 12))); rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps >> 8))); rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 4))); rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); //Execute routine //Set all Set all receiver parameters from current memory values rxr_writeByte(rig, 0x24); unlock(rig); //Set UnLock Level } // Routine 5 Set audio Setup audio controller from memory register values. // currently not used #if 0 static void Execute_Routine_5_1(RIG *rig, char mp, char ad, int numSteps) { setLock(rig, 1); //Set Lock Level setMemPtr(rig, mp, ad); //page, address rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 4))); rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); rxr_writeByte(rig, 0x25); unlock(rig); //Set UnLock Level } #endif // Routine 6 Set RF-IF Setup RF Gain, IF Gain and AGC speed. Also sets Notch Filter and // Noise Blanker if these options are fitted. static void Execute_Routine_6_1(RIG *rig, char mp, char ad, int numSteps) { setLock(rig, 1); //Set Lock Level setMemPtr(rig, mp, ad); //page, address rxr_writeByte(rig, 0x30 | (0x0F & (char)(numSteps >> 4))); rxr_writeByte(rig, 0x60 | (0x0F & (char)(numSteps))); rxr_writeByte(rig, 0x26); unlock(rig); //Set UnLock Level } // Routine 14 Read signal strength // Transmits byte representing received signal strength (read from AGC voltage). // Output is 8-bit binary in range 0 to 255. static int Execute_Routine_14(RIG *rig) { unsigned char response[1]; hamlib_port_t *rp = RIGPORT(rig); const unsigned char buf[] = {0x2e}; // Read command int retval; retval = write_block(rp, buf, 1); if (retval != RIG_OK) { return retval; } retval = read_block(rp, response, 1); if (retval != RIG_OK) { return retval; } return response[0]; } // Operate button x // Button codes :- // 0 = None pressed 5 = RF-IF button // 1 = Mode up button 6 = Memory button // 2 = Mode down button 7 = * button // 3 = Fast button 8 = Menu button // 4 = Filter button 9 = Power button static void Execute_Operate_button(RIG *rig, char button) { // setLock(rig, 1); //Set Lock Level rxr_writeByte(rig, 0xa0 | (0x0F & button)); // unlock(rig); //Set UnLock Level } static int ar7030_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { // frequ Mem_Page=0 Address=1A // 3 bytes 24-bit tuned frequency, value is 376635.2228 / MHz freq = freq * .3766352228; if (freq < 0) {freq = 0;} if (freq > 12058624) {freq = 12058624;} Execute_Routine_4_3(rig, 0, 0x1a, freq); return RIG_OK; } static int ar7030_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { // frequ Mem_Page=0 Address=1A // 3 bytes 24-bit tuned frequency, value is 376635.2228 / MHz unsigned int frequ_i = 0; setMemPtr(rig, 0, 0x1a); frequ_i = (int)(rxr_readByte(rig) << 16); frequ_i = frequ_i + (int)(rxr_readByte(rig) << 8); frequ_i = frequ_i + (int)(rxr_readByte(rig)); *freq = ((float)(frequ_i) * 2.65508890157896); return RIG_OK; } /*! Current mode :- RIG_MODE_NONE = 0, < None 1 = AM RIG_MODE_AM = (1<<0), < Amplitude Modulation 5 = CW RIG_MODE_CW = (1<<1), < CW 7 = USB RIG_MODE_USB = (1<<2), < Upper Side Band 6 = LSB RIG_MODE_LSB = (1<<3), < Lower Side Band 4 = Data RIG_MODE_RTTY = (1<<4), < Remote Teletype 3 = NFM RIG_MODE_FM = (1<<5), < "narrow" band FM RIG_MODE_WFM = (1<<6), < broadcast wide FM RIG_MODE_CWR = (1<<7), < CW reverse sideband RIG_MODE_RTTYR = (1<<8), < RTTY reverse sideband 2 = Sync RIG_MODE_AMS = (1<<9), < Amplitude Modulation Synchronous RIG_MODE_PKTLSB = (1<<10),< Packet/Digital LSB mode (dedicated port) RIG_MODE_PKTUSB = (1<<11),< Packet/Digital USB mode (dedicated port) RIG_MODE_PKTFM = (1<<12),< Packet/Digital FM mode (dedicated port) RIG_MODE_ECSSUSB = (1<<13),< Exalted Carrier Single Sideband USB RIG_MODE_ECSSLSB = (1<<14),< Exalted Carrier Single Sideband LSB RIG_MODE_FAX = (1<<15) < Facsimile Mode */ static int ar7030_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int filter_num; // mode Mem_Page=0 Address=1D // Current mode :- 1 = AM 4 = Data 2 = Sync 5 = CW 3 = NFM 6 = LSB 7 = USB. switch (mode) { case RIG_MODE_AM : Execute_Routine_4_1(rig, 0, 0x1d, 1); break; case RIG_MODE_AMS : Execute_Routine_4_1(rig, 0, 0x1d, 2); break; case RIG_MODE_FM : Execute_Routine_4_1(rig, 0, 0x1d, 3); break; case RIG_MODE_RTTY : Execute_Routine_4_1(rig, 0, 0x1d, 4); break; case RIG_MODE_CW : Execute_Routine_4_1(rig, 0, 0x1d, 5); break; case RIG_MODE_LSB : Execute_Routine_4_1(rig, 0, 0x1d, 6); break; case RIG_MODE_USB : Execute_Routine_4_1(rig, 0, 0x1d, 7); break; default : return -RIG_EINVAL; } if (RIG_PASSBAND_NOCHANGE == width) { return RIG_OK; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } /* * pass-through values 1..6, as filter number * Otherwise find out filter number from passband width */ if (width <= 6) { filter_num = width; } else { if (width <= 800) { filter_num = 1; } else if (width <= 2100) { filter_num = 2; } else if (width <= 3700) { filter_num = 3; } else if (width <= 5200) { filter_num = 4; } else if (width <= 9500) { filter_num = 5; } else { filter_num = 6; } } // filter Mem_Page=0 Address=34 // Current filter number (1 to 6). Execute_Routine_4_1(rig, 0, 0x34, filter_num); return RIG_OK; } static int ar7030_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { // mode Mem_Page=0 Address=1D // Current mode :- 1 = AM 4 = Data 2 = Sync 5 = CW 3 = NFM 6 = LSB 7 = USB. setMemPtr(rig, 0, 0x1d); switch (rxr_readByte(rig)) { case 1: *mode = RIG_MODE_AM; break; case 2: *mode = RIG_MODE_AMS; break; case 3: *mode = RIG_MODE_FM; break; case 4: *mode = RIG_MODE_RTTY; break; case 5: *mode = RIG_MODE_CW; break; case 6: *mode = RIG_MODE_LSB; break; case 7: *mode = RIG_MODE_USB; break; default : return -RIG_EINVAL; } // fltbw Mem_Page=0 Address=38 // Filter bandwidth dezimal in Hz. // Filter bandwidth (2 BCD digits : x.x kHz). setMemPtr(rig, 0, 0x38); if ((*width = (pbwidth_t)BCD_To_int(rig, rxr_readByte(rig)) * 100) < 0) { return -RIG_EINVAL; } return RIG_OK; } static int ar7030_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { switch (level) { case RIG_LEVEL_AF : // af_vol Mem_Page=0 Address=1E // Main channel volume (6-bits, values 15 to 63) val.f = (val.f * 50) + 15; if (val.f < 15) {val.f = 15;} if (val.f > 63) {val.f = 63;} Execute_Routine_4_1(rig, 0, 0x1e, val.f); return RIG_OK; case RIG_LEVEL_RF : // rfgain Mem_Page=0 Address=30 // Current RF gain setting (0 to 5) (0=max gain) val.f = ((val.f * 10) - 1) * -1; if (val.f < 0) {val.f = 0;} if (val.f > 5) {val.f = 5;} Execute_Routine_6_1(rig, 0, 0x30, val.f) ; return RIG_OK; case RIG_LEVEL_SQL : // sqlval Mem_Page=0 Address=33 // Squelch value (current setting)(values 0 to 150) if (val.f < 0) {val.f = 0;} if (val.f > 1) {val.f = 1;} Execute_Routine_6_1(rig, 0, 0x33, val.f * 150); return RIG_OK; case RIG_LEVEL_CWPITCH : // bfoval Mem_Page=0 Address=36 // BFO offset in Hz (x33.19Hz)(values -4248.320 to 4215.130kHz). val.i = val.i * 100 / 3319; if (val.i < -128) {val.i = -128;} if (val.i > 127) {val.i = 127;} Execute_Routine_3_1(rig, 0, 0x36, val.i); return RIG_OK; case RIG_LEVEL_AGC : //ar7030 agcspd 3 > RIG_AGC_OFF // > RIG_AGC_SUPERFAST //ar7030 agcspd 0 > RIG_AGC_FAST //ar7030 agcspd 2 > RIG_AGC_SLOW // > RIG_AGC_USER /*!< user selectable */ //ar7030 agcspd 1 > RIG_AGC_MEDIUM // agcspd Mem_Page=0 Address=32 // Current AGC speed : 0 = Fast 2 = Slow 1 = Medium 3 = Off switch (val.i) { case RIG_AGC_OFF: Execute_Routine_6_1(rig, 0, 0x32, 3); break; case RIG_AGC_SLOW: Execute_Routine_6_1(rig, 0, 0x32, 2); break; case RIG_AGC_MEDIUM: Execute_Routine_6_1(rig, 0, 0x32, 1); break; case RIG_AGC_FAST: Execute_Routine_6_1(rig, 0, 0x32, 0); break; default: return -RIG_EINVAL; } return RIG_OK; default : return -RIG_EINVAL; } } static int ar7030_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int smval1; int smval2; switch (level) { case RIG_LEVEL_AF : // af_vol Mem_Page=0 Address=1E // Main channel volume (6-bits, values 15 to 63) setMemPtr(rig, 0, 0x1e); val->f = (float)(rxr_readByte(rig) - 15) / 50; return RIG_OK; case RIG_LEVEL_RF : // rfgain Mem_Page=0 Address=30 // Current RF gain setting (0 to 5) (0=max gain) setMemPtr(rig, 0, 0x30); val->f = (float)((rxr_readByte(rig) * -1) + 1) / 10; return RIG_OK; case RIG_LEVEL_SQL : // sqlval Mem_Page=0 Address=33 // Squelch value (current setting)(values 0 to 150) setMemPtr(rig, 0, 0x33); val->f = (float)rxr_readByte(rig) / 150; return RIG_OK; case RIG_LEVEL_CWPITCH : // bfoval Mem_Page=0 Address=36 // BFO offset in Hz (x33.19Hz)(values -4248.320 to 4215.130kHz). setMemPtr(rig, 0, 0x36); val->i = ((char)rxr_readByte(rig) * 3319) / 100; return RIG_OK; case RIG_LEVEL_AGC : //ar7030 agcspd 3 > RIG_AGC_OFF // > RIG_AGC_SUPERFAST, //ar7030 agcspd 0 > RIG_AGC_FAST, //ar7030 agcspd 2 > RIG_AGC_SLOW // > RIG_AGC_USER, //ar7030 agcspd 1 > RIG_AGC_MEDIUM // agcspd Mem_Page=0 Address=32 // Current AGC speed : 0 = Fast 2 = Slow 1 = Medium 3 = Off setMemPtr(rig, 0, 0x32); switch (rxr_readByte(rig)) { case 0: val->i = RIG_AGC_FAST; break; case 1: val->i = RIG_AGC_MEDIUM; break; case 2: val->i = RIG_AGC_SLOW; break; case 3: val->i = RIG_AGC_OFF; break; default: return -RIG_EINVAL; } return RIG_OK; // case RIG_LEVEL_LINEOUT : // geht nicht in hamlib // // af_axl Mem_Page=0 Address=23 Bit=0 - 5 // setMemPtr(rig ,0 ,0x23); // val->f = ((float)(rxr_readByte(rig) - 27) * 2) / 100; // // af_axr Mem_Page=0 Address=24 Bit=0 - 5 // return RIG_OK; case RIG_LEVEL_RAWSTR : // Routine 14 Read signal strength // Read signal strength Transmits byte representing received signal strength // (read from AGC voltage). Output is 8-bit binary in range 0 to 255 val->i = Execute_Routine_14(rig); return RIG_OK; case RIG_LEVEL_STRENGTH : // smval Mem_Page=0 Address=3F - 40 // 2 bytes Last S-meter reading (bars + segments) setMemPtr(rig, 0, 0x3f); smval1 = (unsigned char)rxr_readByte(rig); smval2 = (unsigned char)rxr_readByte(rig); if (smval1 < 9) { val->i = (smval1 * 6 + smval2) - 127; } else if (smval1 < 11) { /* int ops => int result => round has no effect (besides compiler warning */ //val->i = round((smval1 * 6 + smval2) * 10 / 12) - 118; val->i = ((smval1 * 6 + smval2) * 10 / 12) - 118; } else { /* int ops => int result => round has no effect (besides compiler warning */ //val->i = round((smval1 * 6 + smval2) * 10 / 6) - 173; val->i = ((smval1 * 6 + smval2) * 10 / 6) - 173; } return RIG_OK; default : return -RIG_EINVAL; } } static int ar7030_set_powerstat(RIG *rig, powerstat_t status) { // Radio power state. // 0 > RIG_POWER_OFF Power off // 1 > RIG_POWER_ON Power on // 2 > RIG_POWER_STANDBY Standby switch (status) { case RIG_POWER_OFF: // Operate button 9 = Power button Execute_Operate_button(rig, 9); return RIG_OK; case RIG_POWER_ON: // Operate button 0 = None pressed Execute_Operate_button(rig, 0); return RIG_OK; default: break; } return -RIG_EINVAL; } static int ar7030_get_powerstat(RIG *rig, powerstat_t *status) { // power Mem_Page=0 Address=2E Bit=0 - 0 // Power on setMemPtr(rig, 0, 0x2e); *status = (char)rxr_readByte(rig) & 0x01; return RIG_OK; } static int ar7030_reset(RIG *rig, reset_t reset) { // Reset operation. // 0 > RIG_RESET_NONE No reset // 1 > RIG_RESET_SOFT Software reset // 2 > RIG_RESET_VFO VFO reset // 3 > RIG_RESET_MCALL Memory clear // 4 > RIG_RESET_MASTER Master reset switch (reset) { // Routine 0 Reset Setup receiver as at switch-on. case RIG_RESET_SOFT : Execute_Routine_0(rig) ; return RIG_OK; default: break; } return -RIG_EINVAL; } struct rig_caps ar7030_caps = { RIG_MODEL(RIG_MODEL_AR7030), .model_name = "AR7030", .mfg_name = "AOR", .version = "20200324.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, /* TBC */ .write_delay = 0, .post_write_delay = 0, //Device: /dev/ttyS0 //.post_write_delay = 85, //Device: /dev/tts/USB0 < 85 sec timedout after 0 chars .timeout = 500, /* 0.5 second */ .retry = 0, .has_get_func = AR7030_FUNC_ALL, .has_set_func = AR7030_FUNC_ALL, .has_get_level = AR7030_LEVEL, .has_set_level = RIG_LEVEL_SET(AR7030_LEVEL), .has_get_parm = AR7030_PARM, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 100, /* FIXME */ .vfo_ops = AR7030_VFO_OPS, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 1000 memories */ .rx_range_list1 = { {kHz(10), MHz(2600), AR7030_MODES, -1, -1, AR7030_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(2600), AR7030_MODES, -1, -1, AR7030_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* no tx range, this is a scanner! */ .tuning_steps = { {AR7030_MODES, 50}, {AR7030_MODES, 100}, {AR7030_MODES, 200}, {AR7030_MODES, 500}, {AR7030_MODES, kHz(1)}, {AR7030_MODES, kHz(2)}, {AR7030_MODES, kHz(5)}, {AR7030_MODES, kHz(6.25)}, {AR7030_MODES, kHz(9)}, {AR7030_MODES, kHz(10)}, {AR7030_MODES, 12500}, {AR7030_MODES, kHz(20)}, {AR7030_MODES, kHz(25)}, {AR7030_MODES, kHz(30)}, {AR7030_MODES, kHz(50)}, {AR7030_MODES, kHz(100)}, {AR7030_MODES, kHz(200)}, {AR7030_MODES, kHz(250)}, {AR7030_MODES, kHz(500)}, // {AR7030_MODES,0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { /* mode/filter list, .remember = order matters! */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(0.8)}, /* narrow */ {RIG_MODE_SSB, kHz(4.8)}, /* wide */ {RIG_MODE_CW, kHz(9.5)}, /* wide */ {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* narrow */ {RIG_MODE_FM | RIG_MODE_AM, kHz(30)}, /* wide */ RIG_FLT_END, }, .priv = NULL, /* priv */ // .rig_init = ar7030_init, // .rig_cleanup = ar7030_cleanup, // .rig_open = ar7030_open, // .rig_close = ar7030_close, .set_freq = ar7030_set_freq, .get_freq = ar7030_get_freq, .set_mode = ar7030_set_mode, .get_mode = ar7030_get_mode, // .set_vfo = ar7030_set_vfo, // .get_vfo = ar7030_get_vfo, .set_powerstat = ar7030_set_powerstat, .get_powerstat = ar7030_get_powerstat, .set_level = ar7030_set_level, .get_level = ar7030_get_level, // .set_func = ar7030_set_func, // .get_func = ar7030_get_func, // .set_parm = ar7030_set_parm, // .get_parm = ar7030_get_parm, // .get_info = ar7030_get_info, // .set_ptt = ar7030_set_ptt, // .get_ptt = ar7030_get_ptt, // .get_dcd = ar7030_get_dcd, // .set_rptr_shift = ar7030_set_rptr_shift, // .get_rptr_shift = ar7030_get_rptr_shift, // .set_rptr_offs = ar7030_set_rptr_offs, // .get_rptr_offs = ar7030_get_rptr_offs, // .set_ctcss_tone = ar7030_set_ctcss_tone, // .get_ctcss_tone = ar7030_get_ctcss_tone, // .set_dcs_code = ar7030_set_dcs_code, // .get_dcs_code = ar7030_get_dcs_code, // .set_ctcss_sql = ar7030_set_ctcss_sql, // .get_ctcss_sql = ar7030_get_ctcss_sql, // .set_dcs_sql = ar7030_set_dcs_sql, // .get_dcs_sql = ar7030_get_dcs_sql, // .set_split_freq = ar7030_set_split_freq, // .get_split_freq = ar7030_get_split_freq, // .set_split_mode = ar7030_set_split_mode, // .get_split_mode = ar7030_get_split_mode, // .set_split_vfo = ar7030_set_split_vfo, // .get_split_vfo = ar7030_get_split_vfo, // .set_rit = ar7030_set_rit, // .get_rit = ar7030_get_rit, // .set_xit = ar7030_set_xit, // .get_xit = ar7030_get_xit, // .set_ts = ar7030_set_ts, // .get_ts = ar7030_get_ts, // .set_ant = ar7030_set_ant, // .get_ant = ar7030_get_ant, // .set_bank = ar7030_set_bank, // .set_mem = ar7030_set_mem, // .get_mem = ar7030_get_mem, // .vfo_op = ar7030_vfo_op, // .scan = ar7030_scan, // .send_dtmf = ar7030_send_dtmf, // .recv_dtmf = ar7030_recv_dtmf, // .send_morse = ar7030_send_morse, .reset = ar7030_reset, // .set_channel = ar7030_set_channel, // .get_channel = ar7030_get_channel, // .set_trn = ar7030_set_trn, // .get_trn = ar7030_get_trn, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/aor/README.aor0000644000175000017500000000134714752216205013076 00000000000000hamlib - Copyright (C) 2000 Frank Singleton libaor.so - Copyright (C) 2000 Stephane Fillod This shared library provides an API for communicating via serial interface to an AOR scanner. Reference Documentation ----------------------- AOR RS232 protocol listing for the AR8200 (accompanies the CC8200) Document release V1.3 AOR Ltd. Status ------ This is a WIP. Handles 5% of all opcodes. All primitives are written from spec. In other words, they are totally untested because I don't own an AOR scanner myself. Patches and contributions are welcome! I'm also looking for a real maintainer :) --SF This lib should/will support other AOR models. Warnings -------- 1. NOTHING IS WORKING, this is a WIP. Contributors ------------ hamlib-4.6.2/rigs/adat/0000755000175000017500000000000014752216242011642 500000000000000hamlib-4.6.2/rigs/adat/adat.c0000644000175000017500000025603714752216205012653 00000000000000// --------------------------------------------------------------------------- // ADAT Hamlib Backend // --------------------------------------------------------------------------- // // adat.c // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012, 2023 Frank Goenninger. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // --------------------------------------------------------------------------- // SYSTEM INCLUDES // --------------------------------------------------------------------------- #include #include #include #include // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include #include "serial.h" #include "misc.h" #include "register.h" #include "riglist.h" // --------------------------------------------------------------------------- // ADAT INCLUDES // --------------------------------------------------------------------------- #include "adat.h" // --------------------------------------------------------------------------- // GLOBAL DEFINITIONS // --------------------------------------------------------------------------- #if !defined(NDEBUG) # define ADAT_DEBUG 1 #endif // --------------------------------------------------------------------------- // ADAT GLOBAL VARIABLES // --------------------------------------------------------------------------- // DEBUG STUFF static int gFnLevel = 0; static adat_priv_data_t gsADATPrivData; // ADAT private state data // ADAT MODES static adat_mode_list_t the_adat_mode_list = { ADAT_NR_MODES, { { ADAT_MODE_STR_CW_R, ADAT_MODE_RNR_CW_R, ADAT_MODE_ANR_CW_R }, { ADAT_MODE_STR_CW, ADAT_MODE_RNR_CW, ADAT_MODE_ANR_CW }, { ADAT_MODE_STR_LSB, ADAT_MODE_RNR_LSB, ADAT_MODE_ANR_LSB }, { ADAT_MODE_STR_USB, ADAT_MODE_RNR_USB, ADAT_MODE_ANR_USB }, { ADAT_MODE_STR_AM, ADAT_MODE_RNR_AM, ADAT_MODE_ANR_AM }, { ADAT_MODE_STR_AM_SL, ADAT_MODE_RNR_AM_SL, ADAT_MODE_ANR_AM_SL }, { ADAT_MODE_STR_AM_SU, ADAT_MODE_RNR_AM_SU, ADAT_MODE_ANR_AM_SU }, { ADAT_MODE_STR_FM, ADAT_MODE_RNR_FM, ADAT_MODE_ANR_FM } } }; // ADAT VFOS static adat_vfo_list_t the_adat_vfo_list = { ADAT_NR_VFOS, { { ADAT_VFO_STR_A, ADAT_VFO_RNR_A, ADAT_VFO_ANR_A }, { ADAT_VFO_STR_B, ADAT_VFO_RNR_B, ADAT_VFO_ANR_B }, { ADAT_VFO_STR_C, ADAT_VFO_RNR_C, ADAT_VFO_ANR_C } } }; // --------------------------------------------------------------------------- // Individual ADAT CAT commands // --------------------------------------------------------------------------- // -- NIL -- (Marks the end of a cmd list) #if 0 static adat_cmd_def_t adat_cmd_nil = { ADAT_CMD_DEF_NIL, ADAT_CMD_KIND_WITHOUT_RESULT, NULL, 0, { NULL } }; #endif // -- ADAT SPECIAL: DISPLAY OFF -- static adat_cmd_def_t adat_cmd_display_off = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITHOUT_RESULT, NULL, 1, { ADAT_CMD_DEF_STRING_DISPLAY_OFF } }; // -- ADAT SPECIAL: DISPLAY ON -- static adat_cmd_def_t adat_cmd_display_on = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITHOUT_RESULT, NULL, 1, { ADAT_CMD_DEF_STRING_DISPLAY_ON } }; // -- ADAT SPECIAL: SELECT VFO -- // -- ADAT SPECIAL: GET SERIAL NR -- static adat_cmd_def_t adat_cmd_get_serial_nr = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_serial_nr, 1, { ADAT_CMD_DEF_STRING_GET_SERIAL_NR } }; // -- ADAT SPECIAL: GET FIRMWARE VERSION -- static adat_cmd_def_t adat_cmd_get_fw_version = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_fw_version, 1, { ADAT_CMD_DEF_STRING_GET_FW_VERSION } }; // -- ADAT SPECIAL: GET HARDWARE VERSION -- static adat_cmd_def_t adat_cmd_get_hw_version = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_hw_version, 1, { ADAT_CMD_DEF_STRING_GET_HW_VERSION } }; // -- ADAT SPECIAL: GET FIRMWARE VERSION -- static adat_cmd_def_t adat_cmd_get_id_code = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_id_code, 1, { ADAT_CMD_DEF_STRING_GET_ID_CODE } }; // -- ADAT SPECIAL: GET GUI FIRMWARE VERSION -- static adat_cmd_def_t adat_cmd_get_gui_fw_version = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_gui_fw_version, 1, { ADAT_CMD_DEF_STRING_GET_GUI_FW_VERSION } }; // -- ADAT SPECIAL: GET OPTIONS -- static adat_cmd_def_t adat_cmd_get_options = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_options, 1, { ADAT_CMD_DEF_STRING_GET_OPTIONS } }; // -- ADAT SPECIAL: GET CALLSIGN -- static adat_cmd_def_t adat_cmd_get_callsign = { ADAT_CMD_DEF_ADAT_SPECIAL, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_callsign, 1, { ADAT_CMD_DEF_STRING_GET_CALLSIGN } }; // -- HAMLIB DEFINED COMMANDS -- // -- GET FREQ -- static adat_cmd_def_t adat_cmd_get_freq = { ADAT_CMD_DEF_GET_FREQ, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_freq, 1, { ADAT_CMD_DEF_STRING_GET_FREQ } }; static adat_cmd_list_t adat_cmd_list_get_freq = { 2, { &adat_cmd_display_off, &adat_cmd_get_freq } }; // -- SET FREQ -- static adat_cmd_def_t adat_cmd_set_freq = { ADAT_CMD_DEF_SET_FREQ, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_freq, 1, { ADAT_CMD_DEF_STRING_SET_FREQ } }; static adat_cmd_list_t adat_cmd_list_set_freq = { 3, { &adat_cmd_display_off, &adat_cmd_set_freq, &adat_cmd_get_freq, } }; // -- GET VFO -- static adat_cmd_list_t adat_cmd_list_get_vfo = { 2, { &adat_cmd_display_off, &adat_cmd_get_freq, } }; // -- GET MODE -- static adat_cmd_def_t adat_cmd_get_mode = { ADAT_CMD_DEF_GET_MODE, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_mode, 1, { ADAT_CMD_DEF_STRING_GET_MODE } }; static adat_cmd_list_t adat_cmd_list_get_mode = { 2, { &adat_cmd_display_off, &adat_cmd_get_mode } }; // -- SET VFO -- static adat_cmd_def_t adat_cmd_set_vfo = { ADAT_CMD_DEF_SET_VFO, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_vfo, 2, { ADAT_CMD_DEF_STRING_SWITCH_ON_VFO, ADAT_CMD_DEF_STRING_SET_VFO_AS_MAIN_VFO } }; static adat_cmd_list_t adat_cmd_list_set_vfo = { 2, { &adat_cmd_display_off, &adat_cmd_set_vfo } }; // -- SET MODE -- static adat_cmd_def_t adat_cmd_set_mode = { ADAT_CMD_DEF_SET_MODE, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_mode, 1, { ADAT_CMD_DEF_STRING_SET_MODE } }; static adat_cmd_list_t adat_cmd_list_set_mode = { 3, { &adat_cmd_display_off, &adat_cmd_set_vfo, &adat_cmd_set_mode, } }; // -- SET PTT -- static adat_cmd_def_t adat_cmd_set_ptt = { ADAT_CMD_DEF_SET_PTT, ADAT_CMD_KIND_WITHOUT_RESULT, adat_cmd_fn_set_ptt, 1, { ADAT_CMD_DEF_STRING_SET_PTT } }; static adat_cmd_list_t adat_cmd_list_set_ptt = { 2, { &adat_cmd_set_ptt, &adat_cmd_display_off } }; // -- GET PTT -- static adat_cmd_def_t adat_cmd_get_ptt = { ADAT_CMD_DEF_GET_PTT, ADAT_CMD_KIND_WITH_RESULT, adat_cmd_fn_get_ptt, 1, { ADAT_CMD_DEF_STRING_GET_PTT } }; static adat_cmd_list_t adat_cmd_list_get_ptt = { 2, { &adat_cmd_display_off, &adat_cmd_get_ptt } }; // -- GET POWER STATUS -- static adat_cmd_list_t adat_cmd_list_get_powerstatus = { 1, { &adat_cmd_get_id_code } }; // -- GET INFO -- static adat_cmd_list_t adat_cmd_list_get_info = { 7, { &adat_cmd_get_serial_nr, &adat_cmd_get_id_code, &adat_cmd_get_fw_version, &adat_cmd_get_gui_fw_version, &adat_cmd_get_hw_version, &adat_cmd_get_options, &adat_cmd_get_callsign } }; // -- OPEN ADAT -- static adat_cmd_list_t adat_cmd_list_open_adat = { 8, { &adat_cmd_display_off, &adat_cmd_get_serial_nr, &adat_cmd_get_id_code, &adat_cmd_get_fw_version, &adat_cmd_get_gui_fw_version, &adat_cmd_get_hw_version, &adat_cmd_get_options, &adat_cmd_get_callsign } }; // -- CLOSE ADAT -- static adat_cmd_list_t adat_cmd_list_close_adat = { 1, { &adat_cmd_display_on } }; // -- ADAT SPECIAL: RECOVER FROM ERROR -- static adat_cmd_list_t adat_cmd_list_recover_from_error = { 1, { &adat_cmd_display_on } }; // --------------------------------------------------------------------------- // IMPLEMENTATION // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // trimwhitespace - taken from Stackoverflow // http://stackoverflow.com/questions/122616/how-do-i-trim-leading-trailing-whitespace-in-a-standard-way // --------------------------------------------------------------------------- // Status: RELEASED size_t trimwhitespace(char *out, size_t len, const char *str) { char *end = NULL; size_t out_size = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. In -> '%s', %d\n", gFnLevel, __func__, __FILE__, __LINE__, str, (int)len); if (len == 0) { gFnLevel--; return 0; } // Trim leading space while (isspace((int)*str)) { str++; } if (*str == 0) // All spaces? { out = NULL; gFnLevel--; return 1; } // Trim trailing space end = (char *)(str + strlen(str) - 1); while (end > str && isspace((int)*end)) { *end = '\0'; end--; } // Set output size to minimum of trimmed string length and buffer size minus 1 //out_size = (end - str) < len-1 ? (end - str) : len - 1; out_size = strlen(str); // Copy trimmed string and add null terminator memcpy(out, str, out_size); out[out_size] = 0; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Out -> \"%s\", %d\n", gFnLevel, __func__, __FILE__, __LINE__, out, (int)out_size); gFnLevel--; return out_size; } // --------------------------------------------------------------------------- // adat_print_cmd // --------------------------------------------------------------------------- // Status: RELEASED int adat_print_cmd(adat_cmd_def_ptr pCmd) { int nRC = RIG_OK; int nI = 0; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %s (%s:%d): ENTRY.\n", __func__, __FILE__, __LINE__); rig_debug(RIG_DEBUG_TRACE, "*** -> Command ID = %u\n", (unsigned int)(pCmd->nCmdId)); rig_debug(RIG_DEBUG_TRACE, "*** -> Command kind = %d\n", pCmd->nCmdKind); while (nI < pCmd->nNrCmdStrs) { rig_debug(RIG_DEBUG_TRACE, "*** -> Command String %d = \"%s\"\n", nI, pCmd->pacCmdStrs[ nI ]); nI++; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %s (%s:%d): EXIT. Return Code = %d\n", __func__, __FILE__, __LINE__, nRC); return nRC; } // --------------------------------------------------------------------------- // adat_parse_freq // --------------------------------------------------------------------------- // Status: RELEASED // Can be used to parse strings with VFO nr and without VFO nr in it: // "1 123.456kHz" => nMode = ADAT_FREQ_PARSE_MODE_WITH_VFO // "800Hz" => nMode = ADAT_FREQ_PARSE_MODE_WITHOUT_VFO int adat_parse_freq(char *pcStr, adat_freq_parse_mode_t nMode, int *nVFO, freq_t *nFreq) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if (pcStr != NULL) { int _nVFO = 0; char *pcEnd = NULL; if (nMode == ADAT_FREQ_PARSE_MODE_WITH_VFO) { // Get VFO from response string _nVFO = strtol(pcStr, &pcEnd, 10); // Save VFO *nVFO = _nVFO; } else { pcEnd = pcStr; } if ((_nVFO != 0) // VFO = 0 -> Current VFO not active. || (nMode == ADAT_FREQ_PARSE_MODE_WITHOUT_VFO)) { char acValueBuf[ ADAT_BUFSZ + 1 ]; char acUnitBuf[ ADAT_BUFSZ + 1 ]; int nI = 0; double dTmpFreq = 0.0; freq_t _nFreq; memset(acValueBuf, 0, ADAT_BUFSZ + 1); memset(acUnitBuf, 0, ADAT_BUFSZ + 1); // Get Freq Value from response string while ((isalpha((int)*pcEnd) == 0) || (*pcEnd == '.')) { acValueBuf[ nI++ ] = *pcEnd; pcEnd += sizeof(char); } dTmpFreq = strtod(acValueBuf, (char **) NULL); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d acValueBuf = \"%s\", dTmpFreq = %f, *pcEnd = %c\n", gFnLevel, acValueBuf, dTmpFreq, *pcEnd); // Get Freq Unit from response string nI = 0; while (isalpha((int)*pcEnd) != 0) { acUnitBuf[ nI++ ] = *pcEnd; pcEnd += sizeof(char); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d acUnitBuf = \"%s\"\n", gFnLevel, acUnitBuf); // Normalize to Hz if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_HZ, ADAT_FREQ_UNIT_HZ_LEN)) { _nFreq = Hz(dTmpFreq); } else { if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_KHZ, ADAT_FREQ_UNIT_KHZ_LEN)) { _nFreq = kHz(dTmpFreq); } else { if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_MHZ, ADAT_FREQ_UNIT_MHZ_LEN)) { _nFreq = MHz(dTmpFreq); } else { if (!strncmp(acUnitBuf, ADAT_FREQ_UNIT_GHZ, ADAT_FREQ_UNIT_GHZ_LEN)) { _nFreq = GHz(dTmpFreq); } else { _nFreq = 0; nRC = -RIG_EINVAL; } } } } // Save Freq *nFreq = _nFreq; } } else { // If input string is NULL set Freq and VFO also to NULL *nFreq = 0; *nVFO = 0; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, nVFO = %d, nFreq = %f\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nVFO, *nFreq); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_parse_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_parse_mode(char *pcStr, rmode_t *nRIGMode, char *pcADATMode) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if (pcStr != NULL) { int nI = 0; int nFini = 0; while ((nI < the_adat_mode_list.nNrModes) && (nFini == 0)) { if (!strcmp(pcStr, the_adat_mode_list.adat_modes[ nI ].pcADATModeStr)) { *nRIGMode = the_adat_mode_list.adat_modes[ nI ].nRIGMode; nFini = 1; // Done. } else { nI++; } } } else { // If input string is NULL ... *nRIGMode = RIG_MODE_NONE; *pcADATMode = 0; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, Mode = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, (int)*nRIGMode); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_mode_rnr2anr // --------------------------------------------------------------------------- // Status: RELEASED int adat_mode_rnr2anr(rmode_t nRIGMode, int *nADATMode) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGMode = %u\n", gFnLevel, __func__, __FILE__, __LINE__, (unsigned int)nRIGMode); while ((nI < the_adat_mode_list.nNrModes) && (nFini == 0)) { if (the_adat_mode_list.adat_modes[ nI ].nRIGMode == nRIGMode) { *nADATMode = the_adat_mode_list.adat_modes[ nI ].nADATMode; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid Mode given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, ADAT Mode = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nADATMode); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_mode_anr2rnr // --------------------------------------------------------------------------- // Status: RELEASED int adat_mode_anr2rnr(int nADATMode, rmode_t *nRIGMode) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGMode = %u\n", gFnLevel, __func__, __FILE__, __LINE__, (unsigned int)*nRIGMode); while ((nI < the_adat_mode_list.nNrModes) && (nFini == 0)) { if (the_adat_mode_list.adat_modes[ nI ].nADATMode == nADATMode) { *nRIGMode = the_adat_mode_list.adat_modes[ nI ].nRIGMode; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid Mode given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG Mode = %u\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, (unsigned int)*nRIGMode); gFnLevel--; return nRC; } #ifdef XXREMOVEDXX // this function wasn't referenced anywhere // --------------------------------------------------------------------------- // adat_parse_vfo // --------------------------------------------------------------------------- // Status: RELEASED int adat_parse_vfo(char *pcStr, vfo_t *nRIGVFONr, int *nADATVFONr) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if (pcStr != NULL) { int nI = 0; int nFini = 0; while ((nI < the_adat_vfo_list.nNrVFOs) && (nFini == 0)) { if (!strcmp(pcStr, the_adat_vfo_list.adat_vfos[ nI ].pcADATVFOStr)) { *nRIGVFONr = the_adat_vfo_list.adat_vfos[ nI ].nRIGVFONr; *nADATVFONr = the_adat_vfo_list.adat_vfos[ nI ].nADATVFONr; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { nRC = -RIG_EINVAL; } } else { // If input string is NULL ... *nRIGVFONr = RIG_VFO_NONE; *nADATVFONr = 0; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG VFO Nr = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nRIGVFONr); gFnLevel--; return nRC; } #endif // --------------------------------------------------------------------------- // adat_vfo_rnr2anr // --------------------------------------------------------------------------- // Status: RELEASED int adat_vfo_rnr2anr(vfo_t nRIGVFONr, int *nADATVFONr) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGVFONr = %u\n", gFnLevel, __func__, __FILE__, __LINE__, nRIGVFONr); while ((nI < the_adat_vfo_list.nNrVFOs) && (nFini == 0)) { if (the_adat_vfo_list.adat_vfos[ nI ].nRIGVFONr == nRIGVFONr) { *nADATVFONr = the_adat_vfo_list.adat_vfos[ nI ].nADATVFONr; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid Mode given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, ADAT VFO Nr = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nADATVFONr); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_vfo_anr2rnr // --------------------------------------------------------------------------- // Status: RELEASED int adat_vfo_anr2rnr(int nADATVFONr, vfo_t *nRIGVFONr) { int nRC = RIG_OK; int nI = 0; int nFini = 0; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nADATVFONr = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nADATVFONr); while ((nI < the_adat_vfo_list.nNrVFOs) && (nFini == 0)) { if (the_adat_vfo_list.adat_vfos[ nI ].nADATVFONr == nADATVFONr) { *nRIGVFONr = the_adat_vfo_list.adat_vfos[ nI ].nRIGVFONr; nFini = 1; // Done. } else { nI++; } } if (nFini == 0) { // No valid ADAT VFO Nr given nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG VFO Nr = %u\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nRIGVFONr); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_parse_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_parse_ptt(char *pcStr, int *nADATPTTStatus) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pcStr = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pcStr); if ((pcStr != NULL) && (strlen(pcStr) > 0)) { *nADATPTTStatus = strtol(pcStr, NULL, 10); } else { // If input string is NULL ... *nADATPTTStatus = ADAT_PTT_STATUS_ANR_OFF; nRC = -RIG_EINVAL; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } #ifdef XXREMOVEDXX // this function wasn't referenced anywhere // --------------------------------------------------------------------------- // adat_ptt_rnr2anr // --------------------------------------------------------------------------- // Status: RELEASED int adat_ptt_rnr2anr(ptt_t nRIGPTTStatus, int *nADATPTTStatus) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nRIGPTTStatus = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRIGPTTStatus); switch (nRIGPTTStatus) { case ADAT_PTT_STATUS_RNR_ON: *nADATPTTStatus = ADAT_PTT_STATUS_ANR_ON; break; case ADAT_PTT_STATUS_RNR_OFF: *nADATPTTStatus = ADAT_PTT_STATUS_ANR_OFF; break; default: nRC = -RIG_EINVAL; break; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, ADAT PTT Status = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nADATPTTStatus); gFnLevel--; return nRC; } #endif // --------------------------------------------------------------------------- // adat_ptt_anr2rnr // --------------------------------------------------------------------------- // Status: RELEASED int adat_ptt_anr2rnr(int nADATPTTStatus, ptt_t *nRIGPTTStatus) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: nADATPTTStatus = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nADATPTTStatus); switch (nADATPTTStatus) { case ADAT_PTT_STATUS_ANR_ON: *nRIGPTTStatus = ADAT_PTT_STATUS_RNR_ON; break; case ADAT_PTT_STATUS_ANR_OFF: *nRIGPTTStatus = ADAT_PTT_STATUS_RNR_OFF; break; default: nRC = -RIG_EINVAL; break; } // Done rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d, RIG PTT Status = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC, *nRIGPTTStatus); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_send // --------------------------------------------------------------------------- // Status: RELEASED int adat_send(RIG *pRig, char *pcData) { int nRC = RIG_OK; hamlib_port_t *pRigPort = RIGPORT(pRig); gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p, pcData = %s\n", gFnLevel, __func__, __FILE__, __LINE__, pRig, pcData); rig_flush(pRigPort); nRC = write_block(pRigPort, (unsigned char *) pcData, strlen(pcData)); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_receive // --------------------------------------------------------------------------- // Status: RELEASED int adat_receive(RIG *pRig, char *pcData) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); nRC = read_string(RIGPORT(pRig), (unsigned char *) pcData, ADAT_RESPSZ, ADAT_EOL, 1, 0, 1); if (nRC > 0) { nRC = RIG_OK; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_priv_set_cmd // --------------------------------------------------------------------------- // Status: RELEASED int adat_priv_set_cmd(RIG *pRig, char *pcCmd, int nCmdKind) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p, pcCmd = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pRig, pcCmd); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; memset(pPriv->acCmd, 0, ADAT_PRIV_DATA_CMD_LENGTH + 1); snprintf(pPriv->acCmd, ADAT_PRIV_DATA_CMD_LENGTH + 1, "%s", pcCmd); pPriv->nCmdKind = nCmdKind; } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_priv_set_result // --------------------------------------------------------------------------- // Status: RELEASED int adat_priv_set_result(RIG *pRig, char *pcResult) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p, pcResult = \"%s\"\n", gFnLevel, __func__, __FILE__, __LINE__, pRig, pcResult); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; memset(pPriv->acResult, 0, ADAT_PRIV_DATA_RESULT_LENGTH + 1); snprintf(pPriv->acResult, ADAT_PRIV_DATA_RESULT_LENGTH + 1, "%s", pcResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acResult = \"%s\"\n", gFnLevel, pPriv->acResult); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_priv_clear_result // --------------------------------------------------------------------------- // Status: RELEASED int adat_priv_clear_result(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; memset(pPriv->acResult, 0, ADAT_PRIV_DATA_RESULT_LENGTH + 1); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_get_single_cmd_result // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_single_cmd_result(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_send(pRig, pPriv->acCmd); if ((nRC == RIG_OK) && (pPriv->nCmdKind == ADAT_CMD_KIND_WITH_RESULT)) { char acBuf[ ADAT_RESPSZ + 1 ]; char acBuf2[ ADAT_RESPSZ + 1 ]; char *pcBufEnd = NULL; char *pcPos = NULL; char *pcResult = NULL; memset(acBuf, 0, ADAT_RESPSZ + 1); memset(acBuf2, 0, ADAT_RESPSZ + 1); nRC = adat_receive(pRig, acBuf); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d acBuf ........ = %p\n", gFnLevel, acBuf); pcPos = acBuf; if (nRC == RIG_OK) { int nBufLength = 0; // cppcheck-suppress knownConditionTrueFalse if (*pcPos == 0) // Adjust for 00 byte at beginning ... { pcPos++; // No, please don't ask me why this happens ... ;-) } nBufLength = strlen(pcPos); pcBufEnd = pcPos + nBufLength - 1; pcResult = pcPos; // Save position if (pcPos < pcBufEnd) { int nLength = strlen(pcPos); if (nLength > 0) { char *pcPos2 = strchr(pcPos, (char) 0x0d); if (pcPos2 != NULL) { *pcPos2 = '\0'; // Truncate \0d\0a } pcPos = strchr(pcPos, ' '); if ((pcPos != NULL) && (pcPos < pcBufEnd)) { pcPos += sizeof(char); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pcPos ........ = %p\n", gFnLevel, pcPos); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pcBufEnd ..... = %p\n", gFnLevel, pcBufEnd); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d nBufLength ... = %d\n", gFnLevel, nBufLength); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pcPos2 ....... = %p\n", gFnLevel, pcPos2); trimwhitespace(acBuf2, strlen(pcPos), pcPos); pcResult = acBuf2; } } else { nRC = -RIG_EINVAL; } } else { nRC = -RIG_EINVAL; } adat_priv_clear_result(pRig); if (nRC == RIG_OK) { adat_priv_set_result(pRig, pcResult); } } } rig_flush(RIGPORT(pRig)); pPriv->nRC = nRC; } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_recover_from_error // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_recover_from_error(RIG *pRig, int nError) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; // Recover from communication error if ((nError == RIG_ETIMEOUT) || (nError == RIG_EPROTO) || (nError == RIG_EIO)) { rig_close(pRig); sleep(ADAT_SLEEP_AFTER_RIG_CLOSE); rig_open(pRig); } // Reset critical Priv values pPriv->nRC = RIG_OK; // Execute recovery commands (void) adat_transaction(pRig, &adat_cmd_list_recover_from_error); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_callsign // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_callsign(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_CALLSIGN, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acCallsign, 0, ADAT_PRIV_DATA_CALLSIGN_LENGTH + 1); snprintf(pPriv->acCallsign, ADAT_PRIV_DATA_CALLSIGN_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acCallsign = \"%s\"\n", gFnLevel, pPriv->acCallsign); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_serial_nr // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_serial_nr(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_SERIAL_NR, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acSerialNr, 0, ADAT_PRIV_DATA_SERIALNR_LENGTH + 1); snprintf(pPriv->acSerialNr, ADAT_PRIV_DATA_SERIALNR_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acSerialNr = \"%s\"\n", gFnLevel, pPriv->acSerialNr); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_fw_version // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_fw_version(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_FW_VERSION, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acFWVersion, 0, ADAT_PRIV_DATA_FWVERSION_LENGTH + 1); snprintf(pPriv->acFWVersion, ADAT_PRIV_DATA_FWVERSION_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acFWVersion = \"%s\"\n", gFnLevel, pPriv->acFWVersion); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_hw_version // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_hw_version(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_HW_VERSION, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acHWVersion, 0, ADAT_PRIV_DATA_HWVERSION_LENGTH + 1); snprintf(pPriv->acHWVersion, ADAT_PRIV_DATA_HWVERSION_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acHWVersion = \"%s\"\n", gFnLevel, pPriv->acHWVersion); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_gui_fw_version // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_gui_fw_version(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_GUI_FW_VERSION, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acGUIFWVersion, 0, ADAT_PRIV_DATA_GUIFWVERSION_LENGTH + 1); snprintf(pPriv->acGUIFWVersion, ADAT_PRIV_DATA_GUIFWVERSION_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acGUIFWVersion = \"%s\"\n", gFnLevel, pPriv->acGUIFWVersion); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_id_code // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_id_code(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_ID_CODE, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acIDCode, 0, ADAT_PRIV_DATA_IDCODE_LENGTH + 1); snprintf(pPriv->acIDCode, ADAT_PRIV_DATA_IDCODE_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acIDCode = \"%s\"\n", gFnLevel, pPriv->acIDCode); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_options // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_options(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_OPTIONS, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(pPriv->acOptions, 0, ADAT_PRIV_DATA_OPTIONS_LENGTH + 1); snprintf(pPriv->acOptions, ADAT_PRIV_DATA_OPTIONS_LENGTH + 1, "%s", pPriv->acResult); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->acOptions = \"%s\"\n", gFnLevel, pPriv->acOptions); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_mode(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_MODE, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { nRC = adat_parse_mode(pPriv->acResult, &(pPriv->nRIGMode), pPriv->acADATMode); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_set_mode(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; // Translate Mode from RIG Mode Nr to ADAT Mode Nr nRC = adat_mode_rnr2anr(pPriv->nRIGMode, &(pPriv->nADATMode)); if (nRC == RIG_OK) { // Prepare Command char acBuf[ ADAT_BUFSZ + 1 ]; memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), "%s%02d%s", ADAT_CMD_DEF_STRING_SET_MODE, (int) pPriv->nADATMode, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); // Execute Command if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_freq(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_FREQ, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { nRC = adat_parse_freq(pPriv->acResult, ADAT_FREQ_PARSE_MODE_WITH_VFO, &(pPriv->nCurrentVFO), &(pPriv->nFreq)); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pPriv->nCurrentVFO = %d, Freq [Hz] = %f\n", gFnLevel, pPriv->nCurrentVFO, pPriv->nFreq); if (nRC == RIG_OK) { nRC = adat_vfo_anr2rnr(pPriv->nCurrentVFO, &(pPriv->nRIGVFONr)); } } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_set_freq(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char acBuf[ ADAT_BUFSZ + 1 ]; // Get frequency of selected VFO memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), "%s%d%s", ADAT_CMD_DEF_STRING_SET_FREQ, (int) pPriv->nFreq, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_vfo // --------------------------------------------------------------------------- // Status: RELEASED // Setting a VFO on an ADAT is actually two steps: // 1. Switching on that VFO // 2. Setting this VFO as the main VFO int adat_cmd_fn_set_vfo(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char acBuf[ ADAT_BUFSZ + 1 ]; // Switch on VFO memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), ADAT_CMD_DEF_STRING_SWITCH_ON_VFO, (int) pPriv->nCurrentVFO, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), ADAT_CMD_DEF_STRING_SET_VFO_AS_MAIN_VFO, (int) pPriv->nCurrentVFO, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_get_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_get_ptt(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_priv_set_cmd(pRig, ADAT_CMD_DEF_STRING_GET_PTT, ADAT_CMD_KIND_WITH_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); if (nRC == RIG_OK) { nRC = adat_parse_ptt(pPriv->acResult, &(pPriv->nADATPTTStatus)); if (nRC == RIG_OK) { nRC = adat_ptt_anr2rnr(pPriv->nADATPTTStatus, &(pPriv->nRIGPTTStatus)); } } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_cmd_fn_set_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_cmd_fn_set_ptt(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char *pcPTTStr = NULL; // Switch PTT switch (pPriv->nOpCode) { case ADAT_OPCODE_PTT_SWITCH_ON: pPriv->nADATPTTStatus = ADAT_PTT_STATUS_ANR_ON; nRC = adat_ptt_anr2rnr(ADAT_PTT_STATUS_ANR_ON, &(pPriv->nRIGPTTStatus)); pcPTTStr = ADAT_CMD_PTT_STR_ON; break; case ADAT_OPCODE_PTT_SWITCH_OFF: pPriv->nADATPTTStatus = ADAT_PTT_STATUS_ANR_OFF; nRC = adat_ptt_anr2rnr(ADAT_PTT_STATUS_ANR_OFF, &(pPriv->nRIGPTTStatus)); pcPTTStr = ADAT_CMD_PTT_STR_OFF; break; default: nRC = -RIG_EINVAL; break; } if (nRC == RIG_OK) { char acBuf[ ADAT_BUFSZ + 1 ]; memset(acBuf, 0, ADAT_BUFSZ + 1); snprintf(acBuf, sizeof(acBuf), ADAT_CMD_DEF_STRING_SET_PTT, pcPTTStr, ADAT_EOM); nRC = adat_priv_set_cmd(pRig, acBuf, ADAT_CMD_KIND_WITHOUT_RESULT); if (nRC == RIG_OK) { nRC = adat_get_single_cmd_result(pRig); } } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // adat_transaction // --------------------------------------------------------------------------- // Status: RELEASED // adat_transaction is a generalized command processor able to execute // commands of type adat_cmd_def_t . int adat_transaction(RIG *pRig, adat_cmd_list_ptr pCmdList) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { int nI = 0; int nFini = 0; // = 1 -> Stop executing commands adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): Nr of commands = %d\n", gFnLevel, __func__, __FILE__, __LINE__, pCmdList->nNrCmds); while ((nRC == RIG_OK) && (nFini == 0) && (nI < pCmdList->nNrCmds)) { adat_cmd_def_ptr pCmd = pCmdList->adat_cmds[ nI ]; if ((pCmd != NULL) && (pCmd->nCmdId != ADAT_CMD_DEF_NIL)) { rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d About to execute ADAT Command ... \n", gFnLevel); adat_print_cmd(pCmd); // Execute Command if (pCmd->pfCmdFn != NULL) { rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d Calling function via fn ptr ... \n", gFnLevel); nRC = pCmd->pfCmdFn(pRig); } else { rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d Sending command string ... \n", gFnLevel); if (pCmd->nNrCmdStrs > 0) { int nJ = 0; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d pacCmdStrs[%d] = %s\n", gFnLevel, nJ, pCmd->pacCmdStrs[ nJ ]); while ((nJ < pCmd->nNrCmdStrs) && (nRC == RIG_OK) && (pCmd->pacCmdStrs[ nJ ] != NULL)) { nRC = adat_send(pRig, pCmd->pacCmdStrs[ nJ ]); if (nRC == RIG_OK) { if (pCmd->nCmdKind == ADAT_CMD_KIND_WITH_RESULT) { char acBuf[ ADAT_RESPSZ + 1 ]; memset(acBuf, 0, ADAT_RESPSZ + 1); nRC = adat_receive(pRig, acBuf); while ((nRC == RIG_OK) && (strncmp(acBuf, ADAT_BOM, strlen(ADAT_BOM)) != 0)) { nRC = adat_receive(pRig, acBuf); } memset(pPriv->acResult, 0, ADAT_PRIV_DATA_RESULT_LENGTH + 1); snprintf(pPriv->acResult, ADAT_PRIV_DATA_RESULT_LENGTH + 1, "%s", acBuf); } } nJ++; } } } if (nRC != RIG_OK) { (void) adat_cmd_recover_from_error(pRig, nRC); } nI++; } else { nFini = 1; } // sleep between cmds - ADAT needs time to act upoon cmds hl_usleep(ADAT_SLEEP_MICROSECONDS_BETWEEN_CMDS); } } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_init // --------------------------------------------------------------------------- // Status: RELEASED int adat_init(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig != NULL) { // Set Rig Priv data memset(&gsADATPrivData, 0, sizeof(adat_priv_data_t)); STATE(pRig)->priv = &gsADATPrivData; } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_cleanup // --------------------------------------------------------------------------- // Status: RELEASED int adat_cleanup(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); if (pRig == NULL) { nRC = -RIG_EARG; } else { STATE(pRig)->priv = NULL; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_open // --------------------------------------------------------------------------- // Status: RELEASED int adat_open(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // grace period for the radio to be there sleep(ADAT_SLEEP_AFTER_RIG_OPEN); // Now get basic info from ADAT TRX nRC = adat_transaction(pRig, &adat_cmd_list_open_adat); } // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_close // --------------------------------------------------------------------------- // Status: RELEASED int adat_close(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Now switch to interactive mode (end Remote Operation mode) nRC = adat_transaction(pRig, &adat_cmd_list_close_adat); // Done ! rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_info // --------------------------------------------------------------------------- // Status: RELEASED const char *adat_get_info(RIG *pRig) { static char acBuf[ 2048 ]; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); memset(acBuf, 0, 2048); if (pRig != NULL) { int nRC = adat_transaction(pRig, &adat_cmd_list_get_info); if (nRC == RIG_OK) { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; snprintf(acBuf, 2048, "ADAT ADT-200A, Callsign: %s, S/N: %s, ID Code: %s, Options: %s, FW: %s, GUI FW: %s, HW: %s", pPriv->acCallsign, pPriv->acSerialNr, pPriv->acIDCode, pPriv->acOptions, pPriv->acFWVersion, pPriv->acGUIFWVersion, pPriv->acHWVersion); } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Value ='%s'\n", gFnLevel, __func__, __FILE__, __LINE__, acBuf); gFnLevel--; return acBuf; } // --------------------------------------------------------------------------- // Function adat_set_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_freq(RIG *pRig, vfo_t vfo, freq_t freq) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; pPriv->nFreq = freq; nRC = adat_transaction(pRig, &adat_cmd_list_set_freq); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_freq // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_freq(RIG *pRig, vfo_t vfo, freq_t *freq) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_freq); *freq = pPriv->nFreq; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_level // --------------------------------------------------------------------------- // Status: IN WORK int adat_set_level(RIG *pRig, vfo_t vfo, setting_t level, value_t val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_level // --------------------------------------------------------------------------- // Status: IN WORK int adat_get_level(RIG *pRig, vfo_t vfo, setting_t level, value_t *val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_mode(RIG *pRig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int nRC; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; pPriv->nRIGMode = mode; adat_vfo_rnr2anr(vfo, &(pPriv->nCurrentVFO)); if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(pRig, mode); } pPriv->nWidth = width; } nRC = adat_transaction(pRig, &adat_cmd_list_set_mode); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_mode // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_mode(RIG *pRig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_mode); if (nRC == RIG_OK) { *mode = pPriv->nRIGMode; *width = pPriv->nWidth; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_vfo // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_vfo(RIG *pRig, vfo_t *vfo) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_vfo); *vfo = pPriv->nRIGVFONr; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_vfo // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_vfo(RIG *pRig, vfo_t vfo) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_vfo_rnr2anr(vfo, &(pPriv->nCurrentVFO)); if (nRC == RIG_OK) { nRC = adat_transaction(pRig, &adat_cmd_list_set_vfo); } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_ptt(RIG *pRig, vfo_t vfo, ptt_t *ptt) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; nRC = adat_transaction(pRig, &adat_cmd_list_get_ptt); *ptt = pPriv->nRIGPTTStatus; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_ptt // --------------------------------------------------------------------------- // Status: RELEASED int adat_set_ptt(RIG *pRig, vfo_t vfo, ptt_t ptt) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; switch (ptt) { case RIG_PTT_ON: pPriv->nOpCode = ADAT_OPCODE_PTT_SWITCH_ON; break; case RIG_PTT_OFF: pPriv->nOpCode = ADAT_OPCODE_PTT_SWITCH_OFF; break; default: nRC = -RIG_EINVAL; break; } if (nRC == RIG_OK) { nRC = adat_transaction(pRig, &adat_cmd_list_set_ptt); } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_power2mW // --------------------------------------------------------------------------- // Status: RELEASED int adat_power2mW(RIG *pRig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if ((pRig == NULL) || (mwpower == NULL)) { nRC = -RIG_EARG; } else { *mwpower = power * ADAT_MAX_POWER_IN_mW; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_mW2power // --------------------------------------------------------------------------- // Status: RELEASED int adat_mW2power(RIG *pRig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if ((pRig == NULL) || (power == NULL)) { nRC = -RIG_EARG; } else { *power = mwpower / ((float)ADAT_MAX_POWER_IN_mW); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_powerstat // --------------------------------------------------------------------------- // Status: RELEASED int adat_get_powerstat(RIG *pRig, powerstat_t *status) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { nRC = adat_transaction(pRig, &adat_cmd_list_get_powerstatus); // nRC < 0 -> Power is off. if (nRC == RIG_OK) { *status = RIG_POWER_ON; } else { *status = RIG_POWER_OFF; nRC = RIG_OK; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_set_conf // --------------------------------------------------------------------------- // Status: IN WORK int adat_set_conf(RIG *pRig, hamlib_token_t token, const char *val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; switch (token) { case TOKEN_ADAT_PRODUCT_NAME: snprintf(pPriv->acProductName, ADAT_PRIV_DATA_PRODUCTNAME_LENGTH + 1, "%s", val); break; default: nRC = -RIG_EINVAL; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_get_conf // --------------------------------------------------------------------------- // Status: IN WORK int adat_get_conf(RIG *pRig, hamlib_token_t token, char *val) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { // cppcheck-suppress constVariablePointer const adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; switch (token) { case TOKEN_ADAT_PRODUCT_NAME: if (strlen(pPriv->acProductName) > 0) { strcpy(val, pPriv->acProductName); } else { strcpy(val, "Unknown product"); } break; default: nRC = -RIG_EINVAL; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_reset // --------------------------------------------------------------------------- // Status: IN WORK int adat_reset(RIG *pRig, reset_t reset) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // Function adat_handle_event // --------------------------------------------------------------------------- // Status: IN WORK int adat_handle_event(RIG *pRig) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY. Params: pRig = %p\n", gFnLevel, __func__, __FILE__, __LINE__, pRig); // Check Params if (pRig == NULL) { nRC = -RIG_EARG; } else { //adat_priv_data_ptr pPriv = (adat_priv_data_ptr) STATE(pRig)->priv; char acBuf[ ADAT_RESPSZ + 1 ]; memset(acBuf, 0, ADAT_RESPSZ + 1); adat_receive(pRig, acBuf); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d Event data = \"%s\"\n", gFnLevel, acBuf); } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // initrigs_adat is called by rig_backend_load // --------------------------------------------------------------------------- // Status: RELEASED DECLARE_INITRIG_BACKEND(adat) { int nRC = RIG_OK; gFnLevel++; #if 0 rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY.\n", gFnLevel, __func__, __FILE__, __LINE__); #endif rig_register(&adt_200a_caps); #if 0 rig_debug(RIG_DEBUG_VERBOSE, "ADAT: Rig ADT-200A registered.\n"); rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); #endif gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // proberig_adat // --------------------------------------------------------------------------- DECLARE_PROBERIG_BACKEND(adat) { int nRC = RIG_OK; gFnLevel++; rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): ENTRY.\n", gFnLevel, __func__, __FILE__, __LINE__); if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 10; port->parm.serial.stop_bits = 2; port->retry = 1; nRC = serial_open(port); if (nRC != RIG_OK) { nRC = RIG_MODEL_NONE; } else { char acBuf[ ADAT_RESPSZ + 1 ]; int nRead = 0; memset(acBuf, 0, ADAT_RESPSZ + 1); nRC = write_block(port, (unsigned char *)ADAT_CMD_DEF_STRING_GET_ID_CODE, strlen(ADAT_CMD_DEF_STRING_GET_ID_CODE)); nRead = read_string(port, (unsigned char *) acBuf, ADAT_RESPSZ, ADAT_EOM, 1, 0, 1); close(port->fd); if ((nRC != RIG_OK || nRead < 0)) { nRC = RIG_MODEL_NONE; } else { rig_debug(RIG_DEBUG_VERBOSE, "ADAT: %d Received ID = %s.", gFnLevel, acBuf); nRC = RIG_MODEL_ADT_200A; } } rig_debug(RIG_DEBUG_TRACE, "*** ADAT: %d %s (%s:%d): EXIT. Return Code = %d\n", gFnLevel, __func__, __FILE__, __LINE__, nRC); gFnLevel--; return nRC; } // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.2/rigs/adat/adt_200a.h0000644000175000017500000001220614752216205013225 00000000000000// --------------------------------------------------------------------------- // ADT-200A // --------------------------------------------------------------------------- // // adt_200a.h // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012 Frank Goenninger. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #if !defined( __ADT_200A_INCLUDED__ ) #define __ADT_200A_INCLUDED__ // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include "rig.h" // --------------------------------------------------------------------------- // ADAT INCLUDES // --------------------------------------------------------------------------- #include "adat.h" // --------------------------------------------------------------------------- // ADT-200A USB DEFINITIONS // --------------------------------------------------------------------------- #define ADT_200A_VENDOR_ID 0x0403 #define ADT_200A_PRODUCT_ID 0x6001 #define ADT_200A_VENDOR_NAME "FTDI" #define ADT_200A_PRODUCT_NAME "TRX3C Serial C945D5B" #define ADT_200A_USB_INTERFACE_NR 0x00 #define ADT_200A_USB_CONFIGURATION_VALUE 0x01 #define ADT_200A_ALTERNATE_SETTIMG 0x00 #define ADT_200A_USB_INPUT_ENDPOINT 0x81 #define ADT_200A_USB_INPUT_MAX_PACKET_SIZE 64 #define ADT_200A_USB_OUTPUT_ENDPOINT b0x02 #define ADT_200A_USB_OUTPUT_MAX_PACKET_SIZE 64 // --------------------------------------------------------------------------- // ADT-200A CAPS DEFINITIONS // --------------------------------------------------------------------------- #define ADT_200A_GET_LEVEL \ ( \ RIG_LEVEL_PREAMP | \ RIG_LEVEL_ATT | \ RIG_LEVEL_AF | \ RIG_LEVEL_NR | \ RIG_LEVEL_CWPITCH | \ RIG_LEVEL_RFPOWER | \ RIG_LEVEL_MICGAIN | \ RIG_LEVEL_KEYSPD | \ RIG_LEVEL_METER | \ RIG_LEVEL_BKIN_DLYMS | \ RIG_LEVEL_RAWSTR | \ RIG_LEVEL_SWR | \ RIG_LEVEL_ALC ) #define ADT_200A_SET_LEVEL \ ( \ RIG_LEVEL_PREAMP | \ RIG_LEVEL_ATT | \ RIG_LEVEL_AF | \ RIG_LEVEL_NR | \ RIG_LEVEL_CWPITCH | \ RIG_LEVEL_RFPOWER | \ RIG_LEVEL_MICGAIN | \ RIG_LEVEL_KEYSPD | \ RIG_LEVEL_METER | \ RIG_LEVEL_BKIN_DLYMS | \ RIG_LEVEL_ALC ) #define ADT_200A_MODES \ ( \ RIG_MODE_AM | \ RIG_MODE_CW | \ RIG_MODE_USB | \ RIG_MODE_LSB | \ RIG_MODE_FM | \ RIG_MODE_CWR | \ RIG_MODE_SAL | \ RIG_MODE_SAH ) // ADT-200A VFO #defines #define ADT_200A_FRA RIG_VFO_N(0) #define ADT_200A_FRB RIG_VFO_N(1) #define ADT_200A_FRC RIG_VFO_N(2) #define ADT_200A_VFO (ADT_200A_FRA|ADT_200A_FRB|ADT_200A_FRC) #define ADT_200A_RIT 9999 #define ADT_200A_XIT 9999 // This is more-than-likely not accurate #define ADT_200A_STR_CAL {9, {\ { 0, -60},\ { 3, -48},\ { 6, -36},\ { 9, -24},\ {12, -12},\ {15, 0},\ {20, 20},\ {25, 40},\ {30, 60}}\ } // ADT-200A FUNCs #define ADT_200A_FUNCS (RIG_FUNC_VOX|RIG_FUNC_NB|RIG_FUNC_NR) // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- #endif hamlib-4.6.2/rigs/adat/adat.h0000644000175000017500000004371214752216205012652 00000000000000// --------------------------------------------------------------------------- // ADAT // --------------------------------------------------------------------------- // // adat.h // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012, 2023 Frank Goenninger. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #if !defined( __ADAT_INCLUDED__ ) #define __ADAT_INCLUDED__ // --------------------------------------------------------------------------- // SYSTEM INCLUDES // --------------------------------------------------------------------------- #include // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include #include "token.h" // --------------------------------------------------------------------------- // GLOBAL DEFINITIONS // --------------------------------------------------------------------------- #define BACKEND_VER "20230927" #define ADAT_BUFSZ 255 #define ADAT_RESPSZ 255 #define ADAT_CR "\x0d" #define ADAT_EOL "\x0a" #define ADAT_BOM "$" // Begin of message #define ADAT_EOM ADAT_CR // End of message #define ADAT_ON 1 #define ADAT_OFF 0 #define ADAT_TOGGLE_ON ADAT_ON #define ADAT_TOGGLE_OFF ADAT_OFF #define ADAT_FREQ_UNIT_HZ "Hz" #define ADAT_FREQ_UNIT_HZ_LEN 2 #define ADAT_FREQ_UNIT_KHZ "kHz" #define ADAT_FREQ_UNIT_KHZ_LEN 3 #define ADAT_FREQ_UNIT_MHZ "MHz" #define ADAT_FREQ_UNIT_MHZ_LEN 3 #define ADAT_FREQ_UNIT_GHZ "GHz" #define ADAT_FREQ_UNIT_GHZ_LEN 3 #define TOKEN_ADAT_PRODUCT_NAME TOKEN_BACKEND(1) #define ADAT_SLEEP_MICROSECONDS_BETWEEN_CMDS (11*1000) // = 11 ms #define ADAT_SLEEP_AFTER_RIG_CLOSE 2 // unit: seconds #define ADAT_SLEEP_AFTER_RIG_OPEN 2 // unit: seconds // ADAT VFO SET/GET DEFINITIONS #define ADAT_NR_VFOS 3 // Each mode is defined by three values: // ADAT_VFO_STR_... -> The string as given back by TRX when asked by // $VFO? // ADAT_VFO_RNR_... -> The Hamlib number of the mode: RIG_VFO_... // ADAT_VFO_ANR_... -> The ADAT Nr representing the VFO when setting it #define ADAT_VFO_STR_A "A" #define ADAT_VFO_RNR_A RIG_VFO_A #define ADAT_VFO_ANR_A 1 #define ADAT_VFO_STR_B "B" #define ADAT_VFO_RNR_B RIG_VFO_B #define ADAT_VFO_ANR_B 2 #define ADAT_VFO_STR_C "C" #define ADAT_VFO_RNR_C RIG_VFO_C #define ADAT_VFO_ANR_C 3 // ADAT MODE DEFINITIONS #define ADAT_MODE_LENGTH 15 #define ADAT_NR_MODES 8 // Each mode is defined by three values: // ADAT_MODE_STR_... -> The string as given back by TRX when asked by // $MOD? // ADAT_MODE_RNR_... -> The Hamlib number of the mode: RIG_MODE_... // ADAT_MODE_ANR_... -> The ADAT Nr representing the mode when setting it #define ADAT_MODE_STR_CW_R "CW-R" #define ADAT_MODE_RNR_CW_R RIG_MODE_CWR #define ADAT_MODE_ANR_CW_R 0 #define ADAT_MODE_STR_CW "CW" #define ADAT_MODE_RNR_CW RIG_MODE_CW #define ADAT_MODE_ANR_CW 1 #define ADAT_MODE_STR_LSB "LSB" #define ADAT_MODE_RNR_LSB RIG_MODE_LSB #define ADAT_MODE_ANR_LSB 2 #define ADAT_MODE_STR_USB "USB" #define ADAT_MODE_RNR_USB RIG_MODE_USB #define ADAT_MODE_ANR_USB 3 #define ADAT_MODE_STR_AM "AM" #define ADAT_MODE_RNR_AM RIG_MODE_AM #define ADAT_MODE_ANR_AM 5 #define ADAT_MODE_STR_AM_SL "AM-SL" #define ADAT_MODE_RNR_AM_SL RIG_MODE_SAL #define ADAT_MODE_ANR_AM_SL 6 #define ADAT_MODE_STR_AM_SU "AM-SU" #define ADAT_MODE_RNR_AM_SU RIG_MODE_SAH #define ADAT_MODE_ANR_AM_SU 7 #define ADAT_MODE_STR_FM "FM" #define ADAT_MODE_RNR_FM RIG_MODE_FM #define ADAT_MODE_ANR_FM 8 // ADAT PTT DEFINITIONS #define ADAT_PTT_STATUS_ANR_ON ADAT_ON #define ADAT_PTT_STATUS_RNR_ON RIG_PTT_ON #define ADAT_PTT_STATUS_ANR_OFF ADAT_OFF #define ADAT_PTT_STATUS_RNR_OFF RIG_PTT_OFF // ADAT POWER LEVEL DEFINITIONS #define ADAT_PWR_LVL_ANR_00 0 #define ADAT_PWR_LVL_RNR_00 100 // 100 mW #define ADAT_PWR_LVL_ANR_01 1 #define ADAT_PWR_LVL_RNR_01 300 // 300 mW #define ADAT_PWR_LVL_ANR_02 2 #define ADAT_PWR_LVL_RNR_02 1000 // ... #define ADAT_PWR_LVL_ANR_03 3 #define ADAT_PWR_LVL_RNR_03 2000 #define ADAT_PWR_LVL_ANR_04 4 #define ADAT_PWR_LVL_RNR_04 3000 #define ADAT_PWR_LVL_ANR_05 5 #define ADAT_PWR_LVL_RNR_05 5000 #define ADAT_PWR_LVL_ANR_06 6 #define ADAT_PWR_LVL_RNR_06 7000 #define ADAT_PWR_LVL_ANR_07 7 #define ADAT_PWR_LVL_RNR_07 10000 #define ADAT_PWR_LVL_ANR_08 8 #define ADAT_PWR_LVL_RNR_08 15000 #define ADAT_PWR_LVL_ANR_09 9 #define ADAT_PWR_LVL_RNR_09 20000 #define ADAT_PWR_LVL_ANR_10 10 #define ADAT_PWR_LVL_RNR_10 25000 #define ADAT_PWR_LVL_ANR_11 11 #define ADAT_PWR_LVL_RNR_11 30000 #define ADAT_PWR_LVL_ANR_12 12 #define ADAT_PWR_LVL_RNR_12 35000 #define ADAT_PWR_LVL_ANR_13 13 #define ADAT_PWR_LVL_RNR_13 40000 #define ADAT_PWR_LVL_ANR_14 14 // Default value after reset #define ADAT_PWR_LVL_RNR_14 45000 #define ADAT_PWR_LVL_ANR_15 15 #define ADAT_PWR_LVL_RNR_15 50000 // 50 W #define ADAT_MAX_POWER_IN_mW ADAT_PWR_LVL_RNR_15 // ADAT CHANNEL CAPS #define ADAT_MEM_CAPS \ { \ .vfo = 1, \ .ant = 1, \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .tx_vfo = 1, \ .rit = 1, \ .xit = 1, \ .tuning_step = 1, \ .channel_desc = 1 \ } #define ADAT_MEM_DESC_SIZE 64 // ADAT OPCODES - Kind of an internal command within ADAT Hamlib Backend #define ADAT_OPCODE_BASE_PTT 110000 #define ADAT_OPCODE_PTT_SWITCH_ON (ADAT_OPCODE_BASE_PTT + 1) #define ADAT_OPCODE_PTT_SWITCH_OFF (ADAT_OPCODE_BASE_PTT + 2) // --------------------------------------------------------------------------- // Individual ADAT CAT commands // --------------------------------------------------------------------------- #define ADAT_CMD_DEF_ADAT_SPECIAL (1<<30) // -- NIL -- (Marks the end of a cmd list) #define ADAT_CMD_DEF_NIL 0 // -- ADAT SPECIAL: DISPLAY OFF -- #define ADAT_CMD_DEF_STRING_DISPLAY_OFF "$VRU>"ADAT_CR // -- ADAT SPECIAL: DISPLAY ON -- #define ADAT_CMD_DEF_STRING_DISPLAY_ON "$VRU<"ADAT_CR // -- ADAT SPECIAL: GET SERIAL NR -- #define ADAT_CMD_DEF_STRING_GET_SERIAL_NR "$CIS?"ADAT_CR // -- ADAT SPECIAL: GET FIRMWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_FW_VERSION "$CIF?"ADAT_CR // -- ADAT SPECIAL: GET HARDWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_HW_VERSION "$CIH?"ADAT_CR // -- ADAT SPECIAL: GET FIRMWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_ID_CODE "$CID?"ADAT_CR // -- ADAT SPECIAL: GET GUI FIRMWARE VERSION -- #define ADAT_CMD_DEF_STRING_GET_GUI_FW_VERSION "$CIG?"ADAT_CR // -- ADAT SPECIAL: GET OPTIONS -- #define ADAT_CMD_DEF_STRING_GET_OPTIONS "$CIO?"ADAT_CR // -- ADAT SPECIAL: GET CALLSIGN -- #define ADAT_CMD_DEF_STRING_GET_CALLSIGN "$CAL?"ADAT_CR // -- ADAT SPECIAL: SET CALLSIGN -- #define ADAT_CMD_DEF_STRING_SET_CALLSIGN "$CAL:" // -- HAMLIB DEFINED COMMANDS -- // -- GET FREQ -- #define ADAT_CMD_DEF_GET_FREQ (1<<0) #define ADAT_CMD_DEF_STRING_GET_FREQ "$FRA?"ADAT_CR // -- SET FREQ -- #define ADAT_CMD_DEF_SET_FREQ (1<<1) #define ADAT_CMD_DEF_STRING_SET_FREQ "$FR1:" // -- GET VFO -- // -- GET MODE -- #define ADAT_CMD_DEF_GET_MODE (1<<2) #define ADAT_CMD_DEF_STRING_GET_MODE "$MOD?"ADAT_CR // -- SET VFO -- #define ADAT_CMD_DEF_SET_VFO (1<<3) #define ADAT_CMD_DEF_STRING_SWITCH_ON_VFO "$VO%1d>%s" #define ADAT_CMD_DEF_STRING_SET_VFO_AS_MAIN_VFO "$VO%1d%%%s" // -- SET MODE -- #define ADAT_CMD_DEF_SET_MODE (1<<4) #define ADAT_CMD_DEF_STRING_SET_MODE "$MOD:" // -- SET PTT -- #define ADAT_CMD_DEF_SET_PTT (1<<5) #define ADAT_CMD_DEF_STRING_SET_PTT "$MOX%s%s" #define ADAT_CMD_PTT_STR_OFF "<" #define ADAT_CMD_PTT_STR_ON ">" // -- GET PTT -- #define ADAT_CMD_DEF_GET_PTT (1<<6) #define ADAT_CMD_DEF_STRING_GET_PTT "$MTR?"ADAT_CR // -- GET POWER STATUS -- // -- GET INFO -- // Nothing to define here // -- OPEN ADAT -- // Nothing to define here // -- ADAT SPECIAL: RECOVER FROM ERROR -- // Nothing to define here // --------------------------------------------------------------------------- // ADAT PRIVATE DATA // --------------------------------------------------------------------------- #define ADAT_PRIV_DATA_PRODUCTNAME_LENGTH 255 #define ADAT_PRIV_DATA_SERIALNR_LENGTH 255 #define ADAT_PRIV_DATA_IDCODE_LENGTH 255 #define ADAT_PRIV_DATA_OPTIONS_LENGTH 255 #define ADAT_PRIV_DATA_FWVERSION_LENGTH 255 #define ADAT_PRIV_DATA_HWVERSION_LENGTH 255 #define ADAT_PRIV_DATA_GUIFWVERSION_LENGTH 255 #define ADAT_PRIV_DATA_CALLSIGN_LENGTH 255 #define ADAT_PRIV_DATA_CMD_LENGTH 255 #define ADAT_PRIV_DATA_RESULT_LENGTH 255 typedef struct _adat_priv_data { int nOpCode; char acProductName[ ADAT_PRIV_DATA_PRODUCTNAME_LENGTH + 1]; // Future use (USB direct I/O) // ADAT device info char acSerialNr[ ADAT_PRIV_DATA_SERIALNR_LENGTH + 1 ]; char acIDCode[ ADAT_PRIV_DATA_IDCODE_LENGTH + 1 ]; char acOptions[ ADAT_PRIV_DATA_OPTIONS_LENGTH + 1 ]; char acFWVersion[ ADAT_PRIV_DATA_FWVERSION_LENGTH + 1 ]; char acHWVersion[ ADAT_PRIV_DATA_HWVERSION_LENGTH + 1 ]; char acGUIFWVersion[ ADAT_PRIV_DATA_GUIFWVERSION_LENGTH + 1 ]; char acCallsign[ ADAT_PRIV_DATA_CALLSIGN_LENGTH + 1 ]; // ADAT Operational Settings: will change during TRX use int nCurrentVFO; vfo_t nRIGVFONr; freq_t nFreq; char acRXFreq[ ADAT_BUFSZ ]; char acTXFreq[ ADAT_BUFSZ ]; rmode_t nRIGMode; char acADATMode[ ADAT_MODE_LENGTH + 1 ]; int nADATMode; pbwidth_t nWidth; int nADATPTTStatus; ptt_t nRIGPTTStatus; value_t mNB1; value_t mNB2; value_t mAGC; value_t mRFGain; value_t mIFShift; value_t mRawStr; // ADAT Command-related Values char acCmd[ ADAT_PRIV_DATA_CMD_LENGTH + 1 ]; int nCmdKind; char acResult[ ADAT_PRIV_DATA_RESULT_LENGTH + 1 ]; int nRC; } adat_priv_data_t, * adat_priv_data_ptr; // --------------------------------------------------------------------------- // ADAT CAT COMMAND DATA TYPE DECLARATIONS // --------------------------------------------------------------------------- typedef unsigned long long adat_cmd_id_t; // Bit mask for commands. Each command // is represented by 1 bit. // adat_cmd_def : ADAT COMMAND DEFINITION. // Basic idea: Each command can be made of several strings to be sent // to the ADAT device. Therefore it is possible to build aggregated // commands which will be executed as a set of individual commands // executed by adat_transaction(). The last value as returned by the // commands will be set as overall command result. typedef enum { ADAT_CMD_KIND_WITH_RESULT = 0, // After sending a command to the ADAT, // a result has to be read. ADAT_CMD_KIND_WITHOUT_RESULT = 1 } adat_cmd_kind_t; typedef struct _adat_cmd_def_t { adat_cmd_id_t nCmdId; // Bit indicating this cmd adat_cmd_kind_t nCmdKind; // Defines if result expected int (*pfCmdFn)(RIG *pRig); // Fn to be called to execute this cmd int nNrCmdStrs; // Oh my, C as a language ... I'd love to // switch to Common Lisp ... What a hack here ... char *pacCmdStrs[]; // Commands to be executed if no CmdFn given } adat_cmd_def_t, * adat_cmd_def_ptr; typedef struct _adat_cmd_table_t { int nNrCmds; adat_cmd_def_ptr adat_cmds[]; } adat_cmd_table_t, * adat_cmd_table_ptr; typedef struct _adat_cmd_list_t { int nNrCmds; adat_cmd_def_ptr adat_cmds[]; } adat_cmd_list_t, * adat_cmd_list_ptr; // --------------------------------------------------------------------------- // OTHER ADAT DATA TYPES // --------------------------------------------------------------------------- typedef enum { ADAT_FREQ_PARSE_MODE_WITH_VFO = 0, ADAT_FREQ_PARSE_MODE_WITHOUT_VFO = 1 } adat_freq_parse_mode_t; // ADAT MODE DEFINITION typedef struct _adat_mode_def { char *pcADATModeStr; rmode_t nRIGMode; int nADATMode; } adat_mode_def_t, * adat_mode_def_ptr; typedef struct _adat_mode_list { int nNrModes; adat_mode_def_t adat_modes[ ADAT_NR_MODES ]; } adat_mode_list_t, * adat_mode_list_ptr; // ADAT VFO DEFINITION typedef struct _adat_vfo_def { char *pcADATVFOStr; vfo_t nRIGVFONr; int nADATVFONr; } adat_vfo_def_t, * adat_vfo_def_ptr; typedef struct _adat_vfo_list { int nNrVFOs; adat_vfo_def_t adat_vfos[ ADAT_NR_VFOS ]; } adat_vfo_list_t, * adat_vfo_list_ptr; // --------------------------------------------------------------------------- // ADAT INTERNAL FUNCTION DECLARATIONS // --------------------------------------------------------------------------- // Helper functions size_t trimwhitespace(char *, size_t, const char *); int adat_print_cmd(adat_cmd_def_ptr); int adat_parse_freq(char *, adat_freq_parse_mode_t, int *, freq_t *); int adat_parse_mode(char *, rmode_t *, char *); int adat_mode_rnr2anr(rmode_t, int *); #ifdef XXREMOVEDXX // this function wasn't referenced anywhere int adat_mode_anr2rnr(int, rmode_t *); #endif #ifdef XXREMOVEDXX // this function wasn't referenced anywhere int adat_parse_vfo(char *, vfo_t *, int *); #endif int adat_vfo_rnr2anr(vfo_t, int *); int adat_vfo_anr2rnr(int, vfo_t *); int adat_parse_ptt(char *, int *); int adat_ptt_rnr2anr(ptt_t, int *); int adat_ptt_anr2rnr(int, ptt_t *); int adat_send(RIG *, char *); int adat_receive(RIG *, char *); int adat_priv_set_cmd(RIG *, char *, int); int adat_priv_set_result(RIG *, char *); int adat_priv_clear_result(RIG *); int adat_get_single_cmd_result(RIG *); int adat_cmd_recover_from_error(RIG *, int); int adat_transaction(RIG *, adat_cmd_list_ptr); // Command implementation int adat_cmd_fn_get_serial_nr(RIG *); int adat_cmd_fn_get_fw_version(RIG *); int adat_cmd_fn_get_hw_version(RIG *); int adat_cmd_fn_get_gui_fw_version(RIG *); int adat_cmd_fn_get_id_code(RIG *); int adat_cmd_fn_get_options(RIG *); int adat_cmd_fn_get_callsign(RIG *); int adat_cmd_fn_set_freq(RIG *); int adat_cmd_fn_get_freq(RIG *); int adat_cmd_fn_get_mode(RIG *); int adat_cmd_fn_set_mode(RIG *); int adat_cmd_fn_get_vfo(RIG *); int adat_cmd_fn_set_vfo(RIG *); int adat_cmd_fn_get_ptt(RIG *); int adat_cmd_fn_set_ptt(RIG *); // --------------------------------------------------------------------------- // ADAT FUNCTION DECLARATIONS // --------------------------------------------------------------------------- int adat_init(RIG *); int adat_cleanup(RIG *); int adat_reset(RIG *, reset_t); int adat_open(RIG *); int adat_close(RIG *); int adat_set_conf(RIG *, hamlib_token_t, const char *val); int adat_get_conf(RIG *, hamlib_token_t, char *val); int adat_set_freq(RIG *, vfo_t, freq_t); int adat_get_freq(RIG *, vfo_t, freq_t *); int adat_set_vfo(RIG *, vfo_t); int adat_get_vfo(RIG *, vfo_t *); int adat_set_ptt(RIG *, vfo_t, ptt_t); int adat_get_ptt(RIG *, vfo_t, ptt_t *); int adat_set_mode(RIG *, vfo_t, rmode_t, pbwidth_t); int adat_get_mode(RIG *, vfo_t, rmode_t *, pbwidth_t *); int adat_set_func(RIG *, vfo_t, setting_t func, int); int adat_get_func(RIG *, vfo_t, setting_t func, int *); int adat_set_level(RIG *, vfo_t, setting_t level, value_t); int adat_get_level(RIG *, vfo_t, setting_t level, value_t *); int adat_handle_event(RIG *); const char *adat_get_info(RIG *); int adat_mW2power(RIG *, float *, unsigned int, freq_t, rmode_t); int adat_power2mW(RIG *, unsigned int *, float, freq_t, rmode_t); int adat_get_powerstat(RIG *, powerstat_t *); extern struct rig_caps adt_200a_caps; // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- #endif hamlib-4.6.2/rigs/adat/Makefile.am0000644000175000017500000000022614752216205013615 00000000000000ADATSRC = adt_200a.c adt_200a.h adat.c adat.h noinst_LTLIBRARIES = libhamlib-adat.la libhamlib_adat_la_SOURCES = $(ADATSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/adat/Makefile.in0000644000175000017500000005233314752216215013635 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/adat ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_adat_la_LIBADD = am__objects_1 = adt_200a.lo adat.lo am_libhamlib_adat_la_OBJECTS = $(am__objects_1) libhamlib_adat_la_OBJECTS = $(am_libhamlib_adat_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/adat.Plo ./$(DEPDIR)/adt_200a.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_adat_la_SOURCES) DIST_SOURCES = $(libhamlib_adat_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ADATSRC = adt_200a.c adt_200a.h adat.c adat.h noinst_LTLIBRARIES = libhamlib-adat.la libhamlib_adat_la_SOURCES = $(ADATSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/adat/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/adat/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-adat.la: $(libhamlib_adat_la_OBJECTS) $(libhamlib_adat_la_DEPENDENCIES) $(EXTRA_libhamlib_adat_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_adat_la_OBJECTS) $(libhamlib_adat_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adat.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adt_200a.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/adat.Plo -rm -f ./$(DEPDIR)/adt_200a.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/adat.Plo -rm -f ./$(DEPDIR)/adt_200a.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/adat/Android.mk0000644000175000017500000000042214752216205013470 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := adat.c adt_200a.c LOCAL_MODULE := adat LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := $(LOCAL_SHARED_LIBRARIES) -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/adat/adt_200a.c0000644000175000017500000001753714752216205013234 00000000000000// --------------------------------------------------------------------------- // ADT-200A HAMLIB BACKEND // --------------------------------------------------------------------------- // // adt_200a.c // // Created by Frank Goenninger DG1SBG. // Copyright © 2011, 2012, 2023 Frank Goenninger. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // --------------------------------------------------------------------------- // ADT-200A INCLUDES // --------------------------------------------------------------------------- #include "adt_200a.h" // --------------------------------------------------------------------------- // GLOBAL DEFINITIONS // --------------------------------------------------------------------------- // GLOBAL VARS // static const struct confparams adt_200a_cfg_params[] = // { // { TOKEN_PRODUCT_NAME, "usb_product_name", "USB Product Name", "USB Product Name (DSP Bo // Model + ' Serial '+ ID Code, e.g. 'TRX3C Serial C945D5B' )", // ADT_200A_PRODUCT_NAME, RIG_CONF_STRING, { .n = { 0,0,0 } } // }, // // { RIG_CONF_END, NULL, } //}; // --------------------------------------------------------------------------- // ADT-200A HAMLIB CAPS / DESCRIPTION // --------------------------------------------------------------------------- struct rig_caps adt_200a_caps = { RIG_MODEL(RIG_MODEL_ADT_200A), .model_name = "ADT-200A", .mfg_name = "ADAT www.adat.ch", .version = BACKEND_VER ".0", .copyright = "Frank Goenninger, DG1SBG. License: Creative Commons", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .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_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 250, .retry = 3, .has_get_func = ADT_200A_FUNCS, .has_set_func = ADT_200A_FUNCS, .has_get_level = ADT_200A_GET_LEVEL, .has_set_level = RIG_LEVEL_SET(ADT_200A_SET_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 5, 10, RIG_DBLST_END, }, .attenuator = { 5, 10, 15, 20, 25, RIG_DBLST_END, }, .max_rit = ADT_200A_RIT, .max_xit = ADT_200A_XIT, .max_ifshift = Hz(500), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = 0, .bank_qty = 1, .chan_desc_sz = ADAT_MEM_DESC_SIZE, .chan_list = { { 0, 99, RIG_MTYPE_MEM, ADAT_MEM_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(10), MHz(30), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, { MHz(50), MHz(50.5), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, { MHz(70), MHz(70.7), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, { MHz(146), MHz(148), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(10), MHz(30), ADT_200A_MODES, mW(100), W(50), ADT_200A_VFO }, { MHz(50), MHz(50.5), ADT_200A_MODES, mW(10), W(1), ADT_200A_FRA }, { MHz(70), MHz(70.7), ADT_200A_MODES, mW(10), W(1), ADT_200A_FRA }, { MHz(146), MHz(148), ADT_200A_MODES, mW(10), mW(100), ADT_200A_FRA }, RIG_FRNG_END, }, .rx_range_list2 = { { kHz(10), MHz(30), ADT_200A_MODES, -1, -1, ADT_200A_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { { kHz(10), MHz(30), ADT_200A_MODES, mW(100), W(50), ADT_200A_VFO }, RIG_FRNG_END, }, .tuning_steps = { { ADT_200A_MODES, RIG_TS_ANY }, // TODO: get actual list here RIG_TS_END, }, .filters = { { RIG_MODE_CW | RIG_MODE_CWR, Hz(50) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(75) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(100) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(150) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(200) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(300) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(750) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(1000) }, { RIG_MODE_CW | RIG_MODE_CWR, Hz(1200) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(300) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(500) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(750) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1000) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1200) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1500) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(1800) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2000) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2200) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2400) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(2700) }, { RIG_MODE_LSB | RIG_MODE_USB, Hz(3500) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(3000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(3500) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(4000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(4500) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(5000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(6000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(7000) }, { RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH, Hz(8000) }, { RIG_MODE_FM, Hz(6000) }, { RIG_MODE_FM, Hz(7000) }, { RIG_MODE_FM, Hz(8000) }, { RIG_MODE_FM, Hz(9000) }, { RIG_MODE_FM, Hz(10000) }, { RIG_MODE_FM, Hz(12000) }, { RIG_MODE_FM, Hz(15000) }, { RIG_MODE_FM, Hz(20000) }, { RIG_MODE_FM, Hz(25000) }, RIG_FLT_END, }, .str_cal = ADT_200A_STR_CAL, // .cfgparams = adt_200a_cfg_params, .rig_init = adat_init, .rig_cleanup = adat_cleanup, .rig_open = adat_open, .reset = adat_reset, .rig_close = adat_close, .set_conf = adat_set_conf, .get_conf = adat_get_conf, .set_freq = adat_set_freq, .get_freq = adat_get_freq, .get_level = adat_get_level, .set_level = adat_set_level, .set_mode = adat_set_mode, .get_mode = adat_get_mode, .get_vfo = adat_get_vfo, .set_vfo = adat_set_vfo, .get_ptt = adat_get_ptt, .set_ptt = adat_set_ptt, .decode_event = adat_handle_event, .get_info = adat_get_info, .power2mW = adat_power2mW, .mW2power = adat_mW2power, .get_powerstat = adat_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.2/rigs/rft/0000755000175000017500000000000014752216243011525 500000000000000hamlib-4.6.2/rigs/rft/Makefile.am0000644000175000017500000000020314752216205013472 00000000000000RFTSRC = ekd500.c rft.c rft.h noinst_LTLIBRARIES = libhamlib-rft.la libhamlib_rft_la_SOURCES = $(RFTSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/rft/Makefile.in0000644000175000017500000005225214752216216013520 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/rft ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_rft_la_LIBADD = am__objects_1 = ekd500.lo rft.lo am_libhamlib_rft_la_OBJECTS = $(am__objects_1) libhamlib_rft_la_OBJECTS = $(am_libhamlib_rft_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ekd500.Plo ./$(DEPDIR)/rft.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_rft_la_SOURCES) DIST_SOURCES = $(libhamlib_rft_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RFTSRC = ekd500.c rft.c rft.h noinst_LTLIBRARIES = libhamlib-rft.la libhamlib_rft_la_SOURCES = $(RFTSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/rft/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/rft/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-rft.la: $(libhamlib_rft_la_OBJECTS) $(libhamlib_rft_la_DEPENDENCIES) $(EXTRA_libhamlib_rft_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_rft_la_OBJECTS) $(libhamlib_rft_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ekd500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rft.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ekd500.Plo -rm -f ./$(DEPDIR)/rft.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ekd500.Plo -rm -f ./$(DEPDIR)/rft.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/rft/Android.mk0000644000175000017500000000037514752216205013361 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ekd500.c rft.c LOCAL_MODULE := rft LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/rft/rft.h0000644000175000017500000000204314752216205012406 00000000000000/* * Hamlib RFT backend - main header * Copyright (c) 2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RFT_H #define _RFT_H 1 #include #define BACKEND_VER "20031007" int rft_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern struct rig_caps ekd500_caps; #endif /* _RFT_H */ hamlib-4.6.2/rigs/rft/rft.c0000644000175000017500000000450214752216205012403 00000000000000/* * Hamlib RFT backend - main file * Copyright (c) 2003 by Thomas B. Ruecker * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "rft.h" #define BUFSZ 64 #define CR "\x0d" #define EOM CR /* * rft_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL */ int rft_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, CR, 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * rft_set_freq * Assumes rig!=NULL */ int rft_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16], ackbuf[16]; int ack_len, retval; /* */ SNPRINTF(freqbuf, sizeof(freqbuf), "FRQ%f" EOM, (float)freq / 1000); retval = rft_transaction(rig, freqbuf, strlen(freqbuf), ackbuf, &ack_len); return retval; } /* * initrigs_rft is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(rft) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ekd500_caps); return RIG_OK; } hamlib-4.6.2/rigs/rft/ekd500.c0000644000175000017500000000650414752216205012604 00000000000000/* * Hamlib RFT backend - EKD-500 description * Copyright (c) 2003-2009 by Thomas B. Ruecker * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "rft.h" #define EKD500_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_FM) #define EKD500_FUNC (RIG_FUNC_NONE) #define EKD500_LEVEL_ALL (RIG_LEVEL_NONE) #define EKD500_PARM_ALL (RIG_PARM_NONE) #define EKD500_VFO (RIG_VFO_A) #define EKD500_VFO_OPS (RIG_OP_NONE) /* * EKD-500 rig capabilities. * * Documentation: * http://www.premium-rx.org/ekd500.htm */ struct rig_caps ekd500_caps = { RIG_MODEL(RIG_MODEL_EKD500), .model_name = "EKD-500", .mfg_name = "RFT", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 2400, .serial_data_bits = 7, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = EKD500_FUNC, .has_set_func = EKD500_FUNC, .has_get_level = EKD500_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(EKD500_LEVEL_ALL), .has_get_parm = EKD500_PARM_ALL, .has_set_parm = RIG_PARM_SET(EKD500_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = EKD500_VFO_OPS, .chan_list = { RIG_CHAN_END, /* FIXME */ }, .rx_range_list1 = { {kHz(10), MHz(30), EKD500_MODES, -1, -1, EKD500_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), EKD500_MODES, -1, -1, EKD500_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {EKD500_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = NULL, .set_freq = rft_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/elad/0000755000175000017500000000000014752216242011636 500000000000000hamlib-4.6.2/rigs/elad/elad.h0000644000175000017500000001546614752216205012647 00000000000000/* * Hamlib ELAD backend - main header * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2018 by Giovanni Franza, info@hb9eik.ch * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ELAD_H #define _ELAD_H 1 #include #include "rig.h" #include "token.h" #define BACKEND_VER "20220608" #define EOM_KEN ';' #define EOM_TH '\r' #define ELAD_MODE_TABLE_MAX 24 #define ELAD_MAX_BUF_LEN 128 /* max answer len, arbitrary */ /* Tokens for Parameters common to multiple rigs. * Use token # >= 1 or <= 100. Defined here so they will be * available in Kenwood name space. */ #define TOK_VOICE TOKEN_BACKEND(1) #define TOK_FINE TOKEN_BACKEND(2) #define TOK_XIT TOKEN_BACKEND(3) #define TOK_RIT TOKEN_BACKEND(4) /* Token structure assigned to .cfgparams in rig_caps */ extern const struct confparams elad_cfg_params[]; /* * modes in use by the "MD" command */ #define MD_NONE '0' #define MD_LSB '1' #define MD_USB '2' #define MD_CW '3' #define MD_FM '4' #define MD_AM '5' #define MD_FSK '6' #define MD_CWR '7' #define MD_FSKR '9' struct elad_priv_caps { char cmdtrm; /* Command termination chars (ken=';' or th='\r') */ int if_len; /* length of IF; answer excluding ';' terminator */ rmode_t *mode_table; }; struct elad_priv_data { char info[ELAD_MAX_BUF_LEN]; split_t split; /* current split state */ int k2_ext_lvl; /* Initial K2 extension level */ int k3_ext_lvl; /* Initial K3 extension level */ int k2_md_rtty; /* K2 RTTY mode available flag, 1 = RTTY, 0 = N/A */ char *fw_rev; /* firmware revision level */ int trn_state; /* AI state discovered at startup */ unsigned fw_rev_uint; /* firmware revision as a number 1.07 -> 107 */ char verify_cmd[4]; /* command used to verify set commands */ int is_emulation; /* flag for TS-2000 emulations */ void * data; /* model specific data */ rmode_t curr_mode; /* used for is_emulation to avoid get_mode on VFOB */ }; #define elad_caps(rig) ((struct elad_priv_caps *)(rig)->caps->priv) extern rmode_t elad_mode_table[ELAD_MODE_TABLE_MAX]; extern const tone_t elad38_ctcss_list[]; extern const tone_t elad42_ctcss_list[]; int elad_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize); int elad_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected); rmode_t elad2rmode(unsigned char mode, const rmode_t mode_table[]); char rmode2elad(rmode_t mode, const rmode_t mode_table[]); int elad_init(RIG *rig); int elad_cleanup(RIG *rig); int elad_open(RIG *rig); int elad_close(RIG *rig); int elad_set_vfo(RIG *rig, vfo_t vfo); int elad_set_vfo_main_sub(RIG *rig, vfo_t vfo); int elad_get_vfo_if(RIG *rig, vfo_t *vfo); int elad_get_vfo_main_sub(RIG *rig, vfo_t *vfo); int elad_set_split(RIG *rig, vfo_t vfo , split_t split, vfo_t txvfo); int elad_set_split_vfo(RIG *rig, vfo_t vfo , split_t split, vfo_t txvfo); int elad_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); int elad_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int elad_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int elad_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq); int elad_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int elad_get_rit(RIG *rig, vfo_t vfo, shortfreq_t * rit); int elad_set_xit(RIG * rig, vfo_t vfo, shortfreq_t rit); int elad_get_xit(RIG *rig, vfo_t vfo, shortfreq_t * rit); int elad_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int elad_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int elad_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int elad_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int elad_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int elad_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int elad_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int elad_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int elad_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int elad_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int elad_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone); int elad_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int elad_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int elad_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int elad_set_powerstat(RIG *rig, powerstat_t status); int elad_get_powerstat(RIG *rig, powerstat_t *status); int elad_reset(RIG *rig, reset_t reset); int elad_send_morse(RIG *rig, vfo_t vfo, const char *msg); int elad_set_ant (RIG * rig, vfo_t vfo, ant_t ant, value_t option); int elad_set_ant_no_ack(RIG * rig, vfo_t vfo, ant_t ant); int elad_get_ant (RIG * rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int elad_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int elad_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int elad_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt); int elad_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int elad_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int elad_set_mem(RIG *rig, vfo_t vfo, int ch); int elad_get_mem(RIG *rig, vfo_t vfo, int *ch); int elad_get_mem_if(RIG *rig, vfo_t vfo, int *ch); int elad_get_channel(RIG *rig, channel_t *chan); int elad_set_channel(RIG *rig, const channel_t *chan); int elad_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); const char * elad_get_info(RIG *rig); int elad_get_id(RIG *rig, char *buf); int elad_set_trn(RIG *rig, int trn); int elad_get_trn(RIG *rig, int *trn); /* only use if returned string has length 6, e.g. 'SQ011;' */ int get_elad_level(RIG *rig, const char *cmd, float *f); int get_elad_func(RIG *rig, const char *cmd, int *status); extern struct rig_caps fdm_duo_caps; #if 0 /* use when not interested in the answer, but want to check its len */ static int inline elad_simple_transaction(RIG *rig, const char *cmd, size_t expected) { struct elad_priv_data *priv = STATE(rig)->priv; return elad_safe_transaction(rig, cmd, priv->info, ELAD_MAX_BUF_LEN, expected); } #endif #endif /* _ELAD_H */ hamlib-4.6.2/rigs/elad/Makefile.am0000644000175000017500000000021214752216205013604 00000000000000ELADSRC = elad.c elad.h fdm_duo.c noinst_LTLIBRARIES = libhamlib-elad.la libhamlib_elad_la_SOURCES = $(ELADSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/elad/Makefile.in0000644000175000017500000005231214752216216013627 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/elad ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_elad_la_LIBADD = am__objects_1 = elad.lo fdm_duo.lo am_libhamlib_elad_la_OBJECTS = $(am__objects_1) libhamlib_elad_la_OBJECTS = $(am_libhamlib_elad_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/elad.Plo ./$(DEPDIR)/fdm_duo.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_elad_la_SOURCES) DIST_SOURCES = $(libhamlib_elad_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ELADSRC = elad.c elad.h fdm_duo.c noinst_LTLIBRARIES = libhamlib-elad.la libhamlib_elad_la_SOURCES = $(ELADSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/elad/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/elad/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-elad.la: $(libhamlib_elad_la_OBJECTS) $(libhamlib_elad_la_DEPENDENCIES) $(EXTRA_libhamlib_elad_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_elad_la_OBJECTS) $(libhamlib_elad_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elad.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdm_duo.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/elad.Plo -rm -f ./$(DEPDIR)/fdm_duo.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/elad.Plo -rm -f ./$(DEPDIR)/fdm_duo.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/elad/Android.mk0000644000175000017500000000040014752216205013460 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := elad.c fdm_duo.c LOCAL_MODULE := elad LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/elad/fdm_duo.c0000644000175000017500000003565414752216205013353 00000000000000/* * Hamlib ELAD backend - FDM_DUO description * Copyright (c) 2000-2004 by Stephane Fillod and Juergen Rinas * Copyright (c) 2018 by Giovanni Franza HB9EIK * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "elad.h" #define FDM_DUO_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FDM_DUO_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define FDM_DUO_AM_TX_MODES RIG_MODE_AM #define FDM_DUO_VFO (RIG_VFO_A|RIG_VFO_B) #define FDM_DUO_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC) #define FDM_DUO_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC) /* * elad_fdm_duo_get_info * Assumes rig!=NULL */ static const char * elad_fdm_duo_get_info(RIG *rig) { char firmbuf[50]; int retval; size_t firm_len; retval = elad_transaction(rig, "TY", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } firm_len = strlen(firmbuf); if (firm_len != 5) { rig_debug(RIG_DEBUG_ERR, "elad_get_info: wrong answer len=%d\n", (int)firm_len); return NULL; } switch (firmbuf[4]) { case '0': return "FDM-DUOHX (200W)"; case '1': return "FDM-DUOSAT (100W + AT)"; case '2': return "Japanese 50W type"; case '3': return "Japanese 20W type"; default: return "Firmware: unknown"; } } /* * elad_fdm_duo_set_level * Assumes rig!=NULL * * set levels of most functions * * WARNING: the commands differ slightly from the general versions in elad.c * e.g.: "SQ"=>"SQ0" , "AG"=>"AG0" */ int elad_fdm_duo_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int elad_val; switch (level) { case RIG_LEVEL_RFPOWER: elad_val = val.f * 100; /* level for FDM_DUOSAT is from 0.. 100W in SSB */ SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", elad_val); break; case RIG_LEVEL_AF: elad_val = val.f * 255; /* possible values for FDM_DUO are 000.. 255 */ SNPRINTF(levelbuf, sizeof(levelbuf), "AG0%03d", elad_val); break; case RIG_LEVEL_RF: elad_val = val.f * 100; /* possible values for FDM_DUO are 000.. 100 */ SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", elad_val); break; case RIG_LEVEL_SQL: elad_val = val.f * 255; /* possible values for FDM_DUO are 000.. 255 */ SNPRINTF(levelbuf, sizeof(levelbuf), "SQ0%03d", elad_val); break; case RIG_LEVEL_AGC: /* possible values for FDM_DUO 000(=off), 001(=fast), 002(=slow) */ /* hamlib argument is int, possible values rig.h:enum agc_level_e */ switch (val.i) { case RIG_AGC_OFF: elad_val = 0; break; case RIG_AGC_FAST: elad_val = 1; break; case RIG_AGC_SLOW: elad_val = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported agc value", __func__); return -RIG_EINVAL; }; SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", elad_val); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return elad_transaction(rig, levelbuf, NULL, 0); } /* * elad_get_level * Assumes rig!=NULL, val!=NULL */ int elad_fdm_duo_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len; int levelint; int retval; switch (level) { case RIG_LEVEL_RFPOWER: retval = elad_transaction(rig, "PC", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_AF: retval = elad_transaction(rig, "AG0", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (6 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[3], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 255.; return RIG_OK; case RIG_LEVEL_RF: retval = elad_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_SQL: retval = elad_transaction(rig, "SQ0", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (6 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[3], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 255.; return RIG_OK; case RIG_LEVEL_AGC: retval = elad_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } switch (ackbuf[4]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_FAST; break; case '2': val->i = RIG_AGC_SLOW; break; default: return -RIG_EPROTO; } return RIG_OK; case RIG_LEVEL_MICGAIN: case RIG_LEVEL_PREAMP: case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_KEYSPD: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_COMP: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; /* never reached */ } static struct elad_priv_caps fdm_duo_priv_caps = { .cmdtrm = EOM_KEN, }; /* * fdm_duo rig capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! */ struct rig_caps fdm_duo_caps = { RIG_MODEL(RIG_MODEL_ELAD_FDM_DUO), .model_name = "FDM-DUO", .mfg_name = "ELAD", .version = BACKEND_VER ".0", .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 = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 10, .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, .transceive = RIG_TRN_RIG, .rx_range_list1 = { {kHz(100), Hz(59999999), FDM_DUO_ALL_MODES, -1, -1, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, /* 100W class */ {kHz(1810), kHz(1850), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, /* 25W class */ {kHz(3500), kHz(3800), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(3500), kHz(3800), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(7), kHz(7200), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(7), kHz(7200), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), FDM_DUO_ALL_MODES, -1, -1, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(3500), MHz(4) - 1, FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(5250), kHz(5450), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(5250), kHz(5450), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(7), kHz(7300), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(7), kHz(7300), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(10100), kHz(10150), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(14), kHz(14350), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(18068), kHz(18168), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(21), kHz(21450), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {kHz(24890), kHz(24990), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(28), kHz(29700), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_OTHER_TX_MODES, 5000, 100000, FDM_DUO_VFO}, {MHz(50), kHz(52000), FDM_DUO_AM_TX_MODES, 5000, 25000, FDM_DUO_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {FDM_DUO_ALL_MODES, kHz(1)}, {FDM_DUO_ALL_MODES, Hz(2500)}, {FDM_DUO_ALL_MODES, kHz(5)}, {FDM_DUO_ALL_MODES, Hz(6250)}, {FDM_DUO_ALL_MODES, kHz(10)}, {FDM_DUO_ALL_MODES, Hz(12500)}, {FDM_DUO_ALL_MODES, kHz(15)}, {FDM_DUO_ALL_MODES, kHz(20)}, {FDM_DUO_ALL_MODES, kHz(25)}, {FDM_DUO_ALL_MODES, kHz(30)}, {FDM_DUO_ALL_MODES, kHz(100)}, {FDM_DUO_ALL_MODES, kHz(500)}, {FDM_DUO_ALL_MODES, MHz(1)}, {FDM_DUO_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .priv = (void *)& fdm_duo_priv_caps, .rig_init = elad_init, .rig_cleanup = elad_cleanup, .set_freq = elad_set_freq, .get_freq = elad_get_freq, .set_rit = elad_set_rit, /* FIXME should this switch to rit mode or just set the frequency? */ .get_rit = elad_get_rit, .set_xit = elad_set_xit, /* FIXME should this switch to xit mode or just set the frequency? */ .get_xit = elad_get_xit, .set_mode = elad_set_mode, .get_mode = elad_get_mode, .set_vfo = elad_set_vfo, .get_vfo = elad_get_vfo_if, .set_split_vfo = elad_set_split_vfo, .get_split_vfo = elad_get_split_vfo_if, .get_ptt = elad_get_ptt, .set_ptt = elad_set_ptt, .get_dcd = elad_get_dcd, .set_powerstat = elad_set_powerstat, .get_powerstat = elad_get_powerstat, .get_info = elad_fdm_duo_get_info, .reset = elad_reset, .set_ant = elad_set_ant, .get_ant = elad_get_ant, .scan = elad_scan, /* not working, invalid arguments using rigctl; elad_scan does only support on/off and not tone and CTCSS scan */ .has_set_level = FDM_DUO_LEVEL_ALL, .has_get_level = FDM_DUO_LEVEL_ALL, .set_level = elad_fdm_duo_set_level, .get_level = elad_fdm_duo_get_level, .has_get_func = FDM_DUO_FUNC_ALL, .has_set_func = FDM_DUO_FUNC_ALL, .set_func = elad_set_func, .get_func = elad_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * my notes: * format with: indent --line-length 200 fdm_duo.c * * for the FDM_DUO the function NR and BC have tree state: NR0,1,2 and BC0,1,2 * this cannot be send through the on/off logic of set_function! */ /* * Function definitions below */ hamlib-4.6.2/rigs/elad/elad.c0000644000175000017500000025762414752216205012646 00000000000000/* * Hamlib ELAD backend - main file * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2018 by Giovanni Franza, info@hb9eik.ch * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "cal.h" #include "elad.h" #ifndef max #define max(a,b) (((a) (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif struct elad_id { rig_model_t model; int id; }; struct elad_id_string { rig_model_t model; const char *id; }; #define UNKNOWN_ID -1 /* * Identification number as returned by "ID;" * Please, if the model number of your rig is listed as UNKNOWN_ID, * send the value to for inclusion. Thanks --SF * * TODO: sort this list with most frequent rigs first. */ static const struct elad_id elad_id_list[] = { { RIG_MODEL_ELAD_FDM_DUO, 1 }, { RIG_MODEL_NONE, UNKNOWN_ID }, /* end marker */ }; /* XXX numeric ids have been tested only with the TS-450 */ static const struct elad_id_string elad_id_string_list[] = { { RIG_MODEL_ELAD_FDM_DUO, "001" }, { RIG_MODEL_NONE, NULL }, /* end marker */ }; rmode_t elad_mode_table[ELAD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_RTTY, [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, /* TUNE mode */ [9] = RIG_MODE_RTTYR }; /* * 38 CTCSS sub-audible tones */ const tone_t elad38_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0, }; /* * 42 CTCSS sub-audible tones */ const tone_t elad42_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0, }; /* Token definitions for .cfgparams in rig_caps * * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams elad_cfg_params[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /** * elad_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * Parameters: * cmdstr: Command to be sent to the rig. cmdstr can also be NULL, * indicating that only a reply is needed (nothing will be sent). * data: Buffer for reply string. Can be NULL, indicating that no reply * is needed and will return with RIG_OK after command was sent. * datasize: Size of buffer. It is the caller's responsibily to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int elad_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize) { struct elad_priv_data *priv = STATE(rig)->priv; const struct elad_priv_caps *caps = elad_caps(rig); struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); int retval; char cmdtrm[2]; /* Default Command/Reply termination char */ char *cmd; size_t len; int retry_read = 0; char buffer[ELAD_MAX_BUF_LEN]; /* use our own buffer since verification may need a longer buffer than the user supplied one */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if ((!cmdstr && !datasize) || (datasize && !data)) { return -RIG_EINVAL; } rs = STATE(rig); rs->transaction_active = 1; /* Emulators don't need any post_write_delay */ if (priv->is_emulation) { rp->post_write_delay = 0; } cmdtrm[0] = caps->cmdtrm; cmdtrm[1] = '\0'; transaction_write: if (cmdstr) { rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); len = strlen(cmdstr); cmd = calloc(1, len + 2); if (cmd == NULL) { retval = -RIG_ENOMEM; goto transaction_quit; } memcpy(cmd, cmdstr, len); /* XXX the if is temporary, until all invocations are fixed */ if (cmdstr[len - 1] != ';' && cmdstr[len - 1] != '\r') { cmd[len] = caps->cmdtrm; len++; } /* flush anything in the read buffer before command is sent */ rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, len); free(cmd); if (retval != RIG_OK) { goto transaction_quit; } } if (!datasize) { rs->transaction_active = 0; /* no reply expected so we need to write a command that always gives a reply so we can read any error replies from the actual command being sent without blocking */ if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { goto transaction_quit; } } transaction_read: /* allow one extra byte for terminator we don't return */ len = min(datasize ? datasize + 1 : strlen(priv->verify_cmd) + 13, ELAD_MAX_BUF_LEN); retval = read_string(rp, (unsigned char *) buffer, len, cmdtrm, strlen(cmdtrm), 0, 1); if (retval < 0) { if (retry_read++ < rp->retry) { goto transaction_write; } goto transaction_quit; } /* Check that command termination is correct */ if (strchr(cmdtrm, buffer[strlen(buffer) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, buffer); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (strlen(buffer) == 2) { switch (buffer[0]) { case 'N': /* Command recognised by rig but invalid data entered. */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, cmdstr); } retval = -RIG_ENAVAIL; goto transaction_quit; case 'O': /* Too many characters sent without a carriage return */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; case 'E': /* Communication error */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EIO; goto transaction_quit; case '?': /* Command not understood by rig or rig busy */ if (cmdstr) { rig_debug(RIG_DEBUG_ERR, "%s: Unknown command or rig busy '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: Retrying shortly\n", __func__); hl_usleep(rig->caps->timeout * 1000); goto transaction_read; } retval = -RIG_ERJCTED; goto transaction_quit; } } /* * Check that we received the correct reply. The first two characters * should be the same as command. Because the Elecraft XG3 uses * single character commands we only check the first character in * that case. */ if (datasize) { if (cmdstr && (buffer[0] != cmdstr[0] || (cmdstr[1] && buffer[1] != cmdstr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ rig_debug(RIG_DEBUG_ERR, "%s: Wrong reply %c%c for command %c%c\n", __func__, buffer[0], buffer[1], cmdstr[0], cmdstr[1]); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (retval > 0) { /* move the result excluding the command terminator into the caller buffer */ len = min(datasize, retval) - 1; strncpy(data, buffer, len); data[len] = '\0'; } } else { if (priv->verify_cmd[0] != buffer[0] || (priv->verify_cmd[1] && priv->verify_cmd[1] != buffer[1])) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ rig_debug(RIG_DEBUG_ERR, "%s: WRONG reply %c%c for command verification %c%c (datasize=%d)\n", __func__, buffer[0], buffer[1] , priv->verify_cmd[0], priv->verify_cmd[1], (int)datasize); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } } retval = RIG_OK; transaction_quit: rs->transaction_active = 0; return retval; } /** * elad_safe_transaction * A wrapper for elad_transaction to check returned data against * expected length, * * Parameters: * cmd Same as elad_transaction() cmdstr * buf Same as kenwwod_transaction() data * buf_size Same as elad_transaction() datasize * expected Value of expected string length * * Returns: * RIG_OK - if no error occurred. * RIG_EPROTO if returned string and expected are not equal * Error from elad_transaction() if any * */ int elad_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected) { int err; int retry = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (expected == 0) { buf_size = 0; } do { size_t length; err = elad_transaction(rig, cmd, buf, buf_size); if (err != RIG_OK) /* return immediately on error as any retries handled at lower level */ { return err; } length = strlen(buf); if (length != expected) /* worth retrying as some rigs occasionally send short results */ { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer; len for cmd %s: " "expected = %d, got %d\n", __func__, cmd, (int)expected, (int)length); err = -RIG_EPROTO; hl_usleep(rig->caps->timeout * 1000); } } while (err != RIG_OK && ++retry < RIGPORT(rig)->retry); return err; } rmode_t elad2rmode(unsigned char mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (mode >= ELAD_MODE_TABLE_MAX) { return RIG_MODE_NONE; } return mode_table[mode]; } char rmode2elad(rmode_t mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (mode != RIG_MODE_NONE) { int i; for (i = 0; i < ELAD_MODE_TABLE_MAX; i++) { if (mode_table[i] == mode) { return i; } } } return -1; } int elad_init(RIG *rig) { struct elad_priv_data *priv; struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = calloc(1, sizeof(struct elad_priv_data)); if (STATE(rig)->priv == NULL) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0x00, sizeof(struct elad_priv_data)); strcpy(priv->verify_cmd, RIG_MODEL_XG3 == rig->caps->rig_model ? ";" : "ID;"); priv->split = RIG_SPLIT_OFF; priv->trn_state = -1; priv->curr_mode = 0; /* default mode_table */ if (caps->mode_table == NULL) { caps->mode_table = elad_mode_table; } /* default if_len */ if (caps->if_len == 0) { caps->if_len = 37; } rig_debug(RIG_DEBUG_TRACE, "%s: if_len = %d\n", __func__, caps->if_len); return RIG_OK; } int elad_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int elad_open(RIG *rig) { struct elad_priv_data *priv = STATE(rig)->priv; int err, i; char *idptr; char id[ELAD_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS590S == rig->caps->rig_model) { char *dot_pos; /* we need the firmware version for these rigs to deal with f/w defects */ static char fw_version[7]; err = elad_transaction(rig, "FV", fw_version, sizeof(fw_version)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version\n", __func__); return err; } /* store the data after the "FV" which should be a f/w version string of the form n.n e.g. 1.07 */ priv->fw_rev = &fw_version[2]; dot_pos = strchr(fw_version, '.'); if (dot_pos) { priv->fw_rev_uint = atoi(&fw_version[2]) * 100 + atoi(dot_pos + 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version\n", __func__); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: found f/w version %s\n", __func__, priv->fw_rev); } /* get id in buffer, will be null terminated */ err = elad_get_id(rig, id); if (RIG_MODEL_XG3 != rig->caps->rig_model && -RIG_ETIMEOUT == err) { /* Some Kenwood emulations have no ID command response :( * Try an FA command to see is anyone is listening */ char buffer[ELAD_MAX_BUF_LEN]; err = elad_transaction(rig, "FA", buffer, sizeof(buffer)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: no response from rig\n", __func__); return err; } /* here we know there is something that responds to FA but not to ID so use FA as the command verification command */ strcpy(priv->verify_cmd, "FA;"); strcpy(id, "ID019"); /* fake a TS-2000 */ } else { if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get identification\n", __func__); return err; } } /* id is something like 'IDXXX' or 'ID XXX' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unknown id type (%s)\n", __func__, id); return -RIG_EPROTO; } if (!strcmp("IDID900", id) /* DDUtil in TS-2000 mode */ || !strcmp("ID900", id) /* PowerSDR after ZZID; command */ || !strcmp("ID904", id) /* SmartSDR Flex-6700 */ || !strcmp("ID905", id) /* PowerSDR Flex-6500 */ || !strcmp("ID906", id) /* PowerSDR Flex-6700R */ || !strcmp("ID907", id) /* PowerSDR Flex-6300 */ || !strcmp("ID908", id) /* PowerSDR Flex-6400 */ || !strcmp("ID909", id) /* PowerSDR Flex-6600 */ ) { priv->is_emulation = 1; /* Emulations don't have SAT mode */ strcpy(id, "ID019"); /* fake it */ } /* check for a white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } /* compare id string */ for (i = 0; elad_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (strcmp(elad_id_string_list[i].id, idptr) != 0) { continue; } /* found matching id, verify driver */ rig_debug(RIG_DEBUG_TRACE, "%s: found match %s\n", __func__, elad_id_string_list[i].id); if (elad_id_string_list[i].model == rig->caps->rig_model) { /* get current AI state so it can be restored */ elad_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ elad_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ return RIG_OK; } /* driver mismatch */ rig_debug(RIG_DEBUG_ERR, "%s: wrong driver selected (%u instead of %u)\n", __func__, rig->caps->rig_model, elad_id_string_list[i].model); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_ERR, "%s: your rig (%s) is unknown\n", __func__, id); return -RIG_EPROTO; } int elad_close(RIG *rig) { const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!no_restore_ai && priv->trn_state >= 0) { /* restore AI state */ elad_set_trn(rig, priv->trn_state); /* ignore status in case it's not supported */ } return RIG_OK; } /* ID * Reads transceiver ID number * * caller must give a buffer of ELAD_MAX_BUF_LEN size * */ int elad_get_id(RIG *rig, char *buf) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_transaction(rig, "ID", buf, ELAD_MAX_BUF_LEN); } /* IF * Retrieves the transceiver status * */ static int elad_get_if(RIG *rig) { struct elad_priv_data *priv = STATE(rig)->priv; const struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_safe_transaction(rig, "IF", priv->info, ELAD_MAX_BUF_LEN, caps->if_len); } /* FN FR FT * Sets the RX/TX VFO or M.CH mode of the transceiver, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int elad_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[6]; int retval; char vfo_function; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Emulations do not need to set VFO since VFOB is a copy of VFOA * except for frequency. And we can change freq without changing VFOS * This prevents a 1.8 second delay in PowerSDR when switching VFOs * We'll do this once if curr_mode has not been set yet */ if (priv->is_emulation && priv->curr_mode > 0) { return RIG_OK; } switch (vfo) { case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } //if rig=ts2000 then check Satellite mode status if (rig->caps->rig_model == RIG_MODEL_TS2000 && !priv->is_emulation) { char retbuf[20]; rig_debug(RIG_DEBUG_VERBOSE, "%s: Checking Satellite mode status\n", __func__); SNPRINTF(cmdbuf, sizeof(cmdbuf), "SA"); retval = elad_transaction(rig, cmdbuf, retbuf, 20); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "Satellite mode status %s\n", retbuf); //Satellite mode ON if (retbuf[2] == '1') { //SAT mode doesn't allow FR command (cannot select VFO) //selecting VFO is useless in SAT MODE return RIG_OK; } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c", vfo_function); if (rig->caps->rig_model == RIG_MODEL_TS50 || rig->caps->rig_model == RIG_MODEL_TS940) { cmdbuf[1] = 'N'; } /* set RX VFO */ retval = elad_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } /* if FN command then there's no FT or FR */ /* If split mode on, the don't change TxVFO */ if ('N' == cmdbuf[1] || priv->split != RIG_SPLIT_OFF) { return RIG_OK; } /* set TX VFO */ cmdbuf[1] = 'T'; return elad_transaction(rig, cmdbuf, NULL, 0); } /* CB * Sets the operating VFO, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int elad_set_vfo_main_sub(RIG *rig, vfo_t vfo) { char cmdbuf[6]; char vfo_function; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_function = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_function = '1'; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "CB%c", vfo_function); return elad_transaction(rig, cmdbuf, NULL, 0); } /* CB * Gets the operating VFO * */ int elad_get_vfo_main_sub(RIG *rig, vfo_t *vfo) { char buf[4]; int rc; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_OK == (rc = elad_safe_transaction(rig, "CB", buf, sizeof(buf), 3))) { *vfo = buf[2] == '1' ? RIG_VFO_SUB : RIG_VFO_MAIN; } return rc; } /* FR FT TB * Sets the split RX/TX VFO or M.CH mode of the transceiver. * */ int elad_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { // this is a bogus suppress which complains priv is not used -- but it is 20231012 // cppcheck-suppress unreadVariable struct elad_priv_data *priv = STATE(rig)->priv; char cmdbuf[6]; int retval; unsigned char vfo_function; split_t tsplit; vfo_t tvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_split_vfo_if(rig, vfo, &tsplit, &tvfo); if (retval != RIG_OK) { return retval; } if (split == tsplit) { rig_debug(RIG_DEBUG_TRACE, "%s: No change detected...ignoring request\n", __func__); } rig_debug(RIG_DEBUG_TRACE, "%s: Change detected requested split %d!=%d\n", __func__, split, tsplit); if (split) { // Rx MAIN/Tx SUB is the only split method retval = elad_set_vfo_main_sub(rig, RIG_VFO_MAIN); if (retval != RIG_OK) { return retval; } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "SP%c", RIG_SPLIT_ON == split ? '1' : '0'); return elad_transaction(rig, cmdbuf, NULL, 0); /* Split off means Rx and Tx are the same */ if (split == RIG_SPLIT_OFF) { txvfo = RIG_VFO_MAIN; if (txvfo == RIG_VFO_CURR) { retval = rig_get_vfo(rig, &txvfo); if (retval != RIG_OK) { return retval; } } } switch (txvfo) { case RIG_VFO_VFO: case RIG_VFO_MAIN: case RIG_VFO_A: vfo_function = '0'; txvfo = RIG_VFO_MAIN; break; case RIG_VFO_SUB: case RIG_VFO_B: vfo_function = '1'; txvfo = RIG_VFO_SUB; break; case RIG_VFO_MEM: vfo_function = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(txvfo)); return -RIG_EINVAL; } /* set TX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT%c", vfo_function); retval = elad_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } retval = elad_set_split(rig, vfo, split, txvfo); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for elad_set_vfo */ priv->split = split; return RIG_OK; } /* SP * Sets the split mode of the transceivers that have the FN command. * */ int elad_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct elad_priv_data *priv = STATE(rig)->priv; char cmdbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // we want stand-alone split so we can control it SNPRINTF(cmdbuf, sizeof(cmdbuf), "SP%c", RIG_SPLIT_ON == split ? '2' : '0'); retval = elad_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for elad_set_vfo */ priv->split = split; return RIG_OK; } /* IF TB * Gets split VFO status from elad_get_if() * */ int elad_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { struct elad_priv_data *priv = STATE(rig)->priv; int retval; int transmitting; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!split || !txvfo) { return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char buf[4]; if (RIG_OK == (retval = elad_safe_transaction(rig, "SP", buf, sizeof(buf), 3))) { if ('1' == buf[2]) { *split = RIG_SPLIT_ON; *txvfo = RIG_VFO_SUB; } else { *split = RIG_SPLIT_OFF; *txvfo = RIG_VFO_MAIN; } } return retval; } retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } switch (priv->info[32]) { case '0': *split = RIG_SPLIT_OFF; break; case '1': *split = RIG_SPLIT_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %c\n", __func__, priv->info[32]); return -RIG_EPROTO; } /* Remember whether split is on, for elad_set_vfo */ priv->split = *split; /* find where is the txvfo.. */ /* Elecraft info[30] does not track split VFO when transmitting */ transmitting = '1' == priv->info[28] && RIG_MODEL_K2 != rig->caps->rig_model && RIG_MODEL_K3 != rig->caps->rig_model; switch (priv->info[30]) { case '0': *txvfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; break; case '1': *txvfo = (*split && !transmitting) ? RIG_VFO_A : RIG_VFO_B; break; case '2': *txvfo = RIG_VFO_MEM; /* SPLIT MEM operation doesn't involve VFO A or VFO B */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); return -RIG_EPROTO; } return RIG_OK; } /* * elad_get_vfo_if using byte 31 of the IF information field * * Specifically this needs to return the RX VFO, the IF command tells * us the TX VFO in split TX mode when transmitting so we need to swap * results sometimes. */ int elad_get_vfo_if(RIG *rig, vfo_t *vfo) { int retval; struct elad_priv_data *priv = STATE(rig)->priv; int split_and_transmitting; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } /* Elecraft info[30] does not track split VFO when transmitting */ split_and_transmitting = '1' == priv->info[28] /* transmitting */ && '1' == priv->info[32] /* split */ && RIG_MODEL_K2 != rig->caps->rig_model && RIG_MODEL_K3 != rig->caps->rig_model; switch (priv->info[30]) { case '0': *vfo = split_and_transmitting ? RIG_VFO_B : RIG_VFO_A; break; case '1': *vfo = split_and_transmitting ? RIG_VFO_A : RIG_VFO_B; break; case '2': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); return -RIG_EPROTO; } return RIG_OK; } /* * elad_set_freq */ int elad_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16]; unsigned char vfo_letter = '\0'; vfo_t tvfo; int err; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; if (RIG_VFO_CURR == tvfo) { /* fetch from rig */ err = rig_get_vfo(rig, &tvfo); if (RIG_OK != err) { return err; } } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%c%011"PRIll, vfo_letter, (int64_t)freq); err = elad_transaction(rig, freqbuf, NULL, 0); if (RIG_OK == err && RIG_MODEL_TS590S == rig->caps->rig_model && priv->fw_rev_uint <= 107 && ('A' == vfo_letter || 'B' == vfo_letter)) { /* TS590s f/w rev 1.07 or earlier has a defect that means frequency set on TX VFO in split mode may not be set correctly. The symptom of the defect is either TX on the wrong frequency (i.e. TX on a frequency different from that showing on the TX VFO) or no output. We use an IF command to find out if we have just set the "back" VFO when the rig is in split mode. If we have; we then read the other VFO and set it to what we read - a null transaction that fixes the defect. */ err = elad_get_if(rig); if (RIG_OK != err) { return err; } if ('1' == priv->info[32] && priv->info[30] != ('A' == vfo_letter ? '0' : '1')) { /* split mode and setting "back" VFO */ /* set other VFO to whatever it is at currently */ err = elad_safe_transaction(rig, 'A' == vfo_letter ? "FB" : "FA", freqbuf, 16, 13); if (RIG_OK != err) { return err; } err = elad_transaction(rig, freqbuf, NULL, 0); } } return err; } int elad_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq) { const struct elad_priv_data *priv = STATE(rig)->priv; char freqbuf[50]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!freq) { return -RIG_EINVAL; } retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } memcpy(freqbuf, priv->info, 15); freqbuf[14] = '\0'; sscanf(freqbuf + 2, "%"SCNfreq, freq); return RIG_OK; } /* * elad_get_freq */ int elad_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[50]; char cmdbuf[4]; int retval; unsigned char vfo_letter = '\0'; vfo_t tvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!freq) { return -RIG_EINVAL; } tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; if (RIG_VFO_CURR == tvfo) { /* fetch from rig */ retval = rig_get_vfo(rig, &tvfo); if (RIG_OK != retval) { return retval; } } /* memory frequency cannot be read with an Fx command, use IF */ if (tvfo == RIG_VFO_MEM) { return elad_get_freq_if(rig, vfo, freq); } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "F%c", vfo_letter); retval = elad_safe_transaction(rig, cmdbuf, freqbuf, 50, 13); if (retval != RIG_OK) { return retval; } sscanf(freqbuf + 2, "%"SCNfreq, freq); return RIG_OK; } int elad_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[6]; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } memcpy(buf, &priv->info[18], 5); buf[5] = '\0'; *rit = atoi(buf); return RIG_OK; } /* * rit can only move up/down by 10 Hz, so we use a loop... */ int elad_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[4]; int retval, i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rit == 0) { return elad_transaction(rig, "RC", NULL, 0); } SNPRINTF(buf, sizeof(buf), "R%c", (rit > 0) ? 'U' : 'D'); retval = elad_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 10)); i++) { retval = elad_transaction(rig, buf, NULL, 0); } return retval; } /* * rit and xit are the same */ int elad_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rit) { return -RIG_EINVAL; } return elad_get_rit(rig, vfo, rit); } int elad_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_set_rit(rig, vfo, rit); } int elad_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { return elad_transaction(rig, scan == RIG_SCAN_STOP ? "SC00" : "SC01", NULL, 0); } else { return elad_transaction(rig, scan == RIG_SCAN_STOP ? "SC0" : "SC1", NULL, 0); } } /* * 000 No select * 002 FM Wide * 003 FM Narrow * 005 AM * 007 SSB * 009 CW * 010 CW NARROW */ /* XXX revise */ static int elad_set_filter(RIG *rig, pbwidth_t width) { char *cmd; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (width <= Hz(250)) { cmd = "FL010009"; } else if (width <= Hz(500)) { cmd = "FL009009"; } else if (width <= kHz(2.7)) { cmd = "FL007007"; } else if (width <= kHz(6)) { cmd = "FL005005"; } else { cmd = "FL002002"; } return elad_transaction(rig, cmd, NULL, 0); } /* * elad_set_mode */ int elad_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const struct elad_priv_data *priv = STATE(rig)->priv; struct elad_priv_caps *caps = elad_caps(rig); char buf[6]; char kmode; int err; char data_mode = '0'; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { /* supports DATA sub modes */ switch (mode) { case RIG_MODE_PKTUSB: data_mode = '1'; mode = RIG_MODE_USB; break; case RIG_MODE_PKTLSB: data_mode = '1'; mode = RIG_MODE_LSB; break; case RIG_MODE_PKTFM: data_mode = '1'; mode = RIG_MODE_FM; break; default: break; } } if (priv->is_emulation || rig->caps->rig_model == RIG_MODEL_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ if (RIG_MODE_PKTLSB == mode) { mode = RIG_MODE_RTTY; } if (RIG_MODE_PKTUSB == mode) { mode = RIG_MODE_RTTYR; } } kmode = rmode2elad(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { /* The TS990s has targetable read mode but can only set the mode of the current VFO :( So we need to toggle the operating VFO to set the "back" VFO mode. This is done here rather than not setting caps.targetable_vfo to not include RIG_TARGETABLE_MODE since the toggle is not required for reading the mode. */ char c; vfo_t curr_vfo; err = elad_get_vfo_main_sub(rig, &curr_vfo); if (err != RIG_OK) { return err; } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } if (vfo != RIG_VFO_CURR && vfo != curr_vfo) { err = elad_set_vfo_main_sub(rig, vfo); if (err != RIG_OK) { return err; } } SNPRINTF(buf, sizeof(buf), "OM0%c", c); /* target vfo is ignored */ err = elad_transaction(rig, buf, NULL, 0); if (vfo != RIG_VFO_CURR && vfo != curr_vfo) { int err2 = elad_set_vfo_main_sub(rig, curr_vfo); if (RIG_OK == err && err2 != RIG_OK) { return err2; } } } else { SNPRINTF(buf, sizeof(buf), "MD%c", '0' + kmode); err = elad_transaction(rig, buf, NULL, 0); } if (err != RIG_OK) { return err; } if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { if (!(RIG_MODE_CW == mode || RIG_MODE_CWR == mode || RIG_MODE_AM == mode || RIG_MODE_RTTY == mode || RIG_MODE_RTTYR == mode)) { /* supports DATA sub modes - see above */ SNPRINTF(buf, sizeof(buf), "DA%c", data_mode); err = elad_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } } } if (RIG_PASSBAND_NOCHANGE == width) { return RIG_OK; } if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS690S || rig->caps->rig_model == RIG_MODEL_TS850 || rig->caps->rig_model == RIG_MODEL_TS950SDX) { if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } elad_set_filter(rig, width); /* non fatal */ } return RIG_OK; } static int elad_get_filter(RIG *rig, pbwidth_t *width) { int err, f, f1, f2; char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!width) { return -RIG_EINVAL; } err = elad_safe_transaction(rig, "FL", buf, sizeof(buf), 8); if (err != RIG_OK) { return err; } f2 = atoi(&buf[5]); buf[5] = '\0'; f1 = atoi(&buf[2]); if (f2 > f1) { f = f2; } else { f = f1; } switch (f) { case 2: *width = kHz(12); break; case 3: case 5: *width = kHz(6); break; case 7: *width = kHz(2.7); break; case 9: *width = Hz(500); break; case 10: *width = Hz(250); break; } return RIG_OK; } /* * elad_get_mode */ int elad_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct elad_priv_data *priv = STATE(rig)->priv; struct elad_priv_caps *caps = elad_caps(rig); char cmd[4]; char modebuf[10]; int offs; int retval; int kmode; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } /* for emulation do not read mode from VFOB as it is copy of VFOA */ /* we avoid the VFO swapping most of the time this way */ /* only need to get it if it has to be initialized */ if (priv->curr_mode > 0 && priv->is_emulation && vfo == RIG_VFO_B) { return priv->curr_mode; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "OM%c", c); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "MD"); offs = 2; } retval = elad_safe_transaction(rig, cmd, modebuf, 6, offs + 1); if (retval != RIG_OK) { return retval; } if (modebuf[offs] <= '9') { kmode = modebuf[offs] - '0'; } else { kmode = modebuf[offs] - 'A' + 10; } *mode = elad2rmode(kmode, caps->mode_table); if (priv->is_emulation || rig->caps->rig_model == RIG_MODEL_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ if (RIG_MODE_RTTY == *mode) { *mode = RIG_MODE_PKTLSB; } if (RIG_MODE_RTTYR == *mode) { *mode = RIG_MODE_PKTUSB; } } if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { /* supports DATA sub-modes */ retval = elad_safe_transaction(rig, "DA", modebuf, 6, 3); if (retval != RIG_OK) { return retval; } if ('1' == modebuf[2]) { switch (*mode) { case RIG_MODE_USB: *mode = RIG_MODE_PKTUSB; break; case RIG_MODE_LSB: *mode = RIG_MODE_PKTLSB; break; case RIG_MODE_FM: *mode = RIG_MODE_PKTFM; break; default: break; } } } /* XXX ? */ *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* This is used when the radio does not support MD; for mode reading */ int elad_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int err; struct elad_priv_caps *caps = elad_caps(rig); const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } err = elad_get_if(rig); if (err != RIG_OK) { return err; } *mode = elad2rmode(priv->info[29] - '0', caps->mode_table); *width = rig_passband_normal(rig, *mode); if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS690S || rig->caps->rig_model == RIG_MODEL_TS850 || rig->caps->rig_model == RIG_MODEL_TS950SDX) { elad_get_filter(rig, width); /* non fatal */ } return RIG_OK; } int elad_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int i, elad_val; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { elad_val = val.f * 255; } else { elad_val = val.i; } switch (level) { case RIG_LEVEL_RFPOWER: /* * Best estimate: 1.0 corresponds to 100W * Anything better must be done in rig-specific files. */ if (RIG_LEVEL_IS_FLOAT(level)) { elad_val = val.f * 100; } SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", elad_val); break; case RIG_LEVEL_AF: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", elad_val); break; case RIG_LEVEL_RF: /* XXX check level range */ SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", elad_val); break; case RIG_LEVEL_SQL: SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%03d", elad_val); break; case RIG_LEVEL_AGC: if (elad_val > 3) { elad_val = 3; /* 0.. 255 */ } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", 84 * elad_val); break; case RIG_LEVEL_ATT: /* set the attenuator if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA00"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && STATE(rig)->attenuator[i]; i++) { if (val.i == STATE(rig)->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_PREAMP: /* set the preamp if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && STATE(rig)->preamp[i]; i++) { if (val.i == STATE(rig)->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_SLOPE_HIGH: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SH%02d", (val.i)); break; case RIG_LEVEL_SLOPE_LOW: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SL%02d", (val.i)); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "PT%02d", (val.i / 50) - 8); break; case RIG_LEVEL_KEYSPD: if (val.i > 50 || val.i < 5) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "KS%03d", val.i); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s", rig_strlevel(level)); return -RIG_EINVAL; } return elad_transaction(rig, levelbuf, NULL, 0); } int get_elad_level(RIG *rig, const char *cmd, float *f) { char lvlbuf[10]; int retval; int lvl; int len = strlen(cmd); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!f) { return -RIG_EINVAL; } retval = elad_safe_transaction(rig, cmd, lvlbuf, 10, len + 3); if (retval != RIG_OK) { return retval; } /* 000..255 */ sscanf(lvlbuf + len, "%d", &lvl); *f = lvl / 255.0; return RIG_OK; }; /* * elad_get_level */ int elad_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[ELAD_MAX_BUF_LEN]; char *cmd; int retval; int lvl; int i, ret, agclevel, len; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RAWSTR: if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { cmd = "SM0"; len = 3; } else { cmd = "SM"; len = 2; } retval = elad_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { return retval; } /* XXX atoi ? */ sscanf(lvlbuf + len, "%d", &val->i); /* rawstr */ break; case RIG_LEVEL_STRENGTH: if (RIG_MODEL_TS590S == rig->caps->rig_model || RIG_MODEL_TS590SG == rig->caps->rig_model) { cmd = "SM0"; len = 3; } else { cmd = "SM"; len = 2; } retval = elad_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + len, "%d", &val->i); /* rawstr */ if (rig->caps->str_cal.size) { val->i = (int) rig_raw2val(val->i, &rig->caps->str_cal); } else { val->i = (val->i * 4) - 54; } break; case RIG_LEVEL_ATT: retval = elad_safe_transaction(rig, "RA", lvlbuf, 50, 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else { for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected att level %d\n", __func__, lvl); return -RIG_EPROTO; } } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->attenuator[i - 1]; } break; case RIG_LEVEL_PREAMP: retval = elad_safe_transaction(rig, "PA", lvlbuf, 50, 3); if (retval != RIG_OK) { return retval; } if (lvlbuf[2] == '0') { val->i = 0; } else if (isdigit((int)lvlbuf[2])) { lvl = lvlbuf[2] - '0'; for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp level %d\n", __func__, lvl); return -RIG_EPROTO; } } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->preamp[i - 1]; } else { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp char '%c'\n", __func__, lvlbuf[2]); return -RIG_EPROTO; } break; case RIG_LEVEL_RFPOWER: /* * an answer "PC100" means 100 Watt * which is val=1.0 on most rigs, but * get_elad_level maps 0...255 onto 0.0 ... 1.0 */ ret = get_elad_level(rig, "PC", &val->f); val->f = val->f * (255.0 / 100.0); return ret; case RIG_LEVEL_AF: return get_elad_level(rig, "AG", &val->f); case RIG_LEVEL_RF: return get_elad_level(rig, "RG", &val->f); case RIG_LEVEL_SQL: return get_elad_level(rig, "SQ", &val->f); case RIG_LEVEL_MICGAIN: return get_elad_level(rig, "MG", &val->f); case RIG_LEVEL_AGC: ret = get_elad_level(rig, "GT", &val->f); agclevel = 255 * val->f; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } return ret; case RIG_LEVEL_SLOPE_LOW: retval = elad_transaction(rig, "SL", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); break; case RIG_LEVEL_SLOPE_HIGH: retval = elad_transaction(rig, "SH", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); break; case RIG_LEVEL_CWPITCH: retval = elad_safe_transaction(rig, "PT", lvlbuf, 50, 4); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &val->i); val->i = (val->i * 1000) + 1000; /* 00 - 08 */ break; case RIG_LEVEL_KEYSPD: retval = elad_safe_transaction(rig, "KS", lvlbuf, 50, 5); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &val->i); break; case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_COMP: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int elad_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[6]; /* longest cmd is GTxxx */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (func) { case RIG_FUNC_NB: SNPRINTF(buf, sizeof(buf), "NB%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_ABM: SNPRINTF(buf, sizeof(buf), "AM%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_COMP: SNPRINTF(buf, sizeof(buf), "PR%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_TONE: SNPRINTF(buf, sizeof(buf), "TO%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_TSQL: SNPRINTF(buf, sizeof(buf), "CT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_VOX: SNPRINTF(buf, sizeof(buf), "VX%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_FAGC: SNPRINTF(buf, sizeof(buf), "GT00%c", (status == 0) ? '4' : '2'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_NR: SNPRINTF(buf, sizeof(buf), "NR%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_BC: SNPRINTF(buf, sizeof(buf), "BC%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_ANF: SNPRINTF(buf, sizeof(buf), "NT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_AIP: SNPRINTF(buf, sizeof(buf), "MX%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case RIG_FUNC_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (status == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %s", rig_strfunc(func)); return -RIG_EINVAL; } return -RIG_EINVAL; } /* * works for any 'format 1' command * answer is always 4 bytes: two byte command id, status and terminator */ int get_elad_func(RIG *rig, const char *cmd, int *status) { int retval; char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!cmd || !status) { return -RIG_EINVAL; } retval = elad_safe_transaction(rig, cmd, buf, 10, 3); if (retval != RIG_OK) { return retval; } *status = buf[2] == '0' ? 0 : 1; return RIG_OK; }; /* * elad_get_func */ int elad_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char fctbuf[20]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_FAGC: retval = elad_safe_transaction(rig, "GT", fctbuf, 20, 5); if (retval != RIG_OK) { return retval; } *status = fctbuf[4] != '4' ? 1 : 0; return RIG_OK; case RIG_FUNC_NB: return get_elad_func(rig, "NB", status); case RIG_FUNC_ABM: return get_elad_func(rig, "AM", status); case RIG_FUNC_COMP: return get_elad_func(rig, "PR", status); case RIG_FUNC_TONE: return get_elad_func(rig, "TO", status); case RIG_FUNC_TSQL: return get_elad_func(rig, "CT", status); case RIG_FUNC_VOX: return get_elad_func(rig, "VX", status); case RIG_FUNC_NR: return get_elad_func(rig, "NR", status); /* FIXME on TS2000 */ case RIG_FUNC_BC: return get_elad_func(rig, "BC", status); case RIG_FUNC_ANF: return get_elad_func(rig, "NT", status); case RIG_FUNC_LOCK: return get_elad_func(rig, "LK", status); case RIG_FUNC_AIP: return get_elad_func(rig, "MX", status); default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %s", rig_strfunc(func)); return -RIG_EINVAL; } return -RIG_EINVAL; } /* * elad_set_ctcss_tone * Assumes rig->caps->ctcss_list != NULL * * Warning! This is untested stuff! May work at least on TS-870S * Please owners report to me , thanks. --SF */ int elad_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); caps = rig->caps; /* TODO: replace 200 by something like RIGTONEMAX */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } /* TODO: replace menu no 57 by a define */ SNPRINTF(tonebuf, sizeof(tonebuf), "EX%03d%04d", 57, i + 1); return elad_transaction(rig, tonebuf, NULL, 0); } int elad_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* XXX 40 is a fixed constant */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "TN%c%02d", c, i + 1); } else { SNPRINTF(buf, sizeof(buf), "TN%02d", i + 1); } return elad_transaction(rig, buf, NULL, 0); } /* * elad_get_ctcss_tone * Assumes STATE(rig)->priv != NULL */ int elad_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct elad_priv_data *priv = STATE(rig)->priv; struct rig_caps *caps; char tonebuf[3]; int i, retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); caps = rig->caps; if (RIG_MODEL_TS990S == caps->rig_model) { char cmd[4]; char buf[6]; char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "TN%c", c); retval = elad_safe_transaction(rig, cmd, buf, sizeof(buf), 5); memcpy(tonebuf, &buf[3], 2); } else { retval = elad_get_if(rig); memcpy(tonebuf, &priv->info[34], 2); } if (retval != RIG_OK) { return retval; } tonebuf[2] = '\0'; tone_idx = atoi(tonebuf); if (tone_idx == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS tone is zero (%s)\n", __func__, tonebuf); return -RIG_EPROTO; } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } } *tone = caps->ctcss_list[tone_idx - 1]; return RIG_OK; } int elad_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "CN%c%02d", c, i + 1); } else { SNPRINTF(buf, sizeof(buf), "CN%02d", i + 1); } return elad_transaction(rig, buf, NULL, 0); } int elad_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char cmd[4]; char tonebuf[6]; int offs; int i, retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); caps = rig->caps; if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "CN%c", c); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "CT"); offs = 2; } retval = elad_safe_transaction(rig, cmd, tonebuf, 6, offs + 2); if (retval != RIG_OK) { return retval; } tone_idx = atoi(tonebuf + offs); if (tone_idx == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS is zero (%s)\n", __func__, tonebuf); return -RIG_EPROTO; } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } } *tone = caps->ctcss_list[tone_idx - 1]; return RIG_OK; } /* * set the aerial/antenna to use */ int elad_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char cmd[8]; char a; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ant) { case RIG_ANT_1: a = '1'; break; case RIG_ANT_2: a = '2'; break; case RIG_ANT_3: a = '3'; break; case RIG_ANT_4: a = '4'; break; default: return -RIG_EINVAL; } if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "AN0%c%c99", c, a); } else { SNPRINTF(cmd, sizeof(cmd), "AN%c", a); } return elad_transaction(rig, cmd, NULL, 0); } int elad_set_ant_no_ack(RIG *rig, vfo_t vfo, ant_t ant) { const char *cmd; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ant) { case RIG_ANT_1: cmd = "AN1"; break; case RIG_ANT_2: cmd = "AN2"; break; case RIG_ANT_3: cmd = "AN3"; break; case RIG_ANT_4: cmd = "AN4"; break; default: return -RIG_EINVAL; } return elad_transaction(rig, cmd, NULL, 0); } /* * get the aerial/antenna in use */ int elad_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char ackbuf[8]; int offs; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { retval = elad_safe_transaction(rig, "AN0", ackbuf, sizeof(ackbuf), 7); offs = 4; } else { retval = elad_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 3); offs = 2; } if (retval != RIG_OK) { return retval; } if (ackbuf[offs] < '1' || ackbuf[offs] > '9') { return -RIG_EPROTO; } *ant_curr = RIG_ANT_N(ackbuf[offs] - '1'); /* XXX check that the returned antenna is valid for the current rig */ return RIG_OK; } /* * elad_get_ptt */ int elad_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct elad_priv_data *priv = STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_get_if(rig); if (retval != RIG_OK) { return retval; } *ptt = priv->info[28] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; return RIG_OK; } int elad_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; char busybuf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TX"; break; case RIG_PTT_ON_MIC: ptt_cmd = "TX0"; break; case RIG_PTT_ON_DATA: ptt_cmd = "TX1"; break; case RIG_PTT_OFF: ptt_cmd = "RX"; break; default: return -RIG_EINVAL; } return elad_transaction(rig, ptt_cmd, busybuf, 4); } int elad_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt) { char busybuf[10]; int err; ptt_t current_ptt; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elad_get_ptt(rig, vfo, ¤t_ptt); if (err != RIG_OK) { return err; } if (current_ptt == ptt) { return RIG_OK; } return elad_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", busybuf, 4); } /* * elad_get_dcd */ int elad_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char busybuf[10]; int retval; int offs = 2; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_safe_transaction(rig, "BY", busybuf, 10, 3); if (retval != RIG_OK) { return retval; } if (RIG_MODEL_TS990S == rig->caps->rig_model && RIG_VFO_SUB == vfo) { offs = 3; } *dcd = (busybuf[offs] == '1') ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } /* * elad_set_trn */ int elad_set_trn(RIG *rig, int trn) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { return elad_transaction(rig, (trn == RIG_TRN_RIG) ? "AI2" : "AI0", NULL, 0); } else { return elad_transaction(rig, (trn == RIG_TRN_RIG) ? "AI1" : "AI0", NULL, 0); } } /* * elad_get_trn */ int elad_get_trn(RIG *rig, int *trn) { char trnbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!trn) { return -RIG_EINVAL; } /* these rigs only have AI[0|1] set commands and no AI query */ if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS690S || rig->caps->rig_model == RIG_MODEL_TS790 || rig->caps->rig_model == RIG_MODEL_TS850 || rig->caps->rig_model == RIG_MODEL_TS950SDX) { return -RIG_ENAVAIL; } retval = elad_safe_transaction(rig, "AI", trnbuf, 6, 3); if (retval != RIG_OK) { return retval; } *trn = trnbuf[2] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; return RIG_OK; } /* * elad_set_powerstat */ int elad_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return elad_transaction(rig, (status == RIG_POWER_ON) ? "PS1" : "PS0", NULL, 0); } /* * elad_get_powerstat */ int elad_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } retval = elad_safe_transaction(rig, "PS", pwrbuf, 6, 3); if (retval != RIG_OK) { return retval; } *status = pwrbuf[2] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; return RIG_OK; } /* * elad_reset */ int elad_reset(RIG *rig, reset_t reset) { char rstbuf[6]; char rst; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { switch (reset) { case RIG_RESET_SOFT: rst = '4'; break; case RIG_RESET_VFO: rst = '3'; break; case RIG_RESET_MCALL: rst = '2'; break; case RIG_RESET_MASTER: rst = '5'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); return -RIG_EINVAL; } } else { switch (reset) { case RIG_RESET_VFO: rst = '1'; break; case RIG_RESET_MASTER: rst = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); return -RIG_EINVAL; } } SNPRINTF(rstbuf, sizeof(rstbuf), "SR%c", rst); /* this command has no answer */ return elad_transaction(rig, rstbuf, NULL, 0); } /* * elad_send_morse */ int elad_send_morse(RIG *rig, vfo_t vfo, const char *msg) { char morsebuf[40], m2[30]; int msg_len, retval, i; const char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); p = msg; msg_len = strlen(msg); while (msg_len > 0) { int buff_len; /* * Check with "KY" if char buffer is available. * if not, sleep. */ for (;;) { retval = elad_transaction(rig, "KY;", m2, 4); if (retval != RIG_OK) { return retval; } /* * If answer is "KY0;", there is space in buffer and we can proceed. * If answer is "KY1;", we have to wait a while * If answer is something else, return with error to prevent infinite loops */ if (!strncmp(m2, "KY0", 3)) { break; } if (!strncmp(m2, "KY1", 3)) { hl_usleep(500000); } else { return -RIG_EINVAL; } } buff_len = msg_len > 24 ? 24 : msg_len; strncpy(m2, p, 24); m2[24] = '\0'; /* * Make the total message segments 28 characters * in length because some Kenwoods demand it. * 0x20 fills in the message end. * Some rigs don't need the fill */ switch (rig->caps->rig_model) { case RIG_MODEL_K3: // probably a lot more rigs need to go here SNPRINTF(morsebuf, sizeof(morsebuf), "KY %s", m2); break; default: /* the command must consist of 28 bytes 0x20 padded */ SNPRINTF(morsebuf, sizeof(morsebuf), "KY %-24s", m2); for (i = strlen(morsebuf) - 1; i > 0 && morsebuf[i] == ' '; --i) { morsebuf[i] = 0x20; } } retval = elad_transaction(rig, morsebuf, NULL, 0); if (retval != RIG_OK) { return retval; } msg_len -= buff_len; p += buff_len; } return RIG_OK; } /* * elad_vfo_op */ int elad_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (op) { case RIG_OP_UP: return elad_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return elad_transaction(rig, "DN", NULL, 0); case RIG_OP_BAND_UP: return elad_transaction(rig, "BU", NULL, 0); case RIG_OP_BAND_DOWN: return elad_transaction(rig, "BD", NULL, 0); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } } /* * elad_set_mem */ int elad_set_mem(RIG *rig, vfo_t vfo, int ch) { char buf[7]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = elad_get_vfo_main_sub(rig, &vfo))) { return err; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MN%c%03d", c, ch); } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(buf, sizeof(buf), "MC %02d", ch); } return elad_transaction(rig, buf, NULL, 0); } /* * elad_get_mem */ int elad_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmd[4]; char membuf[10]; int offs; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_MODEL_TS990S == rig->caps->rig_model) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = elad_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "MN%c", c); offs = 3; } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(cmd, sizeof(cmd), "MC"); offs = 2; } retval = elad_safe_transaction(rig, cmd, membuf, sizeof(membuf), 3 + offs); if (retval != RIG_OK) { return retval; } *ch = atoi(membuf + offs); return RIG_OK; } int elad_get_mem_if(RIG *rig, vfo_t vfo, int *ch) { int err; char buf[4]; const struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elad_get_if(rig); if (err != RIG_OK) { return err; } memcpy(buf, &priv->info[26], 2); buf[2] = '\0'; *ch = atoi(buf); return RIG_OK; } int elad_get_channel(RIG *rig, channel_t *chan) { int err; char buf[26]; char cmd[8]; char bank = ' '; struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* put channel num in the command string */ if (rig->caps->rig_model == RIG_MODEL_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(cmd, sizeof(cmd), "MR0%c%02d", bank, chan->channel_num); err = elad_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { return err; } memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_VFO; /* MR0 1700005890000510 ; * MRsbccfffffffffffMLTtt ; */ /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ if (buf[19] == '0' || buf[19] == ' ') { chan->ctcss_tone = 0; } else { buf[22] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[atoi(&buf[20])]; } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } chan->mode = elad2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[4]); if (buf[3] >= '0' && buf[3] <= '9') { chan->bank_num = buf[3] - '0'; } /* split freq */ cmd[2] = '1'; err = elad_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { return err; } chan->tx_mode = elad2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } return RIG_OK; } int elad_set_channel(RIG *rig, const channel_t *chan) { char buf[128]; char mode, tx_mode = 0; int err; int tone = 0; char bank = ' '; struct elad_priv_caps *caps = elad_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan) { return -RIG_EINVAL; } mode = rmode2elad(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2elad(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ if (chan->ctcss_tone) { for (tone = 0; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = 0; } } if (rig->caps->rig_model == RIG_MODEL_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(buf, sizeof(buf), "MW0%c%02d%011"PRIll"%c%c%c%02d ", /* note the space at the end */ bank, chan->channel_num, (int64_t)chan->freq, '0' + mode, (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); err = elad_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } SNPRINTF(buf, sizeof(buf), "MW1%c%02d%011"PRIll"%c%c%c%02d ", bank, chan->channel_num, (int64_t)(chan->split == RIG_SPLIT_ON ? chan->tx_freq : 0), (chan->split == RIG_SPLIT_ON) ? ('0' + tx_mode) : '0', (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); return elad_transaction(rig, buf, NULL, 0); } int elad_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { char buf[4]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_VOICE: return elad_transaction(rig, "VR", NULL, 0); case TOK_FINE: SNPRINTF(buf, sizeof(buf), "FS%c", (val.i == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case TOK_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (val.i == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); case TOK_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (val.i == 0) ? '0' : '1'); return elad_transaction(rig, buf, NULL, 0); } return -RIG_EINVAL; } int elad_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { int err; struct elad_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_FINE: return get_elad_func(rig, "FS", &val->i); case TOK_XIT: err = elad_get_if(rig); if (err != RIG_OK) { return err; } val->i = (priv->info[24] == '1') ? 1 : 0; return RIG_OK; case TOK_RIT: err = elad_get_if(rig); if (err != RIG_OK) { return err; } val->i = (priv->info[23] == '1') ? 1 : 0; return RIG_OK; } return -RIG_ENIMPL; } /* * elad_get_info * supposed to work only for TS2000... */ const char *elad_get_info(RIG *rig) { char firmbuf[10]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = elad_safe_transaction(rig, "TY", firmbuf, 10, 5); if (retval != RIG_OK) { return NULL; } switch (firmbuf[4]) { case '0': return "Firmware: Overseas type"; case '1': return "Firmware: Japanese 100W type"; case '2': return "Firmware: Japanese 20W type"; default: return "Firmware: unknown"; } } #define IDBUFSZ 16 /* * proberigs_elad * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_elad(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(elad) { char idbuf[IDBUFSZ]; int id_len = -1, i, k_id; int retval = -1; int rates[] = { 115200, 57600, 38400, 19200, 9600, 4800, 1200, 0 }; /* possible baud rates */ int rates_idx; idbuf[0] = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 2; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "ID;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK || id_len < 0) { continue; } } if (retval != RIG_OK || id_len < 0 || !strcmp(idbuf, "ID;")) { return RIG_MODEL_NONE; } /* * reply should be something like 'IDxxx;' */ if (id_len != 5 && id_len != 6) { idbuf[7] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "probe_elad: protocol error, " " expected %d, received %d: %s\n", 6, id_len, idbuf); return RIG_MODEL_NONE; } /* first, try ID string */ for (i = 0; elad_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (!strncmp(elad_id_string_list[i].id, idbuf + 2, 16)) { rig_debug(RIG_DEBUG_VERBOSE, "probe_elad: " "found %s\n", idbuf + 2); if (cfunc) { (*cfunc)(port, elad_id_string_list[i].model, data); } return elad_id_string_list[i].model; } } /* then, try ID numbers */ k_id = atoi(idbuf + 2); /* * Elecraft K2 returns same ID as TS570 */ if (k_id == 17) { retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "K2;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK) { return RIG_MODEL_NONE; } /* * reply should be something like 'K2n;' */ if (id_len == 4 || !strcmp(idbuf, "K2")) { rig_debug(RIG_DEBUG_VERBOSE, "%s: found K2\n", __func__); if (cfunc) { (*cfunc)(port, RIG_MODEL_K2, data); } return RIG_MODEL_K2; } } for (i = 0; elad_id_list[i].model != RIG_MODEL_NONE; i++) { if (elad_id_list[i].id == k_id) { rig_debug(RIG_DEBUG_VERBOSE, "probe_elad: " "found %03d\n", k_id); if (cfunc) { (*cfunc)(port, elad_id_list[i].model, data); } return elad_id_list[i].model; } } /* * not found in known table.... * update elad_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_elad: found unknown device " "with ID %03d, please report to Hamlib " "developers.\n", k_id); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay=%d\n", __func__, port->post_write_delay); return RIG_MODEL_NONE; } /* * initrigs_elad is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(elad) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // rig_debug(RIG_DEBUG_VERBOSE, "elad: _init called\n"); rig_register(&fdm_duo_caps); return RIG_OK; } hamlib-4.6.2/rigs/tentec/0000755000175000017500000000000014752216244012215 500000000000000hamlib-4.6.2/rigs/tentec/tentec.c0000644000175000017500000003245114752216205013565 00000000000000/* * Hamlib Tentec backend - main file * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "tentec.h" static void tentec_tuning_factor_calc(RIG *rig); #define EOM "\015" /* CR */ #define TT_AM '0' #define TT_USB '1' #define TT_LSB '2' #define TT_CW '3' #define TT_FM '4' static int tentec_filters[] = { 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 8000 }; /* * tentec_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ int tentec_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, *data_len, NULL, 0, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * tentec_init: * Basically, it just sets up *priv */ int tentec_init(RIG *rig) { struct tentec_priv_data *priv; STATE(rig)->priv = (struct tentec_priv_data *)calloc(1, sizeof( struct tentec_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tentec_priv_data)); /* * set arbitrary initial status */ priv->freq = MHz(10); priv->mode = RIG_MODE_AM; priv->width = kHz(6); priv->pbt = 0; priv->cwbfo = 1000; priv->agc = RIG_AGC_MEDIUM; /* medium */ priv->lnvol = priv->spkvol = 0.0; /* mute */ /* tentec_tuning_factor_calc needs STATE(rig)->priv */ tentec_tuning_factor_calc(rig); return RIG_OK; } /* * Tentec generic tentec_cleanup routine * the serial port is closed by the frontend */ int tentec_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Tentec transceiver only open routine * Restart and set program to execute. */ int tentec_trx_open(RIG *rig) { int retval; /* * be kind: use XX first, and do 'Dsp Program Execute' only * in " DSP START" state. */ retval = tentec_transaction(rig, "P1" EOM, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * Tuning Factor Calculations * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in supported modes. */ static void tentec_tuning_factor_calc(RIG *rig) { struct tentec_priv_data *priv; freq_t tfreq; int adjtfreq, mcor, fcor, cwbfo; priv = (struct tentec_priv_data *)STATE(rig)->priv; cwbfo = 0; /* computed fcor only used if mode is not CW */ fcor = (int)floor((double)priv->width / 2.0) + 200; switch (priv->mode) { case RIG_MODE_AM: case RIG_MODE_FM: mcor = 0; break; case RIG_MODE_CW: mcor = -1; cwbfo = priv->cwbfo; fcor = 0; break; case RIG_MODE_LSB: mcor = -1; break; case RIG_MODE_USB: mcor = 1; break; default: rig_debug(RIG_DEBUG_BUG, "%s: invalid mode %s\n", __func__, rig_strrmode(priv->mode)); mcor = 1; break; } tfreq = priv->freq / (freq_t)Hz(1); adjtfreq = (int)tfreq - 1250 + (int)(mcor * (fcor + priv->pbt)); priv->ctf = (adjtfreq / 2500) + 18000; priv->ftf = (int)floor((double)(adjtfreq % 2500) * 5.46); priv->btf = (int)floor((double)(fcor + priv->pbt + cwbfo + 8000) * 2.73); } /* * tentec_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tentec_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tentec_priv_data *priv; int retval; char freqbuf[16]; freq_t old_freq; priv = (struct tentec_priv_data *)STATE(rig)->priv; old_freq = priv->freq; priv->freq = freq; tentec_tuning_factor_calc(rig); SNPRINTF(freqbuf, sizeof(freqbuf), "N%c%c%c%c%c%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { priv->freq = old_freq; return retval; } return RIG_OK; } /* * tentec_get_freq * Assumes rig!=NULL, freq!=NULL */ int tentec_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct tentec_priv_data *priv = (struct tentec_priv_data *) STATE(rig)->priv; *freq = priv->freq; return RIG_OK; } /* * tentec_set_mode * Assumes rig!=NULL */ int tentec_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tentec_priv_data *priv = (struct tentec_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char ttmode; rmode_t saved_mode; pbwidth_t saved_width; int ttfilter = -1, retval; char mdbuf[32]; switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* backup current values * in case we fail to write to port */ saved_mode = priv->mode; saved_width = priv->width; if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } for (ttfilter = 0; tentec_filters[ttfilter] != 0; ttfilter++) { if (tentec_filters[ttfilter] == width) { break; } } if (tentec_filters[ttfilter] != width) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } priv->width = width; } priv->mode = mode; tentec_tuning_factor_calc(rig); if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "W%c" EOM "N%c%c%c%c%c%c" EOM "M%c" EOM, ttfilter, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->mode = saved_mode; priv->width = saved_width; return retval; } } else { SNPRINTF(mdbuf, sizeof(mdbuf), "N%c%c%c%c%c%c" EOM "M%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->mode = saved_mode; return retval; } } return RIG_OK; } /* * tentec_get_mode * Assumes rig!=NULL, mode!=NULL */ int tentec_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct tentec_priv_data *priv = (struct tentec_priv_data *) STATE(rig)->priv; *mode = priv->mode; *width = priv->width; return RIG_OK; } /* * tentec_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int tentec_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct tentec_priv_data *priv = (struct tentec_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retval = RIG_OK; char cmdbuf[32]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_AGC: /* default to MEDIUM */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%c" EOM, val.i == RIG_AGC_SLOW ? '1' : ( val.i == RIG_AGC_FAST ? '3' : '2')); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->agc = val.i; } return retval; case RIG_LEVEL_AF: /* FIXME: support also separate Lineout setting * -> need to create RIG_LEVEL_LINEOUT ? */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "C\x7f%c" EOM, (int)((1.0 - val.f) * 63.0)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->lnvol = priv->spkvol = val.f; } return retval; case RIG_LEVEL_IF: priv->pbt = val.i; retval = tentec_set_freq(rig, vfo, priv->freq); return retval; case RIG_LEVEL_CWPITCH: priv->cwbfo = val.i; if (priv->mode == RIG_MODE_CW) { retval = tentec_set_freq(rig, vfo, priv->freq); } return retval; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tentec_get_level * Assumes rig!=NULL, val!=NULL */ int tentec_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct tentec_priv_data *priv = (struct tentec_priv_data *) STATE(rig)->priv; int retval, lvl_len; unsigned char lvlbuf[32]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_RAWSTR: /* read A/D converted value */ lvl_len = 4; retval = tentec_transaction(rig, "X" EOM, 2, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "tentec_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[3] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "tentec_get_level: cmd=%c,hi=%d,lo=%d\n", lvlbuf[0], lvlbuf[1], lvlbuf[2]); val->i = (lvlbuf[1] << 8) + lvlbuf[2]; break; case RIG_LEVEL_AGC: val->i = priv->agc; break; case RIG_LEVEL_AF: val->f = priv->spkvol; break; case RIG_LEVEL_IF: val->i = priv->pbt; break; case RIG_LEVEL_CWPITCH: val->i = priv->cwbfo; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tentec_get_info * Assumes rig!=NULL */ const char *tentec_get_info(RIG *rig) { static char buf[100]; /* FIXME: reentrancy */ int firmware_len, retval; /* * protocol version */ firmware_len = 10; retval = tentec_transaction(rig, "?" EOM, 2, buf, &firmware_len); if ((retval != RIG_OK) || (firmware_len > 10)) { rig_debug(RIG_DEBUG_ERR, "tentec_get_info: ack NG, len=%d\n", firmware_len); return NULL; } return buf; } /* * initrigs_tentec is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(tentec) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&tt550_caps); rig_register(&tt516_caps); rig_register(&tt565_caps); rig_register(&tt538_caps); rig_register(&tt585_caps); rig_register(&tt588_caps); rig_register(&tt599_caps); rig_register(&rx320_caps); rig_register(&rx331_caps); rig_register(&rx340_caps); rig_register(&rx350_caps); return RIG_OK; } hamlib-4.6.2/rigs/tentec/argonaut.c0000644000175000017500000001273514752216205014126 00000000000000/* * Hamlib TenTenc backend - TT-516 PC-Radio description * Copyright (c) 2003-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "tentec2.h" #include "bandplan.h" #include "idx_builtin.h" #define TT516_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB) #define TT516_RXMODES (TT516_MODES|RIG_MODE_AM) #define TT516_FUNCS (RIG_FUNC_NONE) #define TT516_LEVELS (RIG_LEVEL_RAWSTR|/* RIG_LEVEL_NB| */ \ RIG_LEVEL_SQL|/*RIG_LEVEL_PBT|*/ \ RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT) #define TT516_ANTS RIG_ANT_1 #define TT516_VFO (RIG_VFO_A|RIG_VFO_B) // Taken from RX320_STR_CAL -- unknown if accurate for TT516 #define TT516_STR_CAL { 17, { \ { 0, -60 }, \ { 10, -50 }, \ { 20, -40 }, \ { 30, -30 }, \ { 40, -20 }, \ { 50, -15 }, \ { 100, -10 }, \ { 200, -5 }, \ { 225, -3 }, \ { 256, 0 }, \ { 512, 1 }, \ { 768, 3}, \ { 1024, 4 }, \ { 1280, 5 }, \ { 2560, 10 }, \ { 5120, 20 }, \ { 10000, 30 }, \ } } /* * tt516 receiver capabilities. * * protocol is documented at * http://www.rfsquared.com/ * */ struct rig_caps tt516_caps = { RIG_MODEL(RIG_MODEL_TT516), .model_name = "TT-516 Argonaut V", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 3, .has_get_func = TT516_FUNCS, .has_set_func = TT516_FUNCS, .has_get_level = TT516_LEVELS, .has_set_level = RIG_LEVEL_SET(TT516_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(500), MHz(30), TT516_RXMODES, -1, -1, TT516_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT516_MODES, W(1), W(20), TT516_VFO, TT516_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(1), W(5), TT516_VFO, TT516_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TT516_RXMODES, -1, -1, TT516_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT516_MODES, W(1), W(20), TT516_VFO, TT516_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(1), W(5), TT516_VFO, TT516_ANTS), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 10}, /* {RIG_MODE_SSB|RIG_MODE_CW,kHz(1)}, */ {RIG_MODE_AM, 100}, /* {RIG_MODE_AM,kHz(5)}, */ {RIG_MODE_FM, kHz(2.5)}, /* {RIG_MODE_FM,kHz(5)}, */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* FIXME: add increments -> 34 filters? */ {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_SSB, 200}, {RIG_MODE_CW | RIG_MODE_SSB, 0}, /* Filters are 200 Hz to 1000 Hz in 50 Hz steps, 1000 to 2800 Hz in 100 Hz steps */ {RIG_MODE_AM, kHz(4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = TT516_STR_CAL, .priv = (void *)NULL, .set_freq = tentec2_set_freq, .get_freq = tentec2_get_freq, .set_vfo = tentec2_set_vfo, .get_vfo = tentec2_get_vfo, .set_mode = tentec2_set_mode, .get_mode = tentec2_get_mode, .set_split_vfo = tentec2_set_split_vfo, .get_split_vfo = tentec2_get_split_vfo, .set_ptt = tentec2_set_ptt, .get_ptt = tentec2_get_ptt, .reset = tentec2_reset, .get_info = tentec2_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/tentec/Makefile.am0000644000175000017500000000045714752216205014174 00000000000000TENTECSRC = rx320.c rx340.c rx350.c rx331.c rx331.h tt550.c tt550.h \ pegasus.c argonaut.c orion.c orion.h jupiter.c omnivii.c paragon.c \ tentec.c tentec.h tentec2.c tentec2.h noinst_LTLIBRARIES = libhamlib-tentec.la libhamlib_tentec_la_SOURCES = $(TENTECSRC) EXTRA_DIST = README.tentec Android.mk hamlib-4.6.2/rigs/tentec/Makefile.in0000644000175000017500000005667114752216216014220 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/tentec ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_tentec_la_LIBADD = am__objects_1 = rx320.lo rx340.lo rx350.lo rx331.lo tt550.lo \ pegasus.lo argonaut.lo orion.lo jupiter.lo omnivii.lo \ paragon.lo tentec.lo tentec2.lo am_libhamlib_tentec_la_OBJECTS = $(am__objects_1) libhamlib_tentec_la_OBJECTS = $(am_libhamlib_tentec_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/argonaut.Plo ./$(DEPDIR)/jupiter.Plo \ ./$(DEPDIR)/omnivii.Plo ./$(DEPDIR)/orion.Plo \ ./$(DEPDIR)/paragon.Plo ./$(DEPDIR)/pegasus.Plo \ ./$(DEPDIR)/rx320.Plo ./$(DEPDIR)/rx331.Plo \ ./$(DEPDIR)/rx340.Plo ./$(DEPDIR)/rx350.Plo \ ./$(DEPDIR)/tentec.Plo ./$(DEPDIR)/tentec2.Plo \ ./$(DEPDIR)/tt550.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_tentec_la_SOURCES) DIST_SOURCES = $(libhamlib_tentec_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TENTECSRC = rx320.c rx340.c rx350.c rx331.c rx331.h tt550.c tt550.h \ pegasus.c argonaut.c orion.c orion.h jupiter.c omnivii.c paragon.c \ tentec.c tentec.h tentec2.c tentec2.h noinst_LTLIBRARIES = libhamlib-tentec.la libhamlib_tentec_la_SOURCES = $(TENTECSRC) EXTRA_DIST = README.tentec Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/tentec/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/tentec/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-tentec.la: $(libhamlib_tentec_la_OBJECTS) $(libhamlib_tentec_la_DEPENDENCIES) $(EXTRA_libhamlib_tentec_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_tentec_la_OBJECTS) $(libhamlib_tentec_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argonaut.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jupiter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omnivii.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/orion.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paragon.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pegasus.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx320.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx331.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx340.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rx350.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tentec.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tentec2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tt550.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/argonaut.Plo -rm -f ./$(DEPDIR)/jupiter.Plo -rm -f ./$(DEPDIR)/omnivii.Plo -rm -f ./$(DEPDIR)/orion.Plo -rm -f ./$(DEPDIR)/paragon.Plo -rm -f ./$(DEPDIR)/pegasus.Plo -rm -f ./$(DEPDIR)/rx320.Plo -rm -f ./$(DEPDIR)/rx331.Plo -rm -f ./$(DEPDIR)/rx340.Plo -rm -f ./$(DEPDIR)/rx350.Plo -rm -f ./$(DEPDIR)/tentec.Plo -rm -f ./$(DEPDIR)/tentec2.Plo -rm -f ./$(DEPDIR)/tt550.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/argonaut.Plo -rm -f ./$(DEPDIR)/jupiter.Plo -rm -f ./$(DEPDIR)/omnivii.Plo -rm -f ./$(DEPDIR)/orion.Plo -rm -f ./$(DEPDIR)/paragon.Plo -rm -f ./$(DEPDIR)/pegasus.Plo -rm -f ./$(DEPDIR)/rx320.Plo -rm -f ./$(DEPDIR)/rx331.Plo -rm -f ./$(DEPDIR)/rx340.Plo -rm -f ./$(DEPDIR)/rx350.Plo -rm -f ./$(DEPDIR)/tentec.Plo -rm -f ./$(DEPDIR)/tentec2.Plo -rm -f ./$(DEPDIR)/tt550.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/tentec/tt550.c0000644000175000017500000012151514752216205013164 00000000000000/* * Hamlib Tentec Pegasus TT550 backend - main file * Heavily modified for 550 support from the original tentec.c * (c) Oct 2002, Jan,Feb 2004- Ken Koster N7IPB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* Standard C library */ #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include "serial.h" #include "misc.h" #include "tt550.h" /* * Filter table for 550 receiver support */ static int tt550_filters[] = { 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 8000 }; /* * Filter table for 550 transmit support - The 550 allows the transmitter audio * filter bandwidth to be changed, but the filters allowed are only a subset of the * receive filters. This table is used to restrict the filters to the allowable * range. */ static int tt550_tx_filters[] = { 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050 }; /***************************Support Functions********************************/ /* * tt550_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ int tt550_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); /* * set_transaction_active keeps the asynchronous decode routine from being called * when we get data back from a normal command. */ set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { set_transaction_inactive(rig); return retval; } /* * no data expected, TODO: flush input? */ if (!data || !data_len) { set_transaction_inactive(rig); return 0; } retval = read_string(rp, (unsigned char *) data, *data_len, NULL, 0, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; set_transaction_inactive(rig); return RIG_OK; } /* * tt550_tx_control - The 550 has a number of operations that control * the transmitter. Commands like enable/disable tx, enable/disable * amplifier loop, enable/disable keep alive, etc. * This function provides for these commands. */ int tt550_tx_control(RIG *rig, char oper) { int retval; char cmdbuf[4]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "#%c" EOM, oper); retval = write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf)); /* * if (retval == RIG_OK) not currently saving the state of these operations I'm * not sure we need to, but if so, this is where it would go. */ return retval; } /* * tt550_ldg_control - The 550 has a builtin LDG antenna tuner option. * This function controls the tuner operations. * * * The LDG tuner listens on the Pegasus' RS-232 * Rx Data line. The interface is one-way. The tuner can't * respond at all. The Pegasus will respond with Z when * it sees the commands meant for the tuner. This is normal. * The LDG tuner is only listening on the serial line * when RF is applied. Therefore, RF must be applied before * the tuner will do anything. * * $0 = Place tuner in bypass mode * $1 = Start Tune process * $3 = Cap Up * $4 = Cap Dn * $5 = Inductor Up * $6 = Inductor Dn * This function provides for these commands. */ int tt550_ldg_control(RIG *rig, char oper) { int retval, lvl_len; char cmdbuf[4], lvlbuf[32]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%c" EOM, oper); lvl_len = 3; retval = tt550_transaction(rig, cmdbuf, 3, lvlbuf, &lvl_len); /* * if (retval == RIG_OK) not currently saving the state of these operations I'm * not sure we need to, but if so, this is where it would go. */ return retval; } /* * Tuning Factor Calculations * Used by both receive and transmit vfo routines * to calculate the desired tuning parameters. * tx - 0 for receive tuning, 1 for transmit tuning * Thanks to the unknown author of the GPL'd windows program * found on the Ten-Tec site. Having working examples of the * calculations was invaluable. */ static void tt550_tuning_factor_calc(RIG *rig, int tx) { struct tt550_priv_data *priv; int Bfo = 700; double TFreq = 0, IVal, radio_freq = 0; int NVal, FVal; // N value/finetune value int TBfo = 0; // temporary BFO int IBfo = 1500; // Intermediate BFO Freq int FilterBw; // Filter Bandwidth determined from table int Mode, PbtAdj, RitAdj, XitAdj; priv = (struct tt550_priv_data *) STATE(rig)->priv; Mode = (tx ? priv->tx_mode : priv->rx_mode); radio_freq = ((tx ? priv->tx_freq : priv->rx_freq)) / (double) MHz(1); FilterBw = priv->width; PbtAdj = priv->pbtadj; RitAdj = priv->rit; XitAdj = priv->xit; if (tx) { int bwBFO = (FilterBw / 2) + 200; IBfo = (bwBFO > IBfo) ? bwBFO : IBfo; if (Mode == RIG_MODE_USB) { TFreq = radio_freq + (double)(IBfo / 1e6) + (double)(XitAdj / 1e6); IBfo = (int)(IBfo * 2.73); } if (Mode == RIG_MODE_LSB) { TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(XitAdj / 1e6); IBfo = (int)(IBfo * 2.73); } if (Mode == RIG_MODE_CW) { // CW Mode uses LSB Mode IBfo = 1500; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) + (double)(XitAdj / 1e6); IBfo = (int)(Bfo * 2.73); } if (Mode == RIG_MODE_FM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) + (double)(XitAdj / 1e6); IBfo = 0; } if (Mode == RIG_MODE_AM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) + (double)(XitAdj / 1e6); IBfo = 0; } } else { radio_freq = radio_freq + (double)(RitAdj / 1e6); if (Mode == RIG_MODE_USB) { IBfo = (FilterBw / 2) + 200; TFreq = radio_freq + (double)(IBfo / 1e6) + (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + PbtAdj ; } if (Mode == RIG_MODE_LSB) { IBfo = (FilterBw / 2) + 200; TFreq = radio_freq - (double)(IBfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + PbtAdj ; } if (Mode == RIG_MODE_CW) { /* CW Mode uses LSB Mode */ if (((FilterBw / 2) + 300) <= Bfo) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + Bfo + PbtAdj; } else { IBfo = (FilterBw / 2) + 300; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = IBfo + PbtAdj ; } } if (Mode == RIG_MODE_FM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = 0; } if (Mode == RIG_MODE_AM) { IBfo = 0; TFreq = radio_freq - (double)(IBfo / 1e6) + (double)(Bfo / 1e6) - (double)(PbtAdj / 1e6) + (double)(RitAdj / 1e6); IBfo = 0; } } TFreq = TFreq - 0.00125; NVal = (int)(TFreq * 400); IVal = (double)((TFreq * 400.0) - NVal); FVal = (int)(IVal * 2500.0 * 5.46); NVal = (NVal + 18000); TBfo = (tx ? IBfo : (int)(((double) IBfo + 8000.0) * 2.73)); priv->ctf = NVal; priv->ftf = FVal; priv->btf = TBfo; } /*************************End of Support Functions**************************/ /* * tt550_init: * Basically, it just sets up *priv with some sane defaults * */ int tt550_init(RIG *rig) { struct tt550_priv_data *priv; STATE(rig)->priv = (struct tt550_priv_data *) calloc(1, sizeof( struct tt550_priv_data)); if (!STATE(rig)->priv) { /* * whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt550_priv_data)); /* * set arbitrary initial status */ priv->rx_freq = MHz(3.985); priv->tx_freq = MHz(3.985); priv->rx_mode = RIG_MODE_LSB; priv->tx_mode = RIG_MODE_LSB; priv->width = kHz(2.4); priv->tx_width = kHz(2.4); priv->tx_cwbfo = priv->cwbfo = kHz(0.7); priv->agc = 2; /* medium */ priv->lineout = priv->spkvol = 0.0; /* mute */ priv->stepsize = 100; /* default to 100Hz tuning step */ return RIG_OK; } /* * Tentec generic tt550_cleanup routine * the serial port is closed by the frontend */ int tt550_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Software restart */ int tt550_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; reset_len = 16; retval = tt550_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } reset_len = 16; if (strstr(reset_buf, "DSP START")) { retval = tt550_transaction(rig, "P1" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } } if (!strstr(reset_buf, "RADIO START")) { return -RIG_EPROTO; } return RIG_OK; } /* * Tentec 550 transceiver open routine * Restart and set program to execute. */ int tt550_trx_open(RIG *rig) { struct tt550_priv_data *priv; priv = (struct tt550_priv_data *) STATE(rig)->priv; /* * Reset the radio and start its program running * We'll try twice to reset before giving up */ if (tt550_reset(rig, RIG_RESET_SOFT) != RIG_OK) { if (tt550_reset(rig, RIG_RESET_SOFT) != RIG_OK) { return -RIG_EPROTO; } } #ifdef BYPASS_KEEPALIVE /* * Temporarily Disable the transmitter Keep alive. The 550 expects the software * to execute a serial command at least once every two seconds or it will * disable TX. */ tt550_tx_control(rig, DISABLE_KEEPALIVE); #endif /* * Program the radio with the default mode,freq,filter */ tt550_set_tx_mode(rig, RIG_VFO_CURR, priv->tx_mode, priv->tx_width); tt550_set_rx_mode(rig, RIG_VFO_CURR, priv->rx_mode, priv->width); tt550_set_tx_freq(rig, RIG_VFO_CURR, priv->tx_freq); tt550_set_rx_freq(rig, RIG_VFO_CURR, priv->rx_freq); /* * Enable TX */ tt550_tx_control(rig, ENABLE_TX); /* * Bypass automatic tuner */ tt550_ldg_control(rig, '0'); return RIG_OK; } /* * tt550_set_freq * Set the receive frequency to that requested and if * Split mode is OFF do the transmitter too */ int tt550_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; retval = tt550_set_rx_freq(rig, vfo, freq); if (retval != RIG_OK) { return retval; } if (priv->split == RIG_SPLIT_OFF) { return tt550_set_tx_freq(rig, vfo, freq); } return retval; } /* * tt550_get_freq * Get the current receive frequency */ int tt550_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; *freq = priv->rx_freq; return RIG_OK; } /* * tt550_set_mode * Set the receive mode and if NOT in split mode * set the transmitter to the same mode/width */ int tt550_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; retval = tt550_set_rx_mode(rig, vfo, mode, width); if (retval != RIG_OK) { return retval; } if (priv->split == RIG_SPLIT_OFF) { return tt550_set_tx_mode(rig, vfo, mode, width); } return retval; } /* * tt550_get_mode * GET the current receive mode/width */ int tt550_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; *mode = priv->rx_mode; *width = priv->width; return RIG_OK; } /* * tt550_set_rx_freq * Set the receiver to the requested frequency */ int tt550_set_rx_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tt550_priv_data *priv; int retval; char freqbuf[16]; priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->rx_freq = freq; tt550_tuning_factor_calc(rig, RECEIVE); SNPRINTF(freqbuf, sizeof(freqbuf), "N%c%c%c%c%c%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt550_set_tx_freq * Set the current transmit frequency */ int tt550_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tt550_priv_data *priv; int retval; char freqbuf[16]; priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->tx_freq = freq; tt550_tuning_factor_calc(rig, TRANSMIT); SNPRINTF(freqbuf, sizeof(freqbuf), "T%c%c%c%c%c%c" EOM, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt550_get_tx_freq * Get the current transmit frequency */ int tt550_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *freq = priv->tx_freq; return RIG_OK; } /* * tt550_set_rx_mode * SET the current receive mode */ int tt550_set_rx_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char ttmode; rmode_t saved_mode; pbwidth_t saved_width; int ttfilter = -1, retval; char mdbuf[48]; /* * Find mode for receive */ switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* * backup current values in case we fail to write to port */ saved_mode = priv->rx_mode; saved_width = priv->width; if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } for (ttfilter = 0; tt550_filters[ttfilter] != 0; ttfilter++) { if (tt550_filters[ttfilter] == width) { break; } } if (tt550_filters[ttfilter] != width) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %d\n", __func__, (int)width); return -RIG_EINVAL; } priv->width = width; } priv->rx_mode = mode; tt550_tuning_factor_calc(rig, RECEIVE); SNPRINTF(mdbuf, sizeof(mdbuf), "M%c%c" EOM, ttmode, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->rx_mode = saved_mode; priv->width = saved_width; return retval; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "W%c" EOM "N%c%c%c%c%c%c" EOM, ttfilter, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->width = saved_width; return retval; } } return RIG_OK; } /* * tt550_set_tx_mode * Set the current transmit mode/filter * Since the transmitter uses a subset of the filters used * by the receiver we set the filter if possible, if not we use * the nearest value. */ int tt550_set_tx_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char ttmode; rmode_t saved_mode; pbwidth_t saved_width; int ttfilter = -1, retval; char mdbuf[48]; switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported tx mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* * backup current values in case we fail to write to port */ saved_mode = priv->tx_mode; saved_width = priv->tx_width; if (width != RIG_PASSBAND_NOCHANGE) { /* * Limit the transmitter bandwidth - it's not the same as the receiver */ if (width < 1050) { width = 1050; } if (width > 3900) { width = 3900; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } for (ttfilter = 0; tt550_tx_filters[ttfilter] != 0; ttfilter++) { if (tt550_tx_filters[ttfilter] == width) { break; } } if (tt550_tx_filters[ttfilter] != width) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported tx width %d,%d\n", __func__, (int)width, ttfilter); return -RIG_EINVAL; } /* * The tx filter array contains just the allowed filter values, but the * command assumes that the first allowed value is at offset 7. We add * 7 to compensate for the array difference */ ttfilter += 7; priv->tx_width = width; } priv->tx_mode = mode; tt550_tuning_factor_calc(rig, TRANSMIT); SNPRINTF(mdbuf, sizeof(mdbuf), "M%c%c" EOM, ttmode, ttmode); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->tx_mode = saved_mode; priv->tx_width = saved_width; return retval; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "C%c" EOM "T%c%c%c%c%c%c" EOM, ttfilter, priv->ctf >> 8, priv->ctf & 0xff, priv->ftf >> 8, priv->ftf & 0xff, priv->btf >> 8, priv->btf & 0xff); retval = write_block(rp, (unsigned char *) mdbuf, strlen(mdbuf)); if (retval != RIG_OK) { priv->tx_width = saved_width; return retval; } } return RIG_OK; } /* * tt550_get_tx_mode */ int tt550_get_tx_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *mode = priv->tx_mode; *width = priv->tx_width; return RIG_OK; } /* * Set the RIT value and force receive frequency to change */ int tt550_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->rit = rit; tt550_set_rx_freq(rig, vfo, priv->rx_freq); return RIG_OK; } /* * Get The current RIT value */ int tt550_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *rit = priv->rit; return RIG_OK; } /* * Set the XIT value and force the Transmit frequency to change */ int tt550_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->xit = xit; tt550_set_tx_freq(rig, vfo, priv->tx_freq); return RIG_OK; } /* * Get the Current XIT value */ int tt550_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *xit = priv->xit; return RIG_OK; } /* * tt550_set_level */ int tt550_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retval, ditfactor, dahfactor, spcfactor; char cmdbuf[32]; switch (level) { case RIG_LEVEL_AGC: SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%c" EOM, val.i >= 3 ? '3' : (val.i < 2 ? '1' : '2')); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->agc = val.i; } return retval; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "V%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->spkvol = val.f; } return retval; #ifdef RIG_LEVEL_LINEOUT case RIG_LEVEL_LINEOUT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "L%c" EOM, (int)(val.f * 63)); retval = write_block(rp, cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->lineout = val.f; } return retval; #endif case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->rflevel = val.f; } return retval; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "S%c" EOM, (int)(val.f * 19)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->sql = val.f; } return retval; case RIG_LEVEL_NR: SNPRINTF(cmdbuf, sizeof(cmdbuf), "D%c" EOM, (int)(val.f * 7)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->nr = val.f; } return retval; case RIG_LEVEL_ATT: /* * attenuator is either on or off */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "B%c" EOM, val.i < 15 ? '0' : '1'); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->att = val.i; } return retval; case RIG_LEVEL_KEYSPD: ditfactor = spcfactor = (int)(((double) 0.50 / (val.i * (double) 0.4166 * (double) 0.0001667))); dahfactor = ditfactor * 3; SNPRINTF(cmdbuf, sizeof(cmdbuf), "E%c%c%c%c%c%c" EOM, ditfactor >> 8, ditfactor & 0xff, dahfactor >> 8, dahfactor & 0xff, spcfactor >> 8, spcfactor & 0xff); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->keyspd = val.i; } return retval; case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "P%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->rfpower = val.f; } return retval; case RIG_LEVEL_VOXGAIN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UG%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->voxgain = val.f; } return retval; case RIG_LEVEL_VOXDELAY: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UH%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->voxdelay = val.f; } return retval; case RIG_LEVEL_ANTIVOX: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UA%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->antivox = val.f; } return retval; case RIG_LEVEL_COMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "Y%c" EOM, (int)(val.f * 127)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->speechcomp = val.f; } return retval; case RIG_LEVEL_MICGAIN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "O1%c%c" EOM, 0, (int)(val.f * 15)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->mikegain = val.f; } return retval; case RIG_LEVEL_BKINDL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "UQ%c" EOM, (int)(val.f * 255)); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval == RIG_OK) { priv->bkindl = val.f; } return retval; case RIG_LEVEL_IF: priv->pbtadj = val.i; retval = tt550_set_rx_freq(rig, vfo, priv->tx_freq); return retval; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt550_get_level */ int tt550_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; int retval, lvl_len; char lvlbuf[32]; switch (level) { case RIG_LEVEL_STRENGTH: /* * read A/D converted value */ lvl_len = 7; retval = tt550_transaction(rig, "?S" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "tt550_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * Crude but it should work, the first and second digits are * the ascii value for the S number (0x30 = S0 etc.) followed by * a two byte fractional binary portion - We only use the first * portion for now. */ val->i = (((lvlbuf[2] - 0x30) * 6) - 54); break; case RIG_LEVEL_RAWSTR: /* * read A/D converted value */ lvl_len = 6; retval = tt550_transaction(rig, "?X" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "tt550_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } val->i = (lvlbuf[1] << 8) + lvlbuf[2]; break; case RIG_LEVEL_AGC: val->f = priv->agc; break; case RIG_LEVEL_AF: val->f = priv->spkvol; break; #ifdef RIG_LEVEL_LINEOUT case RIG_LEVEL_LINEOUT: val->f = priv->lineout; break; #endif case RIG_LEVEL_RF: val->f = priv->rflevel; break; case RIG_LEVEL_SQL: val->f = priv->sql; break; case RIG_LEVEL_ATT: val->i = priv->att; break; case RIG_LEVEL_KEYSPD: val->i = priv->keyspd; break; case RIG_LEVEL_NR: val->f = priv->nr; break; case RIG_LEVEL_RFPOWER: val->f = priv->rfpower; break; case RIG_LEVEL_VOXGAIN: val->f = priv->voxgain; break; case RIG_LEVEL_VOXDELAY: val->f = priv->voxdelay; break; case RIG_LEVEL_ANTIVOX: val->f = priv->antivox; break; case RIG_LEVEL_COMP: val->f = priv->speechcomp; break; case RIG_LEVEL_MICGAIN: val->f = priv->mikegain; break; case RIG_LEVEL_BKINDL: val->f = priv->bkindl; break; case RIG_LEVEL_IF: val->i = priv->pbtadj; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt550_get_info */ const char * tt550_get_info(RIG *rig) { static char buf[16]; int firmware_len, retval; /* * protocol version */ firmware_len = 10; retval = tt550_transaction(rig, "?V" EOM, 3, buf, &firmware_len); if (retval != RIG_OK || firmware_len != 9) { rig_debug(RIG_DEBUG_ERR, "tt550_get_info: ack NG, len=%d\n", firmware_len); return NULL; } buf[firmware_len] = '\0'; return buf; } /* * tt550_set_ptt */ int tt550_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmdbuf[16]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "Q%c" EOM, ptt == 0 ? '0' : '1'); return (write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf))); } /* * tt550_get_ptt */ int tt550_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { static char buf[10]; int len, retval; /* * The 550 doesn't have an explicit command to return ptt status, so we fake it * with the request for signal strength which returns a 'T' for the first * character if we're transmitting */ len = 7; retval = tt550_transaction(rig, "?S" EOM, 3, buf, &len); if (retval != RIG_OK) { return retval; } /* * buf should contain either Sxx for Receive Signal strength * or Txx for Transmit power/reflected power */ *ptt = buf[0] == 'T' ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * tt550_set_split_vfo */ int tt550_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; priv->split = split; return RIG_OK; } /* * tt550_get_split_vfo */ int tt550_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; *split = priv->split; return RIG_OK; } int tt550_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char fctbuf[16]; struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_VOX: SNPRINTF((char *) fctbuf, sizeof(fctbuf), "U%c" EOM, status == 0 ? '0' : '1'); priv->vox = status; return write_block(rp, fctbuf, strlen((char *)fctbuf)); case RIG_FUNC_NR: SNPRINTF((char *) fctbuf, sizeof(fctbuf), "K%c%c" EOM, status == 0 ? '0' : '1', priv->anf == 0 ? '0' : '1'); priv->en_nr = status; return write_block(rp, fctbuf, strlen((char *)fctbuf)); case RIG_FUNC_ANF: SNPRINTF((char *) fctbuf, sizeof(fctbuf), "K%c%c" EOM, priv->en_nr == 0 ? '0' : '1', status == 0 ? '0' : '1'); priv->anf = status; return write_block(rp, fctbuf, strlen((char *)fctbuf)); case RIG_FUNC_TUNER: priv->tuner = status; if (status == '0') { tt550_ldg_control(rig, 0); } return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } int tt550_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_VOX: *status = priv->vox; break; case RIG_FUNC_NR: *status = priv->en_nr; break; case RIG_FUNC_ANF: *status = priv->anf; break; case RIG_FUNC_TUNER: *status = priv->tuner; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * tt550_set_tuning_step */ int tt550_set_tuning_step(RIG *rig, vfo_t vfo, shortfreq_t stepsize) { struct tt550_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct tt550_priv_data *) rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_set_tuning_step - %d\n", __func__, (int)stepsize); priv->stepsize = stepsize; return RIG_OK; } /* * tt550_get_tuning_step */ int tt550_get_tuning_step(RIG *rig, vfo_t vfo, shortfreq_t *stepsize) { struct tt550_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct tt550_priv_data *) rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_get_tuning_step - %d\n", __func__, (int)priv->stepsize); *stepsize = priv->stepsize; return RIG_OK; } /* * Tune the radio using the LDG antenna tuner */ int tt550_tune(RIG *rig) { value_t current_power; rmode_t current_mode; value_t lowpower; const struct tt550_priv_data *priv = (struct tt550_priv_data *) STATE( rig)->priv; /* Set our lowpower level to about 10 Watts */ lowpower.f = 0.12; /* Get the current power and save it, */ current_power.f = priv->rfpower; /* Set power to approx 10w */ tt550_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER, lowpower); /* Get the current mode, and save */ current_mode = priv->tx_mode; /* Set the mode to cw, keep the old frequency and bandwidth */ tt550_set_tx_mode(rig, RIG_VFO_CURR, RIG_MODE_CW, priv->tx_width); tt550_set_tx_freq(rig, RIG_VFO_CURR, priv->tx_freq); /* key the radio */ tt550_set_ptt(rig, RIG_VFO_CURR, 1); /* Wait long enough for the transmitter to key up */ sleep(1); /* Start the tuner */ tt550_ldg_control(rig, '1'); /* * Wait for tuner to finish * NOTE: Using sleep and blocking like this is BAD, we * really should have a way to tell that the tuner is finished. * What we should be doing here is probably: * 1. wait one second for tuner to start. * 2. Unkey the radio - the LDG tuner will keep it keyed until * it is done. (I think) * NOTE: I was wrong, the LDG does not key the rig so this won't work. * Have to come up with something else. * 3. Keep checking for the Radio to be unkeyed * 4. Stop the tuner and restore everything. * The above should all be done asynchronous to this function so * that we don't stall the calling routine. */ sleep(4); /* Unkey the Radio */ tt550_set_ptt(rig, RIG_VFO_CURR, 0); /* Restore the mode and frequency */ tt550_set_tx_mode(rig, RIG_VFO_CURR, current_mode, priv->tx_width); tt550_set_tx_freq(rig, RIG_VFO_CURR, priv->tx_freq); /* Restore the original Power setting */ tt550_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_RFPOWER, current_power); return RIG_OK; } /* * tt550_vfo_op */ int tt550_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { switch (op) { case RIG_OP_TUNE: tt550_tune(rig); break; default: rig_debug(RIG_DEBUG_ERR, "tt550_vfo_op: unsupported op %#x\n", op); return -RIG_EINVAL; } return RIG_OK; } #define MAXFRAMELEN 7 /* * tt550_decode is called by sa_sigio, when asynchronous data * has been received from the rig * * A lot more can be done in this routine. Things like allowing F2 * to switch the encoder between frequency, audio, power control. Or * letting a function key cycle thru various bands. * For now it just handles the encoder for frequency change and F1 for * changing the step size. */ int tt550_decode_event(RIG *rig) { struct tt550_priv_data *priv; struct rig_state *rs; unsigned char buf[MAXFRAMELEN]; int data_len; // char key; rig_debug(RIG_DEBUG_VERBOSE, "%s/tt: tt550_decode_event called\n", __func__); rs = STATE(rig); priv = (struct tt550_priv_data *) rs->priv; data_len = read_string(RIGPORT(rig), buf, MAXFRAMELEN, "\n\r", 2, 0, 1); if (data_len == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_decode got a timeout before the first character\n", __func__); return RIG_OK; } rig_debug(RIG_DEBUG_VERBOSE, "%s: tt550_decode %p\n", __func__, &buf); /* * The first byte must be either 'U' for keypad operations * or '!' for encoder operations. */ switch (*buf) { /* * For now we'll assume that the encoder is only used for * frequency control, but since it's really a general purpose * device we could later use it for other purposes. * Tied in with priv->stepsize to allow the step rate to change */ case '!': if (rig->callbacks.freq_event) { int movement = buf[1] << 8; movement = movement | buf[2]; // key = buf[3]; rig_debug(RIG_DEBUG_VERBOSE, "%s: Step Direction = %d\n", __func__, movement); if (movement > 0) { priv->rx_freq += priv->stepsize; } if (movement < 0) { priv->rx_freq -= priv->stepsize; } rig->callbacks.freq_event(rig, RIG_VFO_CURR, priv->rx_freq, rig->callbacks.freq_arg); } break; /* * Keypad Function Key support - for now only F1 * Numeric pad can be done later */ case 'U': switch (buf[1]) { case KEY_F1_DOWN: /* F1 changes the Step size from 1hz to 1mhz */ if (priv->stepsize < 10000) { /* In powers of ten */ priv->stepsize = priv->stepsize * 10; } else { priv->stepsize = 1; } break; case KEY_F2_DOWN: case KEY_F3_DOWN: case KEY_F1_UP: case KEY_F2_UP: case KEY_F3_UP: default: rig_debug(RIG_DEBUG_VERBOSE, "tt550_decode: KEY " "unsupported %d\n", buf[1]); return -RIG_ENIMPL; } break; default: rig_debug(RIG_DEBUG_VERBOSE, "tt550_decode: response " "unsupported %s\n", buf); return -RIG_ENIMPL; } return RIG_OK; } hamlib-4.6.2/rigs/tentec/rx331.h0000644000175000017500000000200214752216205013155 00000000000000/* * Hamlib Tentec backend - RX331 header * Copyright (c) 2010 by Berndt Josef Wulf * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RX331_H #define _RX331_H #include "token.h" #define TOK_RIGID TOKEN_BACKEND(1) struct rx331_priv_data { unsigned int receiver_id; }; #endif hamlib-4.6.2/rigs/tentec/rx350.c0000644000175000017500000001136114752216205013161 00000000000000/* * Hamlib TenTenc backend - RX-350 description * Copyright (c) 2003-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "tentec2.h" #define RX350_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|\ RIG_MODE_AM|RIG_MODE_AMS) #define RX350_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF) #define RX350_LEVELS (RIG_LEVEL_RAWSTR|/*RIG_LEVEL_NB|*/ \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_AF|RIG_LEVEL_AGC| \ RIG_LEVEL_SQL|RIG_LEVEL_ATT) #define RX350_ANTS (RIG_ANT_1) #define RX350_PARMS (RIG_PARM_TIME) #define RX350_VFO (RIG_VFO_A|RIG_VFO_B) #define RX350_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) // Taken from RX320_STR_CAL -- unknown if accurate for RX350 #define RX350_STR_CAL { 17, { \ { 0, -60 }, \ { 10, -50 }, \ { 20, -40 }, \ { 30, -30 }, \ { 40, -20 }, \ { 50, -15 }, \ { 100, -10 }, \ { 200, -5 }, \ { 225, -3 }, \ { 256, 0 }, \ { 512, 1 }, \ { 768, 3}, \ { 1024, 4 }, \ { 1280, 5 }, \ { 2560, 10 }, \ { 5120, 20 }, \ { 10000, 30 }, \ } } /* * RX350 receiver capabilities. * * Protocol is documented at * http://www.rfsquared.com/ * * Only set_freq is supposed to work. * This is a skeleton. */ struct rig_caps rx350_caps = { RIG_MODEL(RIG_MODEL_RX350), .model_name = "RX-350", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .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 = 400, .retry = 3, .has_get_func = RX350_FUNCS, .has_set_func = RX350_FUNCS, .has_get_level = RX350_LEVELS, .has_set_level = RIG_LEVEL_SET(RX350_LEVELS), .has_get_parm = RX350_PARMS, .has_set_parm = RX350_PARMS, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } } }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 8, .chan_desc_sz = 15, .chan_list = { { 0, 127, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(100), MHz(30), RX350_MODES, -1, -1, RX350_VFO, RX350_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), RX350_MODES, -1, -1, RX350_VFO, RX350_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX350_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RX350_MODES, kHz(2.4)}, {RX350_MODES, 300}, {RX350_MODES, kHz(8)}, {RX350_MODES, 0}, /* 34 filters */ RIG_FLT_END, }, .str_cal = RX350_STR_CAL, .priv = (void *)NULL, .set_freq = tentec2_set_freq, .get_freq = tentec2_get_freq, .set_vfo = tentec2_set_vfo, .get_vfo = tentec2_get_vfo, .set_mode = tentec2_set_mode, .get_mode = tentec2_get_mode, .reset = tentec2_reset, .get_info = tentec2_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/tentec/pegasus.c0000644000175000017500000002152214752216205013747 00000000000000/* * Hamlib TenTenc backend - TT-550 PC-Radio description * Copyright (c) 2002-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "tt550.h" #define TT550_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_AM) #define TT550_RXMODES (TT550_MODES) #define TT550_FUNCS (RIG_FUNC_VOX|RIG_FUNC_ANF|RIG_FUNC_TUNER| \ RIG_FUNC_NR|RIG_FUNC_VOX) #define TT550_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_AF|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH| \ RIG_LEVEL_RF|RIG_LEVEL_COMP|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT|RIG_LEVEL_NR|RIG_LEVEL_IF| \ RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX) #define TT550_VFO (RIG_VFO_A ) #define TT550_VFO_OPS (RIG_OP_TUNE) /* * a bit coarse, but I don't have a TT550, and the manual is not * verbose on the subject. Please test it and report! --SF */ #define TT550_STR_CAL { 2, { \ { 0, -60 }, \ { 10000, 20 }, \ } } /* * tt550 receiver capabilities. * * protocol is documented at * http://www.tentec.com/550/550prg2.pdf * * TODO: */ struct rig_caps tt550_caps = { RIG_MODEL(RIG_MODEL_TT550), .model_name = "TT-550", .mfg_name = "Ten-Tec", .version = "20190817.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .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 = 100, .retry = 4, .has_get_func = TT550_FUNCS, .has_set_func = TT550_FUNCS, .has_get_level = TT550_LEVELS, .has_set_level = RIG_LEVEL_SET(TT550_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = {.min = {.i = 0}, .max = {.i = 65535}}, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {20, RIG_DBLST_END}, .max_rit = Hz(10000), .max_xit = Hz(10000), .max_ifshift = Hz(2000), .targetable_vfo = RIG_TARGETABLE_ALL, .vfo_ops = TT550_VFO_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = {RIG_FRNG_END,}, /* FIXME: enter region 1 setting */ .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { {kHz(100), MHz(30), TT550_RXMODES, -1, -1, TT550_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(3500), MHz(4) - 1, TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(5330), kHz(5407) - 1, RIG_MODE_USB, 5000, 50000, TT550_VFO}, {MHz(7), kHz(7300), TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(10100), kHz(10150), TT550_MODES, 5000, 100000, TT550_VFO}, {MHz(14), kHz(14350), TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(18068), kHz(18168), TT550_MODES, 5000, 100000, TT550_VFO}, {MHz(21), kHz(21450), TT550_MODES, 5000, 100000, TT550_VFO}, {kHz(24890), kHz(24990), TT550_MODES, 5000, 100000, TT550_VFO}, {MHz(28), kHz(29700), TT550_MODES, 5000, 100000, TT550_VFO}, RIG_FRNG_END, }, .tuning_steps = { {TT550_RXMODES, RIG_TS_ANY}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, Hz(450)}, {RIG_MODE_CW, Hz(300)}, {RIG_MODE_CW, Hz(750)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_FM, Hz(4200)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2400)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2700)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2100)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(5700)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(5400)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(5100)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(4800)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(4500)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(4200)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(3900)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(3600)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(3300)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2850)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(8000)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2550)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2400)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(2250)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(6000)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1950)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1800)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1650)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1500)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1350)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1200)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(1050)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(900)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(750)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(675)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(600)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(525)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(450)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(375)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(330)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_CW, Hz(300)}, RIG_FLT_END, }, .str_cal = TT550_STR_CAL, .rig_init = tt550_init, .rig_cleanup = tt550_cleanup, .rig_open = tt550_trx_open, .reset = tt550_reset, .set_freq = tt550_set_freq, .get_freq = tt550_get_freq, .set_mode = tt550_set_mode, .get_mode = tt550_get_mode, .set_func = tt550_set_func, .get_func = tt550_get_func, .set_level = tt550_set_level, .get_level = tt550_get_level, .get_info = tt550_get_info, .set_ptt = tt550_set_ptt, .get_ptt = tt550_get_ptt, .set_split_freq = tt550_set_tx_freq, .get_split_freq = tt550_get_tx_freq, .set_split_mode = tt550_set_tx_mode, .get_split_mode = tt550_get_tx_mode, .set_split_vfo = tt550_set_split_vfo, .get_split_vfo = tt550_get_split_vfo, .decode_event = tt550_decode_event, .set_ts = tt550_set_tuning_step, .get_ts = tt550_get_tuning_step, .vfo_op = tt550_vfo_op, .set_rit = tt550_set_rit, .get_rit = tt550_get_rit, .set_xit = tt550_set_xit, .get_xit = tt550_get_xit, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/tentec/tentec2.c0000644000175000017500000003441614752216205013652 00000000000000/* * Hamlib Tentec backend - Argonaut, Jupiter, RX-350 * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Module rewritten and tested by Dave Freese, W1HKJ * Tested using the distributed test program "rigctl" to control an Argonaut V xcvr. * Linked to digital modem program, "gmfsk" and bench tested and used on-air * Linked to experimental digital modem program "fldigi", bench tested * and used on-air. * * Note for anyone wishing to expand on the command set. * Recommend using the * * tentec_transaction (rig, sendbuf, sendlen, rcvbuf, &rcv_len) * * function to send the command and receive the response. * * The Argo V always sends a response and ends the response with a "G\r" to * indicate that the command was accepted. A rejected command is responded to by a * two character sequence "Z\r". You should always expect a maximum response equal * to the number of data bytes plus two. * * For example: * A request for the present receiver filter bandwidth is the the string: * "?W\r" which is 3 bytes in length * The response from the Argonaut V will be: * "Wn\rG\r" which is 5 bytes in length, where n is an unsigned char (byte) * If the transceiver failed to receive the command correctly it will respond: * "Z\r" ----> you need to check for that condition * * The tentec_transaction(...) function will always terminate the rcvbuf with a null * character. The pointer to the receive buffer length MUST be initialized to the * length of the max # chars for that command PLUS 1 for the terminator. * For the above command, rcv_len should be 6. */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "tentec.h" #include "tentec2.h" #define TT_AM '0' #define TT_USB '1' #define TT_LSB '2' #define TT_CW '3' #define TT_FM '4' /************************************************************************************* * * Specs from http://www.rfsquared.com * * TODO: [sg]et_split * [sg]et_level: ATT, NB, PBT, KEYER_SPD, RFPOWER, SWR, SQL, STRENGTH, .. * vfo_op: TO_VFO, FROM_VFO + emulated set_mem/get_mem */ /* * tentec_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tentec2_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval, ret_len; char freqbuf[16] = "*Axxxx\r"; unsigned long f = (unsigned long)freq; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_B: freqbuf[1] = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } freqbuf[2] = (f >> 24) & 0xFF; freqbuf[3] = (f >> 16) & 0xFF; freqbuf[4] = (f >> 8) & 0xFF; freqbuf[5] = f & 0xFF; // Argo V will respond // "G\r" or "Z\r" ret_len = 3; retval = tentec_transaction(rig, freqbuf, 7, freqbuf, &ret_len); if (retval != RIG_OK) { return -RIG_EINVAL; } if (ret_len != 2 || freqbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_freq * Assumes rig!=NULL, freq!=NULL */ int tentec2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval, ret_len; char freqbuf[16] = "?A\r"; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_A: break; case RIG_VFO_B: freqbuf[1] = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // Argo V will respond with 8 characters // "Annnn\rG\r" or "Bnnnn\rG\r" // or it will respond // "Z\r" meaning the command was rejected ret_len = 9; retval = tentec_transaction(rig, freqbuf, 3, freqbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len == 2 && freqbuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 8) { return -RIG_EINVAL; } *freq = (unsigned int)((freqbuf[1] & 0x0FF) << 24) + (unsigned int)((freqbuf[2] & 0x0FF) << 16) + (unsigned int)((freqbuf[3] & 0x0FF) << 8) + (unsigned int)(freqbuf[4] & 0x0FF); return RIG_OK; } /* * tentec2_set_vfo * Assumes rig!=NULL */ int tentec2_set_vfo(RIG *rig, vfo_t vfo) { int retval, ret_len; char vfobuf[16] = "*EVA\r"; if ((vfo & ~RIG_VFO_MEM) == RIG_VFO_NONE || vfo == RIG_VFO_VFO) { vfo_t cvfo; retval = tentec2_get_vfo(rig, &cvfo); if (retval != RIG_OK) { return retval; } vfo = (cvfo & (RIG_VFO_A | RIG_VFO_B)) | (vfo & RIG_VFO_MEM); } if (vfo & RIG_VFO_MEM) { vfobuf[2] = 'M'; } switch (vfo & ~RIG_VFO_MEM) { case RIG_VFO_A: break; case RIG_VFO_B: vfobuf[3] = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } ret_len = 3; retval = tentec_transaction(rig, vfobuf, 5, vfobuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || vfobuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_vfo * Assumes rig!=NULL */ int tentec2_get_vfo(RIG *rig, vfo_t *vfo) { int ret_len, retval; unsigned char vfobuf[16] = "?E\r"; ret_len = 7; retval = tentec_transaction(rig, (char *) vfobuf, 3, (char *) vfobuf, &ret_len); if (retval != RIG_OK) { return retval; } // ArgoV sends back 6 character string // "EVA\rG\r" or "EVB\rG\r" // or 2 character failure string // "Z\r" if (ret_len == 2 && vfobuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 6) { return -RIG_EPROTO; } *vfo = vfobuf[2] == 'A' ? RIG_VFO_A : RIG_VFO_B; if (vfobuf[1] == 'M') { *vfo |= RIG_VFO_MEM; } return RIG_OK; } /* * tentec2_set_split_vfo * Assumes rig!=NULL */ int tentec2_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval, ret_len; char retbuf[10] = "*Ox\r"; if (split == RIG_SPLIT_ON) { retbuf[2] = 1; } else { retbuf[2] = 0; } ret_len = 3; retval = tentec_transaction(rig, retbuf, 4, retbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || retbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_split_vfo * Assumes rig!=NULL */ int tentec2_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int ret_len, retval; char splitbuf[16] = "?O\r"; /* * TODO: handle tx_vfo */ ret_len = 6; retval = tentec_transaction(rig, splitbuf, 3, splitbuf, &ret_len); // Argo V returns // "On\rG\r" or // "Z\r" if (retval != RIG_OK) { return retval; } if (ret_len == 2 && splitbuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 5) { return -RIG_EPROTO; } *split = splitbuf[1] == 0 ? RIG_SPLIT_OFF : RIG_SPLIT_ON; return RIG_OK; } /* * tentec2_set_mode * Assumes rig!=NULL */ int tentec2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char ttmode; int ttfilter, retval, ret_len; char mdbuf[16]; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } switch (mode) { case RIG_MODE_USB: ttmode = TT_USB; break; case RIG_MODE_LSB: ttmode = TT_LSB; break; case RIG_MODE_CW: ttmode = TT_CW; break; case RIG_MODE_AM: ttmode = TT_AM; break; case RIG_MODE_FM: ttmode = TT_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* get the mode because we want to leave other VFO unchanged */ ret_len = 7; retval = tentec_transaction(rig, "?M\r", 3, &mdbuf[1], &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 6) { return -RIG_EPROTO; } mdbuf[0] = '*'; switch (vfo) { case RIG_VFO_A: mdbuf[2] = ttmode; break; case RIG_VFO_B: mdbuf[3] = ttmode; break; default: return -RIG_EINVAL; } ret_len = 3; retval = tentec_transaction(rig, mdbuf, 5, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || mdbuf[0] != 'G') { return -RIG_ERJCTED; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } /* * Filter 0: 200 * .. * Filter 16: 1000 * .. * Filter 36: 3000 */ if (width < 200) { ttfilter = 0; } else if (width > 3000) { ttfilter = 36; } else if (width < 1000) { ttfilter = (width / 50) - 4; } else { ttfilter = (width / 100) + 6; } strcpy(mdbuf, "*Wn\r"); mdbuf[2] = ttfilter; ret_len = 3; retval = tentec_transaction(rig, mdbuf, 4, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || mdbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_mode * Assumes rig!=NULL, mode!=NULL */ int tentec2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ttfilter, retval, ret_len; char mdbuf[16]; if (vfo == RIG_VFO_CURR) { if ((retval = tentec2_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } } // response to "?M\r" command: // "M00" -> AM, "M1" -> USB, "M2" -> LSB, "M3" -> CW, "M4" -> FM ret_len = 7; retval = tentec_transaction(rig, "?M\r", 3, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 6) { return -RIG_EPROTO; } if (vfo != RIG_VFO_A && vfo != RIG_VFO_B) { return -RIG_EINVAL; } switch (mdbuf[vfo == RIG_VFO_A ? 1 : 2]) { case TT_USB: *mode = RIG_MODE_USB; break; case TT_LSB: *mode = RIG_MODE_LSB; break; case TT_CW: *mode = RIG_MODE_CW; break; case TT_AM: *mode = RIG_MODE_AM; break; case TT_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, mdbuf[vfo == RIG_VFO_A ? 1 : 2]); return -RIG_EPROTO; } ret_len = 6; retval = tentec_transaction(rig, "?W\r", 3, mdbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len == 2 && mdbuf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 5) { return -RIG_EPROTO; } /* * Filter 0: 200 * .. * Filter 16: 1000 * .. * Filter 36: 3000 */ ttfilter = mdbuf[1]; if (ttfilter < 0 || ttfilter > 36) { return -RIG_EPROTO; } if (ttfilter < 16) { *width = ((long)ttfilter + 4L) * 50L; } else { *width = ((long)ttfilter - 6L) * 100L; } return RIG_OK; } /* * tentec2_set_ptt * Assumes rig!=NULL */ int tentec2_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval, ret_len; char retbuf[10]; ret_len = 3; retval = tentec_transaction(rig, ptt == RIG_PTT_ON ? "#1\r" : "#0\r", 3, retbuf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 2 || retbuf[0] != 'G') { return -RIG_ERJCTED; } return RIG_OK; } /* * tentec2_get_ptt * Assumes rig!=NULL */ int tentec2_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret_len, retval; char buf[7] = "?C\r"; ret_len = 7; retval = tentec_transaction(rig, buf, 3, buf, &ret_len); if (retval != RIG_OK) { return retval; } // ArgoV sends back 6 character string // "Cnn\rG\r" where nn is the status word // or 2 character failure string // "Z\r" if (ret_len == 2 && buf[0] == 'Z') { return -RIG_ERJCTED; } if (ret_len != 6) { return -RIG_EPROTO; } *ptt = (buf[2] & 0x01) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * Software restart */ int tentec2_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; reset_len = 32; retval = tentec_transaction(rig, "*X\r", 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "RADIO START")) { return -RIG_EPROTO; } return RIG_OK; } /* * tentec2_get_info * Assumes rig!=NULL */ const char *tentec2_get_info(RIG *rig) { static char buf[100]; /* FIXME: reentrancy */ int firmware_len, retval; /* * protocol version */ buf[0] = 0; firmware_len = 100; retval = tentec_transaction(rig, "?V\r", 3, buf, &firmware_len); /* "VER 1010-516" */ if (retval != RIG_OK || firmware_len != 12) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } return buf; } hamlib-4.6.2/rigs/tentec/Android.mk0000644000175000017500000000055714752216205014052 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := rx320.c rx340.c rx350.c rx331.c \ pegasus.c argonaut.c orion.c jupiter.c omnivii.c paragon.c \ tentec.c tentec2.c tt550.c LOCAL_MODULE := tentec LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/tentec/orion.h0000644000175000017500000004712614752216205013443 00000000000000/* * Hamlib TenTenc backend - TT-565 headers * Copyright (c) 2004-2011 by Stephane Fillod * Copyright (c) 2004-2011 by Martin Ewing * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup tentec_orion * @{ */ /** * \file orion.h * \brief Backend for Tentec Orion 565 / 566 * * This backend supports the Ten-Tec Orion (565) and Orion II (566) transceivers. */ #include #include "bandplan.h" #include "rig.h" #include "riglist.h" #include "mutex.h" #define BACKEND_VER "20240621" #define TRUE 1 #define FALSE 0 #define TT565_BUFSIZE 32 /** * \brief Memory capability * * Orion's own memory channel holds a freq, mode, and bandwidth. * May be captured from VFO A or B and applied to VFO A or B. * It cannot directly be read or written from the computer! */ #define TT565_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } static int tt565_init(RIG *rig); static int tt565_open(RIG *rig); static int tt565_close(RIG *rig); static int tt565_cleanup(RIG *rig); static int tt565_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt565_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt565_get_freq_cache(RIG *rig, vfo_t vfo, freq_t *freq); static int tt565_set_vfo(RIG *rig, vfo_t vfo); static int tt565_get_vfo(RIG *rig, vfo_t *vfo); static int tt565_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tt565_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt565_get_mode_cache(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt565_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int tt565_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tt565_get_split_vfo_cache(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tt565_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tt565_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int tt565_reset(RIG *rig, reset_t reset); static int tt565_set_mem(RIG * rig, vfo_t vfo, int ch); static int tt565_get_mem(RIG * rig, vfo_t vfo, int *ch); static int tt565_vfo_op(RIG * rig, vfo_t vfo, vfo_op_t op); static int tt565_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int tt565_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); static int tt565_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); static int tt565_get_rit(RIG * rig, vfo_t vfo, shortfreq_t *rit); static int tt565_set_xit(RIG * rig, vfo_t vfo, shortfreq_t xit); static int tt565_get_xit(RIG * rig, vfo_t vfo, shortfreq_t *xit); static int tt565_set_level(RIG * rig, vfo_t vfo, setting_t level, value_t val); static int tt565_get_level(RIG * rig, vfo_t vfo, setting_t level, value_t *val); static const char* tt565_get_info(RIG *rig); static int tt565_send_morse(RIG *rig, vfo_t vfo, const char *msg); static int tt565_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int tt565_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int tt565_set_ant(RIG * rig, vfo_t vfo, ant_t ant, value_t option); static int tt565_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); /** \brief Orion private data */ struct tt565_priv_data { int ch; /*!< memory channel */ vfo_t vfo_curr; /*!< Currently selected VFO */ int ptt; freq_t freqA, freqB; rmode_t mode; pbwidth_t width; pthread_t threadid; split_t split; vfo_t tx_vfo; int threadrun; }; MUTEX(mutex); /** \brief Orion Supported Modes */ #define TT565_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_AM) /** \brief Orion Receiver Modes */ #define TT565_RXMODES (TT565_MODES) /** \brief Orion Supported Functions */ #define TT565_FUNCS (RIG_FUNC_LOCK|RIG_FUNC_TUNER|RIG_FUNC_VOX|RIG_FUNC_NB) /** \brief Orion Supported Levels */ #define TT565_LEVELS (RIG_LEVEL_RAWSTR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_SQL|RIG_LEVEL_IF| \ RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD| \ RIG_LEVEL_RF|RIG_LEVEL_NR| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_AF|RIG_LEVEL_AGC| \ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_COMP|RIG_LEVEL_PREAMP| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT) /** \brief Orion Tx/Rx Antennas*/ #define TT565_ANTS (RIG_ANT_1|RIG_ANT_2) /** \brief Orion Rx Antennas*/ #define TT565_RXANTS (TT565_ANTS|RIG_ANT_3) /** \brief Orion Parameters */ #define TT565_PARMS (RIG_PARM_NONE) /** * \brief Orion VFOs - A and B */ #define TT565_VFO (RIG_VFO_A|RIG_VFO_B) /** * \brief Orion VFO Operations * * Allowed operations */ #define TT565_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO| \ RIG_OP_TUNE) /** * \brief S-Meter Calibration list * * List format: { hardware units, dB relative to S9} * * These alternate tables must be of equal size, because they may be * switched depending on firmware version detection. * * Note high end of scale is severely compressed in v1 * Table corrected against v 1.372, 11/2007 */ #define TT565_STR_CAL_V1 { 14, { \ { 1, -47 }, /* padding to match lengths with v2 */ \ { 10, -47 }, \ { 13, -42 }, \ { 18, -37 }, \ { 22, -32 }, \ { 27, -27 }, \ { 32, -18 }, \ { 37, -11 }, \ { 42, -4 }, \ { 47, -1 }, \ { 52, 10 }, \ { 57, 20 }, \ { 65, 30 }, \ { 74, 40 }, \ } } /** * Calibration for Version 2.062a firmware, from Rigserve project. * Again, this is approximate based on one measurement. */ #define TT565_STR_CAL_V2 { 14, { \ { 10., -48. }, /* S1 = min. indication */ \ { 24., -42. }, \ { 38., -36. }, \ { 47., -30. }, \ { 61., -24. }, \ { 70., -18. }, \ { 79., -12. }, \ { 84., -6. }, \ { 94., 0. }, /* S9 */ \ { 103., 10. }, \ { 118., 20. }, \ { 134., 30. }, \ { 147., 40. }, \ { 161., 50. }, \ } } #undef TT565_TIME /* Define to enable time checks */ #define TT565_ASCII_FREQ /* select ascii mode for vfo commands */ /* Note: Binary mode seems buggy at certain freqs like 7015679 < freq < 7015936, etc. Use ascii mode. */ /** * \brief tt565 transceiver capabilities. * * All of the Orion's personality is defined here! * * Protocol is documented at Tentec's firmware site * http://www.rfsquared.com/ */ struct rig_caps tt565_caps = { RIG_MODEL(RIG_MODEL_TT565), .model_name = "TT-565/566 Orion I/II", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, /* no delay between characters written */ .post_write_delay = 0, /* ms delay between writes DEBUGGING HERE */ .timeout = 200, /* ms */ .retry = 1, .has_get_func = TT565_FUNCS, .has_set_func = TT565_FUNCS, .has_get_level = TT565_LEVELS, .has_set_level = RIG_LEVEL_SET(TT565_LEVELS), .has_get_parm = TT565_PARMS, .has_set_parm = TT565_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 20, RIG_DBLST_END }, .attenuator = { 6, 12, 18, RIG_DBLST_END }, .max_rit = kHz(8), .max_xit = kHz(8), .max_ifshift = kHz(8), .vfo_ops = TT565_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, TT565_MEM_CAP }, }, /* Note Orion's ranges correspond to the hardware capability - same in * regions 1 and 2. Band edges (VFOA) are wider than legal bands. * VFOB is used for general coverage receive. */ .rx_range_list1 = { /* FRQ_RNG_HF(1,TT565_RXMODES, -1,-1,RIG_VFO_N(0),TT565_RXANTS), */ {kHz(1790),kHz(2010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(3490),kHz(4075),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(5100),kHz(5450),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(6890),kHz(7430),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(10090),kHz(10160),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(13990),kHz(15010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(18058),kHz(18178),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(20990),kHz(21460),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(24880),kHz(25000),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(27990),kHz(29710),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(100),MHz(30),TT565_RXMODES,-1,-1,RIG_VFO_N(1),TT565_RXANTS}, RIG_FRNG_END, }, .tx_range_list1 = { /* FRQ_RNG_HF(1,TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS), */ {kHz(1790),kHz(2010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(3490),kHz(4075),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(5100),kHz(5450),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(6890),kHz(7430),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(10090),kHz(10160),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(13990),kHz(15010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(18058),kHz(18178),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(20990),kHz(21460),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(24880),kHz(25000),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(27990),kHz(29710),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, RIG_FRNG_END, }, .rx_range_list2 = { /* FRQ_RNG_HF(2,TT565_RXMODES, -1,-1,RIG_VFO_N(0),TT565_RXANTS), {MHz(5.25),MHz(5.40),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, */ {kHz(1790),kHz(2010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(3490),kHz(4075),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(5100),kHz(5450),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(6890),kHz(7430),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(10090),kHz(10160),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(13990),kHz(15010),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(18058),kHz(18178),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(20990),kHz(21460),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(24880),kHz(25000),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(27990),kHz(29710),TT565_RXMODES,-1,-1,RIG_VFO_N(0),TT565_RXANTS}, {kHz(100),MHz(30),TT565_RXMODES,-1,-1,RIG_VFO_N(1),TT565_RXANTS}, RIG_FRNG_END, }, .tx_range_list2 = { /* FRQ_RNG_HF(2,TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS), {MHz(5.25),MHz(5.40),TT565_MODES,W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, */ {kHz(1790),kHz(2010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(3490),kHz(4075),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(5100),kHz(5450),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(6890),kHz(7430),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(10090),kHz(10160),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(13990),kHz(15010),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(18058),kHz(18178),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(20990),kHz(21460),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(24880),kHz(25000),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, {kHz(27990),kHz(29710),TT565_MODES, W(5),W(100),RIG_VFO_N(0),TT565_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT565_RXMODES,1}, {TT565_RXMODES,10}, {TT565_RXMODES,100}, {TT565_RXMODES,kHz(1)}, {TT565_RXMODES,kHz(10)}, {TT565_RXMODES,kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* 9MHz IF filters: 15kHz, 6kHz, 2.4kHz, 1.0kHz */ /* opt: 1.8kHz, 500Hz, 250Hz */ {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, 100}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, kHz(6)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY, 0}, /* 590 filters */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .priv = (void*)NULL, .rig_init = tt565_init, .rig_cleanup = tt565_cleanup, .rig_open = tt565_open, .rig_close = tt565_close, .set_freq = tt565_set_freq, #if defined(HAVE_PTHREAD) .get_freq = tt565_get_freq_cache, #else .get_freq = tt565_get_freq, #endif .set_vfo = tt565_set_vfo, .get_vfo = tt565_get_vfo, .set_mode = tt565_set_mode, #if defined(HAVE_PTHREAD) .get_mode = tt565_get_mode_cache, #else .get_mode = tt565_get_mode, #endif .set_split_vfo = tt565_set_split_vfo, #if defined(HAVE_PTHREAD) .get_split_vfo = tt565_get_split_vfo_cache, #else .get_split_vfo = tt565_get_split_vfo, #endif .set_level = tt565_set_level, .get_level = tt565_get_level, .set_mem = tt565_set_mem, .get_mem = tt565_get_mem, .set_ptt = tt565_set_ptt, .get_ptt = tt565_get_ptt, .vfo_op = tt565_vfo_op, .set_ts = tt565_set_ts, .get_ts = tt565_get_ts, .set_rit = tt565_set_rit, .get_rit = tt565_get_rit, .set_xit = tt565_set_xit, .get_xit = tt565_get_xit, .reset = tt565_reset, .get_info = tt565_get_info, .send_morse = tt565_send_morse, .wait_morse = rig_wait_morse, .get_func = tt565_get_func, .set_func = tt565_set_func, .get_ant = tt565_get_ant, .set_ant = tt565_set_ant, /* V2 is default. S-Meter cal table may be changed if V1 firmware detected. */ .str_cal = TT565_STR_CAL_V2, }; /* * Eagle TT-599 share the same ability as Orion's */ #define TT599_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\ /* optional */ RIG_MODE_AM|RIG_MODE_FM) #define TT599_RXMODES TT599_MODES #define TT599_FUNCS (RIG_FUNC_ANF) #define TT599_LEVELS (RIG_LEVEL_RAWSTR| \ RIG_LEVEL_SWR|RIG_LEVEL_RFPOWER| \ RIG_LEVEL_NR|RIG_LEVEL_AGC| \ RIG_LEVEL_PREAMP|RIG_LEVEL_ATT) #define TT599_PARMS (RIG_PARM_NONE) #define TT599_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ } #define TT599_ANTS (RIG_ANT_1) #define TT599_RXANTS TT599_ANTS #define TT599_VFO (RIG_VFO_A|RIG_VFO_B) #define TT599_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) /* * Random guess, to be measured. See FAQ at http://hamlib.org */ #define TT599_STR_CAL { 3, { \ { 10., -48. }, /* S1 = min. indication */ \ { 94., 0. }, /* S9 */ \ { 161., 50. }, \ } } /** * \brief tt599 transceiver capabilities. * * All of the Eagle's personality is defined here! * * Protocol is documented in Programmers Reference Manual V1.001 at * http://www.tentec.com/index.php?id=360#down * */ struct rig_caps tt599_caps = { RIG_MODEL(RIG_MODEL_TT599), .model_name = "TT-599 Eagle", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, /* no delay between characters written */ .post_write_delay = 0, /* ms delay between writes DEBUGGING HERE */ .timeout = 2000, /* ms */ .retry = 4, .has_get_func = TT599_FUNCS, .has_set_func = TT599_FUNCS, .has_get_level = TT599_LEVELS|RIG_LEVEL_RF, .has_set_level = RIG_LEVEL_SET(TT599_LEVELS), .has_get_parm = TT599_PARMS, .has_set_parm = TT599_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 12, RIG_DBLST_END }, .max_rit = kHz(0), .max_xit = kHz(0), .max_ifshift = kHz(0), .vfo_ops = TT599_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, TT599_MEM_CAP }, }, .rx_range_list1 = { FRQ_RNG_HF(1,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), FRQ_RNG_6m(1,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), {kHz(500),MHz(30),TT599_RXMODES,-1,-1,RIG_VFO_N(1),TT599_RXANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), FRQ_RNG_6m(1,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { FRQ_RNG_HF(2,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), FRQ_RNG_6m(2,TT599_RXMODES, -1,-1,RIG_VFO_N(0),TT599_RXANTS), {MHz(5.25),MHz(5.40),TT599_RXMODES,-1,-1,RIG_VFO_N(0),TT599_RXANTS}, {kHz(500),MHz(30),TT599_RXMODES,-1,-1,RIG_VFO_N(1),TT599_RXANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), FRQ_RNG_6m(2,TT599_MODES, W(5),W(100),RIG_VFO_N(0),TT599_ANTS), {MHz(5.25),MHz(5.40),TT599_MODES,W(5),W(100),RIG_VFO_N(0),TT599_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT599_RXMODES,1}, {TT599_RXMODES,10}, {TT599_RXMODES,100}, {TT599_RXMODES,kHz(1)}, {TT599_RXMODES,kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* 15kHz, 6kHz, 2.4kHz, 1.0kHz */ /* 9MHz IF filters: 2.4K standard */ /* optional = 300, 600, 1.8k, 6k, 15k */ {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 600}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 300}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, kHz(6)}, {RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB, 0}, /* 127 filters */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .priv = (void*)NULL, .rig_init = tt565_init, .rig_cleanup = tt565_cleanup, .rig_open = tt565_open, .set_freq = tt565_set_freq, .get_freq = tt565_get_freq, .set_vfo = tt565_set_vfo, .get_vfo = tt565_get_vfo, .set_mode = tt565_set_mode, .get_mode = tt565_get_mode, .set_split_vfo = tt565_set_split_vfo, .get_split_vfo = tt565_get_split_vfo, .set_level = tt565_set_level, .get_level = tt565_get_level, .set_mem = tt565_set_mem, .get_mem = tt565_get_mem, .set_ptt = tt565_set_ptt, .get_ptt = tt565_get_ptt, .vfo_op = tt565_vfo_op, .get_info = tt565_get_info, .get_func = tt565_get_func, .set_func = tt565_set_func, .str_cal = TT599_STR_CAL, }; /* * Function definitions below */ /** \brief End of command marker */ #define EOM "\015" /* CR */ /** \brief USB Mode */ #define TT565_USB '0' /** \brief LSB Mode */ #define TT565_LSB '1' /** \brief CW normal Mode */ #define TT565_CW '2' /** \brief CW reverse Mode */ #define TT565_CWR '3' /** \brief AM Mode */ #define TT565_AM '4' /** \brief FM Mode */ #define TT565_FM '5' /** \brief RTTY Mode */ #define TT565_RTTY '6' /** \brief minimum sidetone freq., Hz */ #define TT565_TONE_MIN 300 /** \brief maximum sidetone freq., Hz */ #define TT565_TONE_MAX 1200 /** \brief minimum CW keyer rate, wpm */ #define TT565_CW_MIN 10 /** \brief maximum CW keyer rate, wpm */ #define TT565_CW_MAX 60 /** @} */ hamlib-4.6.2/rigs/tentec/rx320.c0000644000175000017500000001244414752216205013161 00000000000000/* * Hamlib TenTenc backend - RX-320 PC-Radio description * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "tentec.h" #define RX320_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB) /* TODO: LINEOUT */ #define RX320_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_AF|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR|RIG_LEVEL_CWPITCH) #define RX320_VFO (RIG_VFO_A) /* * Modified 11/18/2008, Josh Rovero, KK1D * Calibration via comparison with JRC NRD-525. * Highy non-linear.... */ #define RX320_STR_CAL { 17, { \ { 0, -60 }, \ { 10, -50 }, \ { 20, -40 }, \ { 30, -30 }, \ { 40, -20 }, \ { 50, -15 }, \ { 100, -10 }, \ { 200, -5 }, \ { 225, -3 }, \ { 256, 0 }, \ { 512, 1 }, \ { 768, 3}, \ { 1024, 4 }, \ { 1280, 5 }, \ { 2560, 10 }, \ { 5120, 20 }, \ { 10000, 30 }, \ } } /* * rx320 receiver capabilities. * * protocol is documented at * http://www.tentec.com/rx320prg.zip * * TODO: */ struct rig_caps rx320_caps = { RIG_MODEL(RIG_MODEL_RX320), .model_name = "RX-320", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, /* * Added S-meter read support, Josh Rovero KK1D * Only get_level is for RIG_LEVEL_RAWSTR */ .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RX320_LEVELS, .has_set_level = RIG_LEVEL_SET(RX320_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 10000 } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0 / 64 } }, [LVL_IF] = { .min = { .i = -2000 }, .max = { .i = 2000 }, .step = { .i = 10} }, [LVL_CWPITCH] = { .min = { .i = 0}, .max = { .i = 2000 }, .step = { .i = 100} } }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), RX320_MODES, -1, -1, RX320_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), RX320_MODES, -1, -1, RX320_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX320_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, 300}, {RIG_MODE_CW, 450}, {RIG_MODE_CW, 600}, {RIG_MODE_CW, 750}, {RIG_MODE_CW, 900}, {RIG_MODE_CW, kHz(1.2)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(4.2)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(5.1)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(6)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(8)}, RIG_FLT_END, }, .str_cal = RX320_STR_CAL, .rig_init = tentec_init, .rig_cleanup = tentec_cleanup, .set_freq = tentec_set_freq, .get_freq = tentec_get_freq, .set_mode = tentec_set_mode, .get_mode = tentec_get_mode, .set_level = tentec_set_level, .get_level = tentec_get_level, .get_info = tentec_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/tentec/rx331.c0000644000175000017500000005416114752216205013165 00000000000000/* * Hamlib Tentec backend - RX331 description * Copyright (c) 2010 by Berndt Josef Wulf * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "num_stdio.h" #include "rx331.h" static const struct confparams rx331_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID", "0", RIG_CONF_NUMERIC, { .n = { 0, 99, 1 } } }, { RIG_CONF_END, NULL, } }; #define RX331_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_DSB|\ RIG_MODE_AM|RIG_MODE_AMS) #define RX331_FUNCS (RIG_FUNC_NB) #define RX331_LEVELS (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL| \ RIG_LEVEL_CWPITCH|RIG_LEVEL_AGC| \ RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define RX331_ANTS (RIG_ANT_1) #define RX331_PARMS (RIG_PARM_NONE) #define RX331_VFO (RIG_VFO_A) #define RX331_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) /* TODO: levels.. */ #define RX331_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } static int rx331_init(RIG *rig); static int rx331_cleanup(RIG *rig); static int rx331_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int rx331_get_conf(RIG *rig, hamlib_token_t token, char *val); static int rx331_open(RIG *rig); static int rx331_close(RIG *rig); static int rx331_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int rx331_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int rx331_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int rx331_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int rx331_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int rx331_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int rx331_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static const char *rx331_get_info(RIG *rig); /* * RX331 receiver capabilities. * * Protocol is documented at * http://radio.tentec.com/downloads/receivers/RX331 * * TODO: from/to memory */ struct rig_caps rx331_caps = { RIG_MODEL(RIG_MODEL_RX331), .model_name = "RX-331", .mfg_name = "Ten-Tec", .version = "20200911.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 75, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = RX331_FUNCS, .has_set_func = RX331_FUNCS, .has_get_level = RX331_LEVELS, .has_set_level = RIG_LEVEL_SET(RX331_LEVELS), .has_get_parm = RX331_PARMS, .has_set_parm = RX331_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .vfo_ops = RX331_VFO_OPS, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, RX331_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(0), MHz(30), RX331_MODES, -1, -1, RX331_VFO, RX331_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(0), MHz(30), RX331_MODES, -1, -1, RX331_VFO, RX331_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX331_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RX331_MODES, kHz(3.2)}, {RX331_MODES, Hz(100)}, {RX331_MODES, kHz(16)}, {RX331_MODES, 0}, RIG_FLT_END, }, .priv = (void *)NULL, .cfgparams = rx331_cfg_params, .rig_init = rx331_init, .rig_cleanup = rx331_cleanup, .rig_open = rx331_open, .rig_close = rx331_close, .set_conf = rx331_set_conf, .get_conf = rx331_get_conf, .set_freq = rx331_set_freq, .get_freq = rx331_get_freq, .set_mode = rx331_set_mode, .get_mode = rx331_get_mode, .set_level = rx331_set_level, .get_level = rx331_get_level, .vfo_op = rx331_vfo_op, .get_info = rx331_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #define BUFSZ 128 #define EOM "\015" /* CR */ #define RX331_AM '1' #define RX331_FM '2' #define RX331_CW '3' #define RX331_CW1 '4' #define RX331_ISB '5' #define RX331_LSB '6' #define RX331_USB '7' #define RX331_SAM '8' #define RX331_PREAMP_OFF 0x1 #define RX331_PREAMP_ON 0x2 #define RX331_ATT_OFF 0x1 #define RX331_ATT_ON 0x3 #define RX331_AGC_FAST 0x1 #define RX331_AGC_MEDIUM 0x2 #define RX331_AGC_SLOW 0x3 #define RX331_AGC_PROG 0x4 #define REPORT_FREQ "TF"EOM #define REPORT_MODEFILTER "TDI"EOM #define REPORT_FIRM "V"EOM #define REPORT_STRENGTH "X"EOM #define REPORT_AGC "TM"EOM #define REPORT_ATT "TK"EOM #define REPORT_PREAMP "TK"EOM #define REPORT_RF "TA"EOM #define REPORT_IF "TP"EOM #define REPORT_SQL "TQ"EOM #define REPORT_CWPITCH "TB"EOM #define REPORT_NOTCHF "TN"EOM /* * rx331_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ static int rx331_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int rig_id; int retval; char str[BUFSZ]; char fmt[16]; hamlib_port_t *rp = RIGPORT(rig); const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; rig_flush(rp); num_snprintf(str, BUFSZ, "$%u%s", priv->receiver_id, cmd); retval = write_block(rp, (unsigned char *) str, strlen(str)); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, 1, 0, 1); if (retval < 0) { return retval; } SNPRINTF(fmt, sizeof(fmt) - 1, "%%i%%%ds", BUFSZ); sscanf(data + 1, fmt, &rig_id, data); if (rig_id != priv->receiver_id) { return -RIG_EPROTO; } *data_len = retval; return RIG_OK; } /* * rx331_init: * Basically, it just sets up *priv */ int rx331_init(RIG *rig) { struct rx331_priv_data *priv; STATE(rig)->priv = (struct rx331_priv_data *)calloc(1, sizeof( struct rx331_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct rx331_priv_data)); return RIG_OK; } /* * Tentec generic rx331_cleanup routine * the serial port is closed by the frontend */ int rx331_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int rx331_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: priv->receiver_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } int rx331_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%u", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int rx331_get_conf(RIG *rig, hamlib_token_t token, char *val) { return rx331_get_conf2(rig, token, val, 128); } // cppcheck-suppress constParameterCallback int rx331_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_close */ // cppcheck-suppress constParameterCallback int rx331_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } int rx331_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; int freq_len, retval; char freqbuf[16]; freq_len = num_snprintf(freqbuf, sizeof(freqbuf), "$%uF%.6f" EOM, priv->receiver_id, freq / 1e6); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, freq_len); return retval; } /* * rx331_get_freq * Assumes rig!=NULL, freq!=NULL */ int rx331_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[BUFSZ]; int buf_len; int retval; double f; retval = rx331_transaction(rig, REPORT_FREQ, strlen(REPORT_FREQ), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 2 || buf[0] != 'F' || num_sscanf(buf + 1, "%lf", &f) != 1) { return -RIG_EPROTO; } *freq = f * 1e6; return RIG_OK; } /* * rx331_set_mode * Assumes rig!=NULL */ int rx331_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; char dmode; int mdbuf_len, retval; char mdbuf[32]; switch (mode) { case RIG_MODE_USB: dmode = RX331_USB; break; case RIG_MODE_LSB: dmode = RX331_LSB; break; case RIG_MODE_CW: dmode = RX331_CW; break; case RIG_MODE_FM: dmode = RX331_FM; break; case RIG_MODE_AM: dmode = RX331_AM; break; case RIG_MODE_AMS: dmode = RX331_SAM; break; case RIG_MODE_DSB: dmode = RX331_ISB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } /* * Set DETECTION MODE and IF FILTER */ mdbuf_len = num_snprintf(mdbuf, sizeof(mdbuf), "$%uD%cI%.02f" EOM, priv->receiver_id, dmode, (float)width / 1e3); } else { /* * Set DETECTION MODE */ mdbuf_len = num_snprintf(mdbuf, sizeof(mdbuf), "$%uD%c" EOM, priv->receiver_id, dmode); } retval = write_block(RIGPORT(rig), (unsigned char *) mdbuf, mdbuf_len); return retval; } /* * rx331_get_mode * Assumes rig!=NULL, mode!=NULL */ int rx331_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[BUFSZ]; int buf_len; int retval; double f; retval = rx331_transaction(rig, REPORT_MODEFILTER, strlen(REPORT_MODEFILTER), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 4 || buf[0] != 'D' || buf[2] != 'I') { return -RIG_EPROTO; } switch (buf[1]) { case RX331_USB: *mode = RIG_MODE_USB; break; case RX331_LSB: *mode = RIG_MODE_LSB; break; case RX331_CW1: case RX331_CW: *mode = RIG_MODE_CW; break; case RX331_FM: *mode = RIG_MODE_FM; break; case RX331_AM: *mode = RIG_MODE_AM; break; case RX331_SAM: *mode = RIG_MODE_AMS; break; case RX331_ISB: *mode = RIG_MODE_DSB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode '%c'\n", __func__, buf[1]); return -RIG_EPROTO; } if (num_sscanf(buf + 3, "%lf", &f) != 1) { return -RIG_EPROTO; } *width = f * 1e3; return RIG_OK; } /* * rx331_set_level * Assumes rig!=NULL * cannot support PREAMP and ATT both at same time (make sense though) */ int rx331_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { const struct rx331_priv_data *priv = (struct rx331_priv_data *)STATE(rig)->priv; int retval = RIG_OK; char cmdbuf[32]; switch (level) { case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uK%i" EOM, priv->receiver_id, val.i ? RX331_ATT_ON : RX331_ATT_OFF); break; case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uK%i" EOM, priv->receiver_id, val.i ? RX331_PREAMP_ON : RX331_PREAMP_OFF); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: val.i = RX331_AGC_FAST; break; case RIG_AGC_MEDIUM: val.i = RX331_AGC_MEDIUM; break; case RIG_AGC_SLOW: val.i = RX331_AGC_SLOW; break; case RIG_AGC_USER: val.i = RX331_AGC_PROG; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %d\n", __func__, val.i); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uM%i" EOM, priv->receiver_id, val.i); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uA%d" EOM, priv->receiver_id, 120 - (int)(val.f * 120)); break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "$%uQ%d" EOM, priv->receiver_id, 120 - (int)(val.f * 120)); break; case RIG_LEVEL_NOTCHF: num_snprintf(cmdbuf, sizeof(cmdbuf), "$%uN%f" EOM, priv->receiver_id, ((float)val.i) / 1e3); break; case RIG_LEVEL_IF: num_snprintf(cmdbuf, sizeof(cmdbuf), "$%uP%f" EOM, priv->receiver_id, ((float)val.i) / 1e3); break; case RIG_LEVEL_CWPITCH: /* only in CW mode */ num_snprintf(cmdbuf, sizeof(cmdbuf), "$%uB%f" EOM, priv->receiver_id, ((float)val.i) / 1e3); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf)); return retval; } /* * rx331_get_level * Assumes rig!=NULL, val!=NULL */ int rx331_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; double f; char lvlbuf[BUFSZ]; switch (level) { case RIG_LEVEL_STRENGTH: retval = rx331_transaction(rig, REPORT_STRENGTH, strlen(REPORT_STRENGTH), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 2 || lvlbuf[0] != 'X') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } // Range is 0-120 covering the 120dB range of the receiver if (num_sscanf(lvlbuf + 1, "%d", &val->i) != 1) { return -RIG_EPROTO; } val->i = val->i - 120; break; case RIG_LEVEL_AGC: retval = rx331_transaction(rig, REPORT_AGC, strlen(REPORT_AGC), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'M') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } switch (atoi(lvlbuf + 1)) { case RX331_AGC_FAST: val->i = RIG_AGC_FAST; break; case RX331_AGC_MEDIUM: val->i = RIG_AGC_MEDIUM; break; case RX331_AGC_SLOW: val->i = RIG_AGC_SLOW; break; case RX331_AGC_PROG: val->i = RIG_AGC_USER; break; default: rig_debug(RIG_DEBUG_ERR, "%s:Unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } break; case RIG_LEVEL_ATT: retval = rx331_transaction(rig, REPORT_ATT, strlen(REPORT_ATT), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'K') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%i", &val->i) != 1) { return -RIG_EPROTO; } val->i = (val->i == RX331_ATT_ON); break; case RIG_LEVEL_PREAMP: retval = rx331_transaction(rig, REPORT_PREAMP, strlen(REPORT_PREAMP), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'K') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%i", &val->i) != 1) { return -RIG_EPROTO; } val->i = (val->i == RX331_PREAMP_ON); break; case RIG_LEVEL_RF: retval = rx331_transaction(rig, REPORT_RF, strlen(REPORT_RF), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'A') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%d", &val->i) != 1) { return -RIG_EPROTO; } f = val->i / 120.0; val->f = 1.0 - f; break; case RIG_LEVEL_IF: retval = rx331_transaction(rig, REPORT_IF, strlen(REPORT_IF), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'P') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%f", &val->f) != 1) { return -RIG_EPROTO; } f = val->f * 1000.0; val->i = (int)f; break; case RIG_LEVEL_SQL: retval = rx331_transaction(rig, REPORT_SQL, strlen(REPORT_SQL), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'Q') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%d", &val->i) != 1) { return -RIG_EPROTO; } f = val->i / 120.0; val->f = 1.0 - f; break; case RIG_LEVEL_CWPITCH: retval = rx331_transaction(rig, REPORT_CWPITCH, strlen(REPORT_CWPITCH), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'B') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%f", &val->f) != 1) { return -RIG_EPROTO; } f = val->f * 1000.0; val->i = f; break; case RIG_LEVEL_NOTCHF: retval = rx331_transaction(rig, REPORT_NOTCHF, strlen(REPORT_NOTCHF), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 0 || lvlbuf[0] != 'N') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } if (num_sscanf(lvlbuf + 1, "%f", &val->f) != 1) { return -RIG_EPROTO; } f = val->f * 1000.0; val->i = f; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * rx331_vfo_op * Assumes rig!=NULL */ int rx331_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { return -RIG_ENIMPL; } /* * rx331_get_info * Assumes rig!=NULL */ const char *rx331_get_info(RIG *rig) { static char buf[BUFSZ]; /* FIXME: reentrancy */ int firmware_len = sizeof(buf), retval; retval = rx331_transaction(rig, REPORT_FIRM, strlen(REPORT_FIRM), buf, &firmware_len); if ((retval != RIG_OK) || (firmware_len > 10)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } return buf; } hamlib-4.6.2/rigs/tentec/paragon.c0000644000175000017500000003666514752216205013745 00000000000000/* * Hamlib TenTenc backend - TT-585 Paragon description * Copyright (c) 2003-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "bandplan.h" #include "iofunc.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" struct tt585_priv_data { unsigned char status_data[30]; struct timeval status_tv; int channel_num; }; /* RIG_MODE_FM is optional */ #define TT585_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define TT585_RXMODES (TT585_MODES|RIG_MODE_AM) #define TT585_FUNCS (RIG_FUNC_NONE) #define TT585_LEVELS (RIG_LEVEL_NONE) #define TT585_ANTS (RIG_ANT_1) #define TT585_PARMS (RIG_PARM_ANN|RIG_PARM_TIME) #define TT585_VFO (RIG_VFO_A|RIG_VFO_B) #define TT585_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|\ RIG_OP_CPY|RIG_OP_MCL|RIG_OP_TOGGLE|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TUNE) #define TT585_CACHE_TIMEOUT 500 /* ms */ /* * Mem caps to be checked, maybe more like split.. */ #define TT585_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .channel_desc = 1, \ } static int tt585_init(RIG *rig); static int tt585_cleanup(RIG *rig); static int tt585_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt585_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt585_set_vfo(RIG *rig, vfo_t vfo); static int tt585_get_vfo(RIG *rig, vfo_t *vfo); static int tt585_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); static int tt585_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo); static int tt585_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt585_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tt585_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int tt585_set_parm(RIG *rig, setting_t parm, value_t val); static int tt585_set_mem(RIG *rig, vfo_t vfo, int ch); static int tt585_get_mem(RIG *rig, vfo_t vfo, int *ch); static int tt585_get_status_data(RIG *rig); /* * tt585 transceiver capabilities, * with the optional model 258 RS232 Interface board. */ struct rig_caps tt585_caps = { RIG_MODEL(RIG_MODEL_TT585), .model_name = "TT-585 Paragon", .mfg_name = "Ten-Tec", .version = "20200305.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 100, /* instead of 20 ms */ .post_write_delay = 200, /* FOR T=1 TO 200 on a 4.77 MHz PC */ .timeout = 1000, .retry = 0, .has_get_func = TT585_FUNCS, .has_set_func = TT585_FUNCS, .has_get_level = TT585_LEVELS, .has_set_level = RIG_LEVEL_SET(TT585_LEVELS), .has_get_parm = TT585_PARMS, .has_set_parm = TT585_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = TT585_VFO_OPS, .chan_list = { { 0, 61, RIG_MTYPE_MEM, TT585_MEM_CAP }, }, .rx_range_list1 = { {kHz(100), MHz(30) - 10, TT585_RXMODES, -1, -1, TT585_VFO, TT585_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT585_MODES, W(5), W(100), TT585_VFO, TT585_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30) - 10, TT585_RXMODES, -1, -1, TT585_VFO, TT585_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT585_MODES, W(5), W(100), TT585_VFO, TT585_ANTS), {MHz(5.25), MHz(5.40), TT585_MODES, W(5), W(100), TT585_VFO, TT585_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT585_RXMODES, 10}, {TT585_RXMODES, 20}, {TT585_RXMODES, 50}, {TT585_RXMODES, 100}, {TT585_RXMODES, 500}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, kHz(1.8)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, 500}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, 250}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .priv = (void *) NULL, .rig_init = tt585_init, .rig_cleanup = tt585_cleanup, .set_freq = tt585_set_freq, .get_freq = tt585_get_freq, .set_vfo = tt585_set_vfo, .get_vfo = tt585_get_vfo, .set_split_vfo = tt585_set_split_vfo, .get_split_vfo = tt585_get_split_vfo, .vfo_op = tt585_vfo_op, .set_mode = tt585_set_mode, .get_mode = tt585_get_mode, .set_parm = tt585_set_parm, .set_mem = tt585_set_mem, .get_mem = tt585_get_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * tt585_init: * Basically, it just sets up *priv */ int tt585_init(RIG *rig) { struct tt585_priv_data *priv; STATE(rig)->priv = (struct tt585_priv_data *) calloc(1, sizeof( struct tt585_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt585_priv_data)); return RIG_OK; } int tt585_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); STATE(rig)->priv = NULL; } return RIG_OK; } int tt585_get_vfo(RIG *rig, vfo_t *vfo) { struct tt585_priv_data *priv = (struct tt585_priv_data *) STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } *vfo = (priv->status_data[9] & 0x08) ? RIG_VFO_A : RIG_VFO_B; return RIG_OK; } /* * tt585_set_vfo * Assumes rig!=NULL */ int tt585_set_vfo(RIG *rig, vfo_t vfo) { vfo_t curr_vfo; int ret; ret = tt585_get_vfo(rig, &curr_vfo); if (ret < 0) { return ret; } if (vfo == curr_vfo || vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) { return RIG_OK; } /* toggle VFOs */ return write_block(RIGPORT(rig), (unsigned char *) "F", 1); } int tt585_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { split_t curr_split; vfo_t curr_txvfo; int ret; ret = tt585_get_split_vfo(rig, vfo, &curr_split, &curr_txvfo); if (ret < 0) { return ret; } if (split == curr_split) { return RIG_OK; } /* toggle split mode */ return write_block(RIGPORT(rig), (unsigned char *) "J", 1); } int tt585_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } *split = (priv->status_data[9] & 0x02) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; *txvfo = RIG_VFO_B; return RIG_OK; } /* * tt585_get_freq * Assumes rig!=NULL, freq!=NULL */ int tt585_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; int ret; unsigned char *p; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } p = priv->status_data; *freq = ((((((p[0] * 10 + p[1]) * 10 + p[2]) * 10 + p[3]) * 10 + p[4]) * 10 + p[5]) * 10 + p[6]) * 10; return RIG_OK; } /* * tt585_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tt585_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; #define FREQBUFSZ 16 char buf[FREQBUFSZ], *p; num_snprintf(buf, FREQBUFSZ - 1, "%.5f@", (double)freq / MHz(1)); buf[FREQBUFSZ - 1] = '\0'; /* replace decimal point with W */ p = strchr(buf, '.'); *p = 'W'; rig_force_cache_timeout(&priv->status_tv); return write_block(RIGPORT(rig), (unsigned char *) buf, strlen(buf)); } /* * tt585_get_mode * Assumes rig!=NULL, mode!=NULL */ int tt585_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } if (priv->status_data[7] & 0x02) { *mode = RIG_MODE_CW; } else if (priv->status_data[7] & 0x04) { *mode = RIG_MODE_USB; } else if (priv->status_data[7] & 0x08) { *mode = RIG_MODE_LSB; } else if (priv->status_data[7] & 0x10) { *mode = RIG_MODE_AM; } else if (priv->status_data[7] & 0x20) { *mode = RIG_MODE_FM; } else if (priv->status_data[7] & 0x40) { *mode = RIG_MODE_RTTY; } else { *mode = RIG_MODE_NONE; } if (priv->status_data[8] & 0x08) { *width = 250; } else if (priv->status_data[8] & 0x10) { *width = 500; } else if (priv->status_data[8] & 0x20) { *width = 1800; } else if (priv->status_data[8] & 0x40) { *width = 2400; } else if (priv->status_data[8] & 0x80) { *width = 6000; } else { *width = 0; } return RIG_OK; } /* * tt585_set_mode * Assumes rig!=NULL */ int tt585_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; const char *mcmd, *wcmd; int ret; hamlib_port_t *rp = RIGPORT(rig); switch (mode) { case RIG_MODE_LSB: mcmd = "N"; break; case RIG_MODE_USB: mcmd = "O"; break; case RIG_MODE_CW: mcmd = "P"; break; case RIG_MODE_FM: mcmd = "L"; break; case RIG_MODE_AM: mcmd = "M"; break; case RIG_MODE_RTTY: mcmd = "XP"; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } rig_force_cache_timeout(&priv->status_tv); ret = write_block(rp, (unsigned char *) mcmd, strlen(mcmd)); if (ret < 0) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } if (width <= 250) { wcmd = "V"; } else if (width <= 500) { wcmd = "U"; } else if (width <= 1800) { wcmd = "T"; } else if (width <= 2400) { wcmd = "S"; } else /* 6000 (or FM?) */ { wcmd = "R"; } return write_block(rp, (unsigned char *) wcmd, strlen(mcmd)); } int tt585_set_mem(RIG *rig, vfo_t vfo, int ch) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; char buf[16]; if (ch < 0 || ch > 61) { return -RIG_EINVAL; } priv->channel_num = ch; /* does it work without a command after the channel number? */ SNPRINTF(buf, sizeof(buf), ":%02d", ch); return write_block(RIGPORT(rig), (unsigned char *) buf, strlen(buf)); } int tt585_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct tt585_priv_data *priv = (struct tt585_priv_data *) STATE(rig)->priv; int ret; ret = tt585_get_status_data(rig); if (ret < 0) { return ret; } /* 63 means not in MEM mode, 0xfe means mem full */ if (priv->status_data[11] > 61) { return -RIG_ERJCTED; } *ch = priv->status_data[11]; return RIG_OK; } /* * private helper function. Retrieves status data from rig. * using buffer indicated in *priv struct. * * need to use this when doing tt585_get_* stuff */ int tt585_get_status_data(RIG *rig) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; hamlib_port_t *rigport; int ret; rigport = RIGPORT(rig); if (!rig_check_cache_timeout(&priv->status_tv, TT585_CACHE_TIMEOUT)) { return RIG_OK; } rig_flush(rigport); /* send STATUS command to fetch data*/ ret = write_block(rigport, (unsigned char *) "\\", 1); if (ret < 0) { return ret; } ret = read_block(rigport, (unsigned char *)(char *) priv->status_data, sizeof(priv->status_data)); if (ret < 0) { return ret; } /* update cache date */ gettimeofday(&priv->status_tv, NULL); return RIG_OK; } int tt585_set_parm(RIG *rig, setting_t parm, value_t val) { int ret; switch (parm) { case RIG_PARM_ANN: /* FIXME: > is a toggle command only */ ret = write_block(RIGPORT(rig), (unsigned char *) ">", 1); if (ret < 0) { return ret; } /* exact additional delay TBC */ sleep(1); return RIG_OK; /* TODO: RIG_PARM_TIME */ default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * tt585_vfo_op * Assumes rig!=NULL */ int tt585_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct tt585_priv_data *priv = (struct tt585_priv_data *)STATE(rig)->priv; const char *cmd; char buf[16]; switch (op) { case RIG_OP_TUNE: cmd = "Q"; break; case RIG_OP_MCL: SNPRINTF(buf, sizeof(buf), ":%02dXD", priv->channel_num); cmd = buf; break; case RIG_OP_TO_VFO: SNPRINTF(buf, sizeof(buf), ":%02d", priv->channel_num); cmd = buf; break; case RIG_OP_FROM_VFO: SNPRINTF(buf, sizeof(buf), "<%02d", priv->channel_num); cmd = buf; break; case RIG_OP_CPY: cmd = "E"; break; case RIG_OP_TOGGLE: cmd = "F"; break; case RIG_OP_DOWN: cmd = "]"; break; case RIG_OP_UP: cmd = "["; break; case RIG_OP_BAND_DOWN: cmd = "XY"; break; case RIG_OP_BAND_UP: cmd = "XZ"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } rig_force_cache_timeout(&priv->status_tv); return write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); } hamlib-4.6.2/rigs/tentec/jupiter.c0000644000175000017500000010051614752216205013763 00000000000000/* * Hamlib TenTenc backend - TT-538 description * Copyright (c) 2003-2012 by Stephane Fillod, Martin Ewing * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Extended and corrected by Martin Ewing AA6E 2/2012 * This backend tested with firmware v 1.330. * Firmware version >=1.18 is probably required. * Reference: Jupiter Model 538 Programmer's Reference Guide Rev. 1.1 * v 0.7 - 2012-07-15 - correct RAWSTR processing, add cal table for RIG_LEVEL_STRENGTH * 2012-08-02 - Add support for "IF" (passband tuning), NB, NR, ANF * 2012-12-04 - Revise reported bandwidth code */ /* to do: * implement dual VFO & split capability */ #include #include #include #include #include "tentec2.h" #include "tentec.h" #include "bandplan.h" struct tt538_priv_data { int ch; /* mem */ vfo_t vfo_curr; }; #define TT538_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM) #define TT538_RXMODES (TT538_MODES) #define TT538_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_NB) #define TT538_LEVELS (RIG_LEVEL_RAWSTR| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_AF|RIG_LEVEL_AGC| \ RIG_LEVEL_SWR|RIG_LEVEL_ATT) #define TT538_LEVELS_SET (RIG_LEVEL_SQL|RIG_LEVEL_RF| \ RIG_LEVEL_AF|RIG_LEVEL_IF| \ RIG_LEVEL_AGC|RIG_LEVEL_ATT) #define TT538_ANTS (RIG_ANT_1) #define TT538_PARMS (RIG_PARM_NONE) #define TT538_VFO (RIG_VFO_A|RIG_VFO_B) #define TT538_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) #define TT538_AM '0' #define TT538_USB '1' #define TT538_LSB '2' #define TT538_CW '3' #define TT538_FM '4' #define EOM "\015" /* CR */ /* Jupiter's RAWSTR is S-meter reading in S value + fractional S value, times 256 */ #define TT538_STR_CAL { 18, { \ { 256, -48 }, \ { 512, -42 }, \ { 768, -36 }, \ { 1024, -30 }, \ { 1280, -24 }, \ { 1536, -18 }, \ { 1792, -12 }, \ { 2048, -6 }, \ { 2304, 0 }, \ { 2560, 6 }, \ { 2816, 12 }, \ { 3072, 18 }, \ { 3328, 24 }, \ { 3584, 30 }, \ { 3840, 36 }, \ { 4096, 42 }, \ { 4352, 48 }, \ { 4608, 54 }, \ } } static int tt538_init(RIG *rig); static int tt538_reset(RIG *rig, reset_t reset); static int tt538_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt538_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt538_set_vfo(RIG *rig, vfo_t vfo); static int tt538_get_vfo(RIG *rig, vfo_t *vfo); static int tt538_set_split_vfo(RIG *rig, vfo_t vfo, split_t, vfo_t tx_vfo); static int tt538_get_split_vfo(RIG *rig, vfo_t vfo, split_t *, vfo_t *tx_vfo); static int tt538_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt538_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static char which_vfo(const RIG *rig, vfo_t vfo); static int tt538_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tt538_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tt538_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int tt538_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); /* * tt538 transceiver capabilities. * * Protocol is documented at * http://www.rfsquared.com/ */ struct rig_caps tt538_caps = { RIG_MODEL(RIG_MODEL_TT538), .model_name = "TT-538 Jupiter", .mfg_name = "Ten-Tec", .version = "20240913.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .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 = 400, .retry = 3, .has_get_func = TT538_FUNCS, .has_set_func = TT538_FUNCS, .has_get_level = TT538_LEVELS, .has_set_level = TT538_LEVELS_SET, .has_get_parm = TT538_PARMS, .has_set_parm = TT538_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 127, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(100), MHz(30), TT538_RXMODES, -1, -1, TT538_VFO, TT538_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT538_MODES, W(5), W(100), TT538_VFO, TT538_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TT538_RXMODES, -1, -1, TT538_VFO, TT538_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT538_MODES, W(5), W(100), TT538_VFO, TT538_ANTS), {MHz(5.25), MHz(5.40), TT538_MODES, W(5), W(100), TT538_VFO, TT538_ANTS}, RIG_FRNG_END, }, .tuning_steps = { {TT538_RXMODES, 1}, {TT538_RXMODES, 10}, {TT538_RXMODES, 100}, {TT538_RXMODES, kHz(1)}, {TT538_RXMODES, kHz(10)}, {TT538_RXMODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, 300}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, kHz(8)}, {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_AM, 0}, /* 34 filters */ {RIG_MODE_FM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .priv = (void *) NULL, .rig_init = tt538_init, .set_freq = tt538_set_freq, .get_freq = tt538_get_freq, .set_vfo = tt538_set_vfo, .get_vfo = tt538_get_vfo, .set_mode = tt538_set_mode, .get_mode = tt538_get_mode, .get_level = tt538_get_level, .set_level = tt538_set_level, .get_func = tt538_get_func, .set_func = tt538_set_func, .set_split_vfo = tt538_set_split_vfo, .get_split_vfo = tt538_get_split_vfo, .set_ptt = tt538_set_ptt, .reset = tt538_reset, .get_info = tentec2_get_info, .str_cal = TT538_STR_CAL, // This signals front-end support of level STRENGTH .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* Filter table for 538 receiver support. */ static int tt538_rxFilter[] = { 8000, 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 260, 225, 180, 165, 150 }; #define JUPITER_TT538_RXFILTERS ( sizeof(tt538_rxFilter) / sizeof(tt538_rxFilter[0]) ) /* * Function definitions below */ /* I frequently see the Jupiter and my laptop get out of sync. A response from the 538 isn't seen by the laptop. A few "XX"s sometimes get things going again, hence this hack, er, function. */ static int tt538_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { char reset_buf[32]; int i, reset_len, retval; retval = tentec_transaction(rig, cmd, cmd_len, data, data_len); if (data == NULL || (data != NULL && data_len > 0)) { return retval; } /* Try a few times to do a DSP reset to resync things. */ for (i = 0; i < 3; i++) { reset_len = 32; retval = tentec_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { continue; /* Try again. This 1 didn't work. */ } if (strstr(reset_buf, "RADIO START")) { break; /* DSP reset successful! */ } } /* Try real command one last time... */ return tentec_transaction(rig, cmd, cmd_len, data, data_len); } /* * tt538_init: * Basically, it just sets up *priv */ int tt538_init(RIG *rig) { struct tt538_priv_data *priv; STATE(rig)->priv = (struct tt538_priv_data *) calloc(1, sizeof( struct tt538_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt538_priv_data)); /* * set arbitrary initial status */ priv->ch = 0; priv->vfo_curr = RIG_VFO_A; return RIG_OK; } static char which_vfo(const RIG *rig, vfo_t vfo) { const struct tt538_priv_data *priv = (struct tt538_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: return 'A'; case RIG_VFO_B: return 'B'; case RIG_VFO_NONE: return 'N'; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } } int tt538_get_vfo(RIG *rig, vfo_t *vfo) { const struct tt538_priv_data *priv = (struct tt538_priv_data *) STATE( rig)->priv; *vfo = priv->vfo_curr; return RIG_OK; } /* * tt538_set_vfo * Assumes rig!=NULL */ int tt538_set_vfo(RIG *rig, vfo_t vfo) { struct tt538_priv_data *priv = (struct tt538_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { return RIG_OK; } priv->vfo_curr = vfo; return RIG_OK; } /* * Software restart */ int tt538_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; reset_len = 32; retval = tt538_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "RADIO START")) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, reset_buf); return -RIG_EPROTO; } return RIG_OK; } /* * tt538_get_freq * Assumes rig!=NULL, freq!=NULL */ int tt538_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char curVfo; int resp_len, retval; unsigned char cmdbuf[16], respbuf[32]; SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?%c" EOM, which_vfo(rig, vfo)); resp_len = 7; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } curVfo = which_vfo(rig, vfo); if (respbuf[0] != curVfo) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } if (resp_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected length '%d'\n", __func__, resp_len); return -RIG_EPROTO; } *freq = (respbuf[1] << 24) + (respbuf[2] << 16) + (respbuf[3] << 8) + respbuf[4]; return RIG_OK; } /* * tt538_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL * assumes priv->mode in AM,CW,LSB or USB. */ int tt538_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char bytes[4]; unsigned char cmdbuf[16]; int retval = -RIG_EINTERNAL; int retry = STATE(rig)->retry; freq_t freqchk = 0; /* Freq is 4 bytes long, MSB sent first. */ bytes[3] = ((unsigned int) freq >> 24) & 0xff; bytes[2] = ((unsigned int) freq >> 16) & 0xff; bytes[1] = ((unsigned int) freq >> 8) & 0xff; bytes[0] = ((unsigned int) freq) & 0xff; do { SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*%c%c%c%c%c" EOM, which_vfo(rig, vfo), bytes[3], bytes[2], bytes[1], bytes[0]); retval = tt538_transaction(rig, (char *) cmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { continue; } retval = tt538_get_freq(rig, vfo, &freqchk); if (retval != RIG_OK) { return retval; } } while (freq != freqchk && --retry >= 0); return retval; } /* * tt538_set_split_vfo * assumes rig!=NULL */ int tt538_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { return tentec_transaction(rig, RIG_SPLIT_ON == split ? "*O1\r" : "*O0\r", 4, NULL, NULL); } /* * tt538_get_split_vfo * assumes rig!=NULL */ int tt538_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval, ret_len; char buf[4] = "?O\r"; ret_len = 4; retval = tentec_transaction(rig, buf, 3, buf, &ret_len); if (retval != RIG_OK) { return retval; } if (ret_len != 3) { return -RIG_EPROTO; } *split = buf[1] == '0' ? RIG_SPLIT_OFF : RIG_SPLIT_ON; *tx_vfo = RIG_VFO_A; return RIG_OK; } /* * tt538_get_mode * Assumes rig!=NULL, mode!=NULL */ int tt538_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int resp_len, retval; int rpb; unsigned char cmdbuf[16], respbuf[32]; char ttmode; /* Find bandwidth according to response from table. */ const static int pbwidth[39] = { 8000, 6000, 5700, 5400, 5100, 4800, 4500, 4200, 3900, 3600, 3300, 3000, 2850, 2700, 2550, 2400, 2250, 2100, 1950, 1800, 1650, 1500, 1350, 1200, 1050, 900, 750, 675, 600, 525, 450, 375, 330, 300, 260, 225, 180, 165, 150 }; /* Query mode */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 5; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M' || resp_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (which_vfo(rig, vfo)) { case 'A': ttmode = respbuf[1]; break; case 'B': ttmode = respbuf[2]; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; break; } switch (ttmode) { case TT538_AM: *mode = RIG_MODE_AM; break; case TT538_USB: *mode = RIG_MODE_USB; break; case TT538_LSB: *mode = RIG_MODE_LSB; break; case TT538_CW: *mode = RIG_MODE_CW; break; case TT538_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, ttmode); return -RIG_EPROTO; } /* Query passband width (filter) */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?W" EOM); resp_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'W' && resp_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } rpb = respbuf[1]; if (rpb <= 38) { *width = pbwidth[rpb]; } else { rig_debug(RIG_DEBUG_ERR, "%s: unexpected bandwidth '%c'\n", __func__, respbuf[1]); return -RIG_EPROTO; } return RIG_OK; } /* Find rx filter index of bandwidth the same or larger as requested. */ static int tt538_filter_number(int width) { int i; for (i = JUPITER_TT538_RXFILTERS - 1; i >= 0; i--) { if (width <= tt538_rxFilter[i]) { return i; } } return 0; /* Widest filter, 8 kHz. */ } /* * tt538_set_mode * Assumes rig!=NULL */ int tt538_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmdbuf[32], respbuf[32], ttmode; int resp_len, retval; const struct tt538_priv_data *priv = (struct tt538_priv_data *) STATE( rig)->priv; /* Query mode for both VFOs. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 5; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M' || resp_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (mode) { case RIG_MODE_USB: ttmode = TT538_USB; break; case RIG_MODE_LSB: ttmode = TT538_LSB; break; case RIG_MODE_CW: ttmode = TT538_CW; break; case RIG_MODE_AM: ttmode = TT538_AM; break; case RIG_MODE_FM: ttmode = TT538_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* Set mode for both VFOs. */ if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, ttmode, respbuf[2]); break; case RIG_VFO_B: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, respbuf[1], ttmode); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } /* Set rx filter bandwidth. */ width = tt538_filter_number((int) width); SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*W%c" EOM, (unsigned char) width); return tt538_transaction(rig, (char *) cmdbuf, 4, NULL, NULL); return RIG_OK; } /* * tt538_set_ptt * Assumes rig!=NULL */ int tt538_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { return tentec_transaction(rig, ptt == RIG_PTT_ON ? "Q1\r" : "Q0\r", 3, NULL, NULL); } /* * tt538_get_level * Assumes rig!=NULL, val!=NULL */ int tt538_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { float fwd, refl; float ratio, swr; int retval, lvl_len; unsigned char cmdbuf[16], lvlbuf[32]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_SWR: /* Get forward power. */ lvl_len = 4; retval = tt538_transaction(rig, "?F" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'F' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } fwd = (float) lvlbuf[1]; /* Get reflected power. */ lvl_len = 4; retval = tt538_transaction(rig, "?R" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'R' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } refl = (float) lvlbuf[1]; ratio = refl / fwd; if (ratio > 0.9) { swr = 10.0; /* practical maximum SWR, avoid div by 0 */ } else { swr = 1.0 / (1.0 - ratio); } val->f = swr; break; case RIG_LEVEL_RAWSTR: lvl_len = 7; retval = tt538_transaction(rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'S' || lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } /* Jupiter returns actual S value in 1/256s of an S unit, in ascii hex digits. We convert those digits to binary and return that integer (S units * 256) */ { char hex[5]; int i; unsigned int ival; for (i = 0; i < 4; i++) { hex[i] = lvlbuf[i + 1]; } hex[4] = '\0'; sscanf(hex, "%4x", &ival); val->i = ival; /* S-units+fract * 256 */ } break; case RIG_LEVEL_AGC: /* Read rig's AGC level setting. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?G" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'G' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } switch (lvlbuf[1] & 0xf) { /* Prog. Man. claims Jupiter returns '1', '2', and '3', but not so if AGC was set by program! So look at 2nd hex digit only. */ case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; default: return -RIG_EPROTO; } break; case RIG_LEVEL_AF: /* Volume returned as single byte. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?U" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'U' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = (float) lvlbuf[1] / 127; break; case RIG_LEVEL_RF: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?I" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } /* Note: Any RF gain over "50%" on front panel returns 1.00 (firmware 1.281) on test rig. However RF set level seems OK. Firmware problem? -AA6E */ val->f = 1 - (float) lvlbuf[1] / 0xff; break; case RIG_LEVEL_IF: /* IF passband tuning, Hz */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?P" EOM); lvl_len = 5; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, & lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'P' || lvl_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = (int) lvlbuf[1] * 256 + (int) lvlbuf[2]; break; case RIG_LEVEL_ATT: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?J" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'J' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = lvlbuf[1]; break; case RIG_LEVEL_SQL: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?H" EOM); lvl_len = 4; retval = tt538_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'H' || lvl_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = ((float) lvlbuf[1] / 127); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt538_set_level * Assumes rig!=NULL, val!=NULL */ int tt538_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cc, cmdbuf[32], c1, c2; int retval; int len; switch (level) { case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: cc = '3'; break; case RIG_AGC_MEDIUM: cc = '2'; break; case RIG_AGC_SLOW: cc = '1'; break; default: cc = '2'; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*G%c" EOM, cc); len = 4; break; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*U%c" EOM, (int)(127 * val.f)); len = 4; break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*I%c" EOM, (int)(127 * val.f)); len = 4; break; case RIG_LEVEL_IF: c1 = val.i >> 8; c2 = val.i & 0xff; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*P%c%c" EOM, c1, c2); len = 5; break; case RIG_LEVEL_ATT: if (val.i) { cc = '1'; } else { cc = '0'; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*J%c" EOM, cc); len = 4; break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*H%c" EOM, (int)(127 * val.f)); len = 4; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = tt538_transaction(rig, cmdbuf, len, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } int tt538_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char frespbuf[32]; int retval, fresplen; switch (func) { case RIG_FUNC_NR: /* ?K gets nb(0-7), an, nr according to prog ref guide, but it's really nb, nr, an */ fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = frespbuf[ 2 ] == 1; return RIG_OK; case RIG_FUNC_ANF: fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = frespbuf[ 3 ] == 1; return RIG_OK; case RIG_FUNC_NB: /* Based on research by AA6E - * Data transferred from rig: * * |__|__|__| (a 3 bit value, 0 - 7 indicating NB "strength" * 4 2 1 * * Apparently the "ON" / "OFF" state of the NB is NOT available for reading. This * state is visible in the Jupiter's menu. Hamlib does not support a "level" for * NB. We only recognize zero (off) or non-zero (on) for this function on read. */ fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = (frespbuf[ 1 ] != 0); /* non-zero value -> "on" */ return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } } int tt538_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char fcmdbuf[32], frespbuf[32]; int retval, fresplen, i; switch (func) { case RIG_FUNC_NB: /* Jupiter combines, nb, nr, and anf in one command, so we need to retrieve them all before changing one of them */ fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5; i++) { fcmdbuf[i + 1] = frespbuf[i]; } fcmdbuf[0] = '*'; fcmdbuf[2] = status ? 5 : 1; /* Based on AA6E research (no thanks to errors in TT Prog Ref Manual!) * The "set" function (*K command) uses a different data format from the ?K get function. * Data transferred to rig: * +--+--+----------NB value (0-7) * v v v +-------NB "on/off" bit * |__|__|__|__| * 8 4 2 1 * The NB on/off bit corresponds to the "Noise Blanker" item in the Jupiter menu. * The value is show in the "NB selection" item in the Jupiter menu. * Note that if all zeroes are sent, the NB does shut off, but the NB value * is unchanged. If you want to change the NB value, the on/off bit must be set. * Because the on/off status cannot (apparently) be read back by software, we will * leave NB always on, but set to zero value when NB "off" is desired. It is not clear * if NB on/off makes a difference if the value is zero. (ver 1330-538 firmware) */ /* send data back, with change */ retval = tt538_transaction(rig, fcmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; break; case RIG_FUNC_NR: fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5; i++) { fcmdbuf[i + 1] = frespbuf[i]; } fcmdbuf[0] = '*'; fcmdbuf[3] = status ? 1 : 0; /* send data back, with change */ retval = tt538_transaction(rig, fcmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; break; case RIG_FUNC_ANF: fresplen = 6; retval = tt538_transaction(rig, "?K" EOM, 3, frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5; i++) { fcmdbuf[i + 1] = frespbuf[i]; } fcmdbuf[0] = '*'; fcmdbuf[4] = status ? 1 : 0; /* send data back, with change */ retval = tt538_transaction(rig, fcmdbuf, 6, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } } hamlib-4.6.2/rigs/tentec/README.tentec0000644000175000017500000000611114752216205014272 00000000000000Jupiter (538) (29 February 2012, AA6E) The Jupiter needs current firmware, at least version 1,18. Earlier firmware apparently had a different command protocol. Most available commands are now implemented, with exception of NB, NR, and AN. Omni VI (563), VI Plus (564) (26 March 2008, AA6E) Note that the Omni uses an Icom-style command interface. The Omni backend lives in the ../icom directory! Omni (hardware) menu selections: The Omni's device address must be set to '04'. The 563 and 564 provide 1200, 2400, 4800, 9600, and 19200 baud rates. Notes on 563 (Omni VI) vs. 564 (Omni VI Plus) Omni VI Plus (Hamlib model 351) backend can be used with the Omni VI, subject to its hardware limitations. Orion (TT 565, 565AT) and Orion II (TT 566, 566AT) (14 February 2008) Improved serial I/O transfer reliability, better error handling V1 and V2 firmware are autorecognized in the tt565_open routine. Version 2.xxx is now the default for Orion. (5 November 2007) The S-meter behavior has changed for Version 2.xxx of firmware for Orion. Orion II presumably also has a different calibration. We will recalibrate, but it is not clear if Orion and Orion II will produce the same readings. :-( Please send calibration info to me as indicated on the Hamlib FAQ at http://hamlib.sourceforge.net/faq.html . (23 April 2006) These are all covered by the TT565 backend (model 1608). This backend is functioning for basic HF work, although memory, multi-VFO, and antenna selection, etc. are left for the future. All testing to date has been on a model 565AT, running v 1.372 firmware. All reports of success/failure (especially for the Orion 2) are welcome -- Martin, aa6e@arrl.net (26 Feb 2006) tt550 TODO (Ken, N7IPB): Support for multiple VFO's and Memories. The TT550 doesn't really have VFO's or Memories since it's strictly a software controlled radio, but they can easily be simulated in software. I already support a split mode since the TX and RX control is separate. Adding support for VFO-A, VFO-B and memory channels will be done next. The optional encoder with keypad is supported for changing frequency only, along with F1 changing the stepsize. The other function keys have no current assignments. I can add hard-coded Function keys as I did with F1 but maybe a more generic solution can be determined. In addition the keypad is not supported. Hamlib has no apparent way to make use of the numeric keys. We probably need to add a callback for key data. IF-Shift: IF-Shift code is in place but I see no way in hamlib to make use of it. The Icom dual pass-band tuning is supported, but not just simple IF shift. Or maybe I just missed something. TX Audio Monitor Volume - no hamlib support - RIG_LEVEL_TX_MON? CW Sidetone Volume - no hamlib support - RIG_LEVEL_SIDETONE? Transmit Audio Source and Volume select - no hamlib support - RIG_LEVEL_LINEIN? CW Spot Level - no hamlib support - RIG_LEVEL_CW_SPOT? Enable/Disable Amplifier keying loop - no hamlib support - RIG_FUNC_AMP? hamlib-4.6.2/rigs/tentec/tt550.h0000644000175000017500000001321414752216205013165 00000000000000/* * Hamlib Tentec backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TT550_H #define _TT550_H 1 #include #define EOM "\015" /* CR */ #define TT_AM '0' #define TT_USB '1' #define TT_LSB '2' #define TT_CW '3' #define TT_FM '4' /* * Transmit and receive flags used by tt550_tuning_factor_calc * to modify behavior for transmit versus receive vfo's */ #define RECEIVE 0 #define TRANSMIT 1 /* * Transmitter control operations */ #define DISABLE_TX '0' #define ENABLE_TX '1' #define DISABLE_AMP '2' #define ENABLE_AMP '3' #define ENABLE_KEYER '6' #define DISABLE_KEYER '7' #define DISABLE_KEEPALIVE '8' #define ENABLE_KEEPALIVE '9' /* This is needed until we come up with a way to guarantee that the ** KEEPALIVE mechanism of the Pegasus is met. */ #define BYPASS_KEEPALIVE 1 #define KEY_F1_DOWN 0x11 #define KEY_F2_DOWN 0x12 #define KEY_F3_DOWN 0x13 #define KEY_F1_UP 0x91 #define KEY_F2_UP 0x92 #define KEY_F3_UP 0x93 struct tt550_priv_data { rmode_t tx_mode; /* transmitter mode - may be different from receiver in split mode */ rmode_t rx_mode; /* Current RX Mode */ freq_t tx_freq; /* tuned transmitter frequency - may be different from * 'freq' when in split mode */ freq_t rx_freq; /* Current RX Frequency */ shortfreq_t rit; /* Current RIT Value */ shortfreq_t xit; /* Current XIT Value */ shortfreq_t pbtadj; /* Current pass band tuning value */ pbwidth_t width; /* filter bandwidth in Hz */ pbwidth_t tx_width; /* transmit filter bandwidth in Hz */ int pb; /* RX passband offset in Hz 0 [0-10000] */ int cwbfo; /* BFO frequency: 700 [0-2000Hz] */ int tx_cwbfo; /* TX_BFO frequency: 700 [0-2000Hz] */ float lineout; /* line-out volume: 30 [0..63] */ float spkvol; /* speaker volume: 30 [0..63] */ int agc; /* AGC: medium */ float rflevel; /* RF Gain Level: [0..255] */ float sql; /* Squelch: [0..255] */ int att; /* Attenuator level [0..1] */ int keyspd; /* Keyer speed: [0..255] */ float nr; /* Noise reduction: [0..1] */ float autonotch; /* Autonotch filter: [0..1] */ float rfpower; /* RF Power: [0..255] */ float speechcomp; /* Speech compressor: [0..127] */ float voxgain; /* Vox Gain: [0..255] */ float voxdelay; /* Vox delay: [0..255] */ float antivox; /* AntiVox gain: [0..255] */ float mikegain; /* Microphone gain: [0..15] */ float bkindl; /* CW QSK level */ int split; /* split - ON/OFF */ shortfreq_t stepsize; /*current step size */ int anf; /* ANF on/off 1/0 */ int en_nr; /* Noise Reduction on/off 1/0 */ int tuner; /* automatic tuner on/off 1/0 */ int vox; /* VOX on/off 1/0 */ /* calculated by tt550_tuning_factor_calc() */ int ctf; /* Coarse Tune Factor */ int ftf; /* Fine Tune Factor */ int btf; /* Bfo Tune Factor, btval is ignored by RX-320 in AM MODE */ /* S-meter calibration data */ cal_table_t str_cal; }; int tt550_init (RIG * rig); int tt550_cleanup (RIG * rig); int tt550_trx_open (RIG * rig); int tt550_reset(RIG * rig, reset_t reset); int tt550_set_freq (RIG * rig, vfo_t vfo, freq_t freq); int tt550_get_freq (RIG * rig, vfo_t vfo, freq_t * freq); int tt550_set_mode (RIG * rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tt550_get_mode (RIG * rig, vfo_t vfo, rmode_t * mode, pbwidth_t * width); int tt550_set_level (RIG * rig, vfo_t vfo, setting_t level, value_t val); int tt550_get_level (RIG * rig, vfo_t vfo, setting_t level, value_t * val); int tt550_set_ptt (RIG * rig, vfo_t vfo, ptt_t ptt); int tt550_get_ptt (RIG * rig, vfo_t vfo, ptt_t * ptt); int tt550_decode_event (RIG * rig); const char *tt550_get_info (RIG * rig); int tt550_set_tx_freq (RIG * rig, vfo_t vfo, freq_t freq); int tt550_get_tx_freq (RIG * rig, vfo_t vfo, freq_t * freq); int tt550_set_rx_freq (RIG * rig, vfo_t vfo, freq_t freq); int tt550_get_rx_freq (RIG * rig, vfo_t vfo, freq_t * freq); int tt550_set_tx_mode (RIG * rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tt550_get_tx_mode (RIG * rig, vfo_t vfo, rmode_t * mode, pbwidth_t * width); int tt550_set_rx_mode (RIG * rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tt550_get_rx_mode (RIG * rig, vfo_t vfo, rmode_t * mode, pbwidth_t * width); int tt550_get_split_vfo (RIG * rig, vfo_t vfo, split_t * split, vfo_t * tx_vfo); int tt550_set_split_vfo (RIG * rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int tt550_get_tuning_step (RIG * rig, vfo_t vfo, shortfreq_t * stepsize); int tt550_set_tuning_step (RIG * rig, vfo_t vfo, shortfreq_t stepsize); int tt550_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int tt550_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int tt550_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int tt550_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int tt550_get_rit(RIG *rig, vfo_t vfo, shortfreq_t * rit); int tt550_set_xit(RIG * rig, vfo_t vfo, shortfreq_t rit); int tt550_get_xit(RIG *rig, vfo_t vfo, shortfreq_t * rit); #endif /* _TT550_H */ hamlib-4.6.2/rigs/tentec/tentec2.h0000644000175000017500000000401114752216205013643 00000000000000/* * Hamlib Tentec backend - Argonaut, Jupiter, RX-350 header * Copyright (c) 2001-2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TENTEC2_H #define _TENTEC2_H 1 #include // The include order will determine which BACKEND_VER is used // tentec.h may also be included and the last include is the BACKEND_VER used #undef BACKEND_VER #define BACKEND_VER "20191208" /* * Mem caps to be checked.. */ #define TT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .split = 1, \ } int tentec2_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int tentec2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int tentec2_set_vfo(RIG *rig, vfo_t vfo); int tentec2_get_vfo(RIG *rig, vfo_t *vfo); int tentec2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tentec2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int tentec2_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int tentec2_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int tentec2_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int tentec2_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int tentec2_reset(RIG *rig, reset_t reset); const char* tentec2_get_info(RIG *rig); #endif /* _TENTEC2_H */ hamlib-4.6.2/rigs/tentec/omnivii.c0000644000175000017500000012467714752216205013771 00000000000000/* * Hamlib TenTenc backend - TT-588 description * Copyright (c) 2003-2009 by Stephane Fillod * Modifications 2014 by Michael Black W9MDB for 1.036 firmware * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include "tentec2.h" #include "bandplan.h" struct tt588_priv_data { int ch; /* mem */ vfo_t vfo_curr; }; #define TT588_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_AM) #define TT588_RXMODES (TT588_MODES) #define TT588_FUNCS (RIG_FUNC_NR|RIG_FUNC_ANF) #define TT588_LEVELS ( RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SQL| \ RIG_LEVEL_SWR| \ RIG_LEVEL_RF| \ RIG_LEVEL_AF| \ RIG_LEVEL_AGC| \ RIG_LEVEL_PREAMP| \ RIG_LEVEL_SWR| \ RIG_LEVEL_ATT \ /*RIG_LEVEL_NB| */ \ /*RIG_LEVEL_IF| */ \ /*RIG_LEVEL_RFPOWER| */ \ /*RIG_LEVEL_KEYSPD| */ \ /*RIG_LEVEL_ANF| */ \ /*RIG_LEVEL_MICGAIN|*/ \ /*RIG_LEVEL_NR| */ \ /*RIG_LEVEL_VOXGAIN| */ \ /*RIG_LEVEL_VOX| */\ /*RIG_LEVEL_COMP|*/ \ ) #define TT588_ANTS (RIG_ANT_1|RIG_ANT_2) #define TT588_PARMS (RIG_PARM_NONE) #define TT588_VFO (RIG_VFO_A|RIG_VFO_B) #define TT588_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) #define TT588_AM '0' #define TT588_USB '1' #define TT588_LSB '2' #define TT588_CW '3' #define TT588_FM '4' #define TT588_CWR '5' // What would FSK mode match in hamlib? Not implemented. // #define TT588_FSK '6' #define EOM "\015" /* CR */ #define FALSE 0 #define TRUE 1 static int tt588_init(RIG *rig); static int tt588_reset(RIG *rig, reset_t reset); static int tt588_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tt588_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tt588_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int tt588_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int tt588_set_vfo(RIG *rig, vfo_t vfo); static int tt588_get_vfo(RIG *rig, vfo_t *vfo); static int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static char which_vfo(const RIG *rig, vfo_t vfo); static int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tt588_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int tt588_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int tt588_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int tt588_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int tt588_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tt588_reset(RIG *rig, reset_t reset); static const char *tt588_get_info(RIG *rig); static int tt588_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int tt588_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int tt588_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); #if 0 // these are example prototypes for remote operation static int tt588_get_ant(RIG *rig, vfo_t vfo, ant_t *ant); static int tt588_set_ant(RIG *rig, vfo_t vfo, ant_t ant); #endif /* * tt588 transceiver capabilities. * * Protocol is documented at the tentec site */ struct rig_caps tt588_caps = { RIG_MODEL(RIG_MODEL_TT588), .model_name = "TT-588 Omni VII", .mfg_name = "Ten-Tec", .version = "20231002.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 57600, .serial_rate_max = 57600, .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 = 400, .retry = 3, .has_get_func = TT588_FUNCS, .has_set_func = TT588_FUNCS, .has_get_level = TT588_LEVELS, .has_set_level = RIG_LEVEL_SET(TT588_LEVELS), .has_get_parm = TT588_PARMS, .has_set_parm = TT588_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, /* FIXME: real value */ .attenuator = { 6, 12, 18, RIG_DBLST_END }, .max_rit = Hz(8192), .max_xit = Hz(8192), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 127, RIG_MTYPE_MEM, TT_MEM_CAP }, }, .rx_range_list1 = { {kHz(500), MHz(30), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, {MHz(48), MHz(54), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), FRQ_RNG_6m(1, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, {MHz(48), MHz(54), TT588_RXMODES, -1, -1, TT588_VFO, TT588_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), {MHz(5.25), MHz(5.40), TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS}, FRQ_RNG_6m(2, TT588_MODES, W(5), W(100), TT588_VFO, TT588_ANTS), RIG_FRNG_END, }, .tuning_steps = { {TT588_RXMODES, 1}, {TT588_RXMODES, 10}, {TT588_RXMODES, 100}, {TT588_RXMODES, kHz(1)}, {TT588_RXMODES, kHz(10)}, {TT588_RXMODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, 300}, {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, kHz(8)}, {RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_AM, 0}, /* 34 filters */ {RIG_MODE_FM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .priv = (void *) NULL, .rig_init = tt588_init, .set_freq = tt588_set_freq, .get_freq = tt588_get_freq, .set_vfo = tt588_set_vfo, .get_vfo = tt588_get_vfo, .set_mode = tt588_set_mode, .get_mode = tt588_get_mode, .get_level = tt588_get_level, .set_level = tt588_set_level, .set_split_freq = tt588_set_split_freq, .get_split_freq = tt588_get_split_freq, .set_split_mode = tt588_set_split_mode, .get_split_mode = tt588_get_split_mode, .set_split_vfo = tt588_set_split_vfo, .get_split_vfo = tt588_get_split_vfo, .set_ptt = tt588_set_ptt, .reset = tt588_reset, .get_info = tt588_get_info, .get_xit = tt588_get_xit, .set_xit = tt588_set_xit, .get_rit = tt588_get_xit, .set_rit = tt588_set_rit, // Antenna functions only in remote mode -- prototypes provided //.get_ant = tt588_get_ant, //.set_ant = tt588_set_ant .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* Filter table for 588 receiver support. */ static int tt588_rxFilter[] = { 12000, 9000, 8000, 7500, 7000, 6500, 6000, 5500, 5000, 4500, 4000, 3800, 3600, 3400, 3200, 3000, 2800, 2600, 2500, 2400, 2200, 2000, 1800, 1600, 1400, 1200, 1000, 900, 800, 700, 600, 500, 450, 400, 350, 300, 250, 200 }; /* * Function definitions below */ /* I frequently see the Omni VII and my laptop get out of sync. A response from the 538 isn't seen by the laptop. A few "XX"s sometimes get things going again, hence this hack, er, function. */ /* Note: data should be at least data_len+1 long for null byte insertion */ static int tt588_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, const int *data_len) { int i, retval = -RIG_EINTERNAL; hamlib_port_t *rp = RIGPORT(rig); // The original file had "A few XX's" due to sync problems // So I put this in a try loop which should, hopefully, never be seen for (i = 0; i < 3; ++i) // We'll try 3 times { char xxbuf[32]; rig_flush(rp); // We add 1 to data_len here for the null byte inserted by read_string eventually // That way all the callers can use the expected response length for the cmd_len parameter here // Callers all need to ensure they have enough room in data for this retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval == RIG_OK) { // All responses except from "XX" terminate with EOM (i.e. \r) so that is our stop char char *term = EOM; if (cmd[0] == 'X') // we'll let the timeout take care of this as it shouldn't happen anyways { term = ""; } if (data) { retval = read_string(rp, (unsigned char *) data, (*data_len) + 1, term, strlen(term), 0, 1); if (retval != -RIG_ETIMEOUT) { return RIG_OK; } rig_debug(RIG_DEBUG_ERR, "%s: read_string failed, try#%d\n", __func__, i + 1); return retval; } else { return RIG_OK; // no data wanted so just return } } else { rig_debug(RIG_DEBUG_ERR, "%s: write_block failed, try#%d\n", __func__, i + 1); } write_block(rp, (unsigned char *) "XX" EOM, 3); // we wont' worry about the response here retval = read_string(rp, (unsigned char *) xxbuf, sizeof(xxbuf), "", 0, 0, 1); // this should timeout if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: XX command failed, try#%d\n", __func__, i + 1); } } return retval; } /* * tt588_init: * Basically, it just sets up *priv */ int tt588_init(RIG *rig) { struct tt588_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s:\n", __func__); STATE(rig)->priv = (struct tt588_priv_data *) calloc(1, sizeof( struct tt588_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt588_priv_data)); /* * set arbitrary initial status */ priv->ch = 0; priv->vfo_curr = RIG_VFO_A; return RIG_OK; } static int check_vfo(vfo_t vfo) { switch (vfo) // Omni VII only has A & B { case RIG_VFO_A: break; case RIG_VFO_B: break; case RIG_VFO_CURR: break; // will default to A in which_vfo default: return FALSE; } return TRUE; } // which_vfo returns the only two answers that work for commands // Each calling routine should call check_vfo() before calling this // Anything other than RIG_VFO_B will return 'A' since Omni VII only uses B on split // So 'A' is always the default VFO static char which_vfo(const RIG *rig, vfo_t vfo) { return RIG_VFO_B == vfo ? 'B' : 'A'; } int tt588_get_vfo(RIG *rig, vfo_t *vfo) { static int getinfo = TRUE; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; if (getinfo) // this is the first call to this package so we do this here { getinfo = FALSE; tt588_get_info(rig); } *vfo = priv->vfo_curr; if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } /* * tt588_set_vfo * Assumes rig!=NULL */ int tt588_set_vfo(RIG *rig, vfo_t vfo) { struct tt588_priv_data *priv = (struct tt588_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { return RIG_OK; } priv->vfo_curr = vfo; return RIG_OK; } /* * Software restart */ int tt588_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s: reset=%d\n", __func__, reset); reset_len = 32; retval = tt588_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "RADIO START")) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, reset_buf); return -RIG_EPROTO; } return RIG_OK; } /* * tt588_get_freq * Assumes rig!=NULL, freq!=NULL */ int tt588_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int resp_len, retval; unsigned char cmdbuf[16], respbuf[32]; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?%c" EOM, which_vfo(rig, vfo)); resp_len = 6; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if ((respbuf[0] == 'A' || respbuf[0] == 'B') && respbuf[5] == 0x0d) { *freq = (respbuf[1] << 24) + (respbuf[2] << 16) + (respbuf[3] << 8) + respbuf[4]; } else { *freq = 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __func__, rig_strvfo(vfo), *freq); return RIG_OK; } /* * tt588_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int tt588_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char bytes[4]; unsigned char cmdbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __func__, rig_strvfo(vfo), freq); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { int retval; if ((retval = tt588_get_vfo(rig, &vfo)) != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s: set_freq2 vfo=%s\n", __func__, rig_strvfo(vfo)); } /* Freq is 4 bytes long, MSB sent first. */ bytes[3] = ((int) freq >> 24) & 0xff; bytes[2] = ((int) freq >> 16) & 0xff; bytes[1] = ((int) freq >> 8) & 0xff; bytes[0] = (int) freq & 0xff; SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*%c%c%c%c%c" EOM, which_vfo(rig, vfo), bytes[3], bytes[2], bytes[1], bytes[0]); return tt588_transaction(rig, (char *) cmdbuf, 7, NULL, NULL); } /* * tt588_set_split_freq */ int tt588_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { // VFOB is the split VFO return tt588_set_freq(rig, RIG_VFO_B, tx_freq); } /* * tt588_get_split_freq * assumes rig!=NULL, tx_freq!=NULL */ int tt588_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { // VFOB is the split VFO return tt588_get_freq(rig, RIG_VFO_B, tx_freq); } /* * tt588_set_split_mode * assumes rig!=NULL */ int tt588_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { // VFOB is the split VFO return tt588_set_mode(rig, RIG_VFO_B, tx_mode, tx_width); } /* * tt588_get_split_mode * assumes rig!=NULL, tx_mode!=NULLm, tx_width!=NULL */ int tt588_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { // VFOB is the split VFO return tt588_get_mode(rig, RIG_VFO_B, tx_mode, tx_width); } /* * tt588_get_mode * Assumes rig!=NULL, mode!=NULL */ int tt588_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int resp_len, retval; unsigned char cmdbuf[16], respbuf[32]; char ttmode; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } // Query mode SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 4; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (which_vfo(rig, vfo)) { case 'A': ttmode = respbuf[1]; break; case 'B': ttmode = respbuf[2]; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; break; } switch (ttmode) { case TT588_AM: *mode = RIG_MODE_AM; break; case TT588_USB: *mode = RIG_MODE_USB; break; case TT588_LSB: *mode = RIG_MODE_LSB; break; case TT588_CW: *mode = RIG_MODE_CW; break; case TT588_CWR: *mode = RIG_MODE_CWR; break; case TT588_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, ttmode); return -RIG_EPROTO; } /* Query passband width (filter) */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?W" EOM); resp_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'W') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (respbuf[1]) { case 0: *width = 12000; break; case 1: *width = 9000; break; case 2: *width = 8000; break; case 3: *width = 7500; break; case 4: *width = 7000; break; case 5: *width = 6500; break; case 6: *width = 6000; break; case 7: *width = 5500; break; case 8: *width = 5000; break; case 9: *width = 4500; break; case 10: *width = 4000; break; case 11: *width = 3800; break; case 12: *width = 3600; break; case 13: *width = 3400; break; case 14: *width = 3200; break; case 15: *width = 3000; break; case 16: *width = 2800; break; case 17: *width = 2600; break; case 18: *width = 2500; break; case 19: *width = 2400; break; case 20: *width = 2200; break; case 21: *width = 2000; break; case 22: *width = 1800; break; case 23: *width = 1600; break; case 24: *width = 1400; break; case 25: *width = 1200; break; case 26: *width = 1000; break; case 27: *width = 900; break; case 28: *width = 800; break; case 29: *width = 700; break; case 30: *width = 600; break; case 31: *width = 500; break; case 32: *width = 450; break; case 33: *width = 400; break; case 34: *width = 350; break; case 35: *width = 300; break; case 36: *width = 250; break; case 37: *width = 200; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected bandwidth '%c'\n", __func__, respbuf[1]); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } /* Find rx filter index of bandwidth the same or larger as requested. */ static int tt588_filter_number(int width) { int i; for (i = 34; i >= 0; i--) if (width <= tt588_rxFilter[i]) { return i; } return 0; /* Widest filter, 8 kHz. */ } /* * tt588_set_mode * Assumes rig!=NULL */ int tt588_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmdbuf[32], respbuf[32], ttmode; int resp_len, retval; const struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE( rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } /* Query mode for both VFOs. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?M" EOM); resp_len = 4; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'M' || respbuf[3] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } switch (mode) { case RIG_MODE_USB: ttmode = TT588_USB; break; case RIG_MODE_LSB: ttmode = TT588_LSB; break; case RIG_MODE_CW: ttmode = TT588_CW; break; case RIG_MODE_CWR: ttmode = TT588_CWR; break; case RIG_MODE_AM: ttmode = TT588_AM; break; case RIG_MODE_FM: ttmode = TT588_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } /* Set mode for both VFOs. */ if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, ttmode, respbuf[2]); break; case RIG_VFO_B: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*M%c%c" EOM, respbuf[1], ttmode); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } retval = tt588_transaction(rig, (char *) cmdbuf, 5, NULL, NULL); if (retval != RIG_OK) { return retval; } /* Set rx filter bandwidth. */ if (RIG_PASSBAND_NOCHANGE == width) { return retval; } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } width = tt588_filter_number((int) width); SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*W%c" EOM, (unsigned char) width); return tt588_transaction(rig, (char *) cmdbuf, 4, NULL, NULL); } /* * tt588_get_level * Assumes rig!=NULL, val!=NULL */ int tt588_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { float fwd, refl; int retval, lvl_len; unsigned char cmdbuf[16], lvlbuf[32]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_SWR: lvl_len = 4; retval = tt588_transaction(rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } // top bit of lvlbuf[1] should be on if transmitting if (lvlbuf[0] != 'S' || lvlbuf[3] != 0x0d || ((lvlbuf[1] & 0x80) == 0)) { val->f = 99; // infinity rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d buf=%02x %02x %02x %02x\n", __func__, lvl_len, lvlbuf[0], lvlbuf[1], lvlbuf[2], lvlbuf[3]); return -RIG_EPROTO; } /* forward power. */ fwd = (float)(lvlbuf[1] & 0x7f); /* reflected power. */ refl = (float) lvlbuf[2]; if (fwd > 0) { val->f = refl / fwd; // our ratio val->f = (1 + val->f) / (1 - val->f); // SWR formula } else { val->f = 99; } break; case RIG_LEVEL_STRENGTH: lvl_len = 6; retval = tt588_transaction(rig, "?S" EOM, 3, (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'S') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } // Reply in the form S0944 for 44 dB over S9 in ASCII // S0600 is S6 (0 db over S9) // S9=34db S0=-20dB // So you can read the exact S-meter from the 1st 2 bytes // 2nd set of bytes is S9-relative if ((lvlbuf[1] & 0x80) == 0) // then we're not in tx mode so we're good { // 1st two bytes are the S-level sscanf((char *)lvlbuf, "S%02d", &val->i); val->i = (val->i - 9) * 6; // convert S meter to dBS9 relative rig_debug(RIG_DEBUG_TRACE, "%s: meter= %ddB\n", __func__, val->i); } else { // transmit reply example S<0x8f><0x01> 0x0f=15 watts, 0x01 // it appears 0x01 reflected = 0W since 0 means not read yet int strength; int reflected = (int)lvlbuf[2]; reflected = reflected > 0 ? reflected - 1 : 0; // computer transmit power strength = (int)(lvlbuf[1] & 0x7f) - reflected; rig_debug(RIG_DEBUG_TRACE, "%s: strength fwd=%d, rev=%d\n", __func__, strength, reflected); if (strength > 0) // convert watts to dbM { val->i = 10 * log10(strength) + 30; // now convert to db over 1uV val->i += 73; } else { val->i = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: strength= %ddB\n", __func__, val->i); } break; case RIG_LEVEL_AGC: /* Read rig's AGC level setting. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?G" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'G' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } switch (lvlbuf[1]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_SLOW; break; case '2': val->i = RIG_AGC_MEDIUM; break; case '3': val->i = RIG_AGC_FAST; break; default: return -RIG_EPROTO; } break; case RIG_LEVEL_AF: /* Volume returned as single byte. */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?U" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'U' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = (float) lvlbuf[1] / 127; break; case RIG_LEVEL_IF: // Omni VII has so such thing rig_debug(RIG_DEBUG_ERR, "%s: no RIG_LEVEL_IF on Omni VII\n", __func__); val->i = 0; break; case RIG_LEVEL_RF: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?I" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = lvlbuf[1] / 127.0f; break; case RIG_LEVEL_ATT: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?J" EOM); lvl_len = 33; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'J' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = (lvlbuf[1] - '0') * 6; // 1=6, 2=12, 3=18 break; #if 0 case RIG_LEVEL_PREAMP: /* Only in remote mode */ val->i = 0; break; #endif case RIG_LEVEL_SQL: SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "?H" EOM); lvl_len = 3; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'H' || lvlbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = lvlbuf[1] / 127.0f; break; #if 0 case RIG_LEVEL_MICGAIN: /* Only in remote mode */ val->i = 0; break; #endif #if 0 case RIG_LEVEL_COMP: /* Only in remote mode */ val->i = 0; break; #endif default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level)); return RIG_OK; } /* * tt588_set_level * Assumes rig!=NULL, val!=NULL */ int tt588_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, ii; unsigned char cmdbuf[16], agcmode; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_AF: /* Volume */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*U%c" EOM, (char)(val.f * 127)); retval = tt588_transaction(rig, (char *) cmdbuf, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_RF: /* RF gain. Omni-VII expects value 0 for full gain, and 127 for lowest gain */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*I%c" EOM, 127 - (char)(val.f * 127)); retval = tt588_transaction(rig, (char *) cmdbuf, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agcmode = '0'; break; case RIG_AGC_SLOW: agcmode = '1'; break; case RIG_AGC_MEDIUM: agcmode = '2'; break; case RIG_AGC_FAST: agcmode = '3'; break; default: return -RIG_EINVAL; } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*Gx" EOM); cmdbuf[2] = agcmode; retval = tt588_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_ATT: /* Attenuation */ ii = -1; /* Request 0-5 dB -> 0, 6-11 dB -> 6, etc. */ while (rig->caps->attenuator[++ii] != RIG_DBLST_END) { if (rig->caps->attenuator[ii] > val.i) { break; } } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*J%c" EOM, ii + '0'); retval = tt588_transaction(rig, (char *) cmdbuf, 4, NULL, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_SQL: /* Squelch level, float 0.0 - 1.0 */ SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "*H%c" EOM, (int)(val.f * 127)); retval = tt588_transaction(rig, (char *) cmdbuf, 3, NULL, NULL); if (retval != RIG_OK) { return retval; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * tt588_set_split_vfo * Assumes rig!=NULL */ int tt588_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval, resp_len; char cmdbuf[16], respbuf[16]; if (tx_vfo == RIG_VFO_SUB) { tx_vfo = RIG_VFO_B; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s split=%d tx_vfo=%s\n", __func__, rig_strvfo(vfo), split, rig_strvfo(tx_vfo)); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*Nx" EOM "?N" EOM); //if (split == RIG_SPLIT_ON || tx_vfo==RIG_VFO_B) if (split == RIG_SPLIT_ON) { cmdbuf[2] = 1; } else { cmdbuf[2] = 0; } resp_len = 3; retval = tt588_transaction(rig, cmdbuf, 4, respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'N' || respbuf[2] != 0x0d) { rig_debug(RIG_DEBUG_ERR, "%s: unknown response to *N%d='%s'\n", __func__, split, respbuf); return -RIG_EINVAL; } return RIG_OK; } /* * tt588_get_split_vfo * Assumes rig!=NULL, split!=NULL, tx_vfo!=NULL */ int tt588_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int resp_len, retval; char cmdbuf[16], respbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // get split on/off SNPRINTF(cmdbuf, sizeof(cmdbuf), "?N" EOM); resp_len = 3; retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); // respbuf returns "N0" or "N1" for split off/on if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'N' || respbuf[2] != 0x0d || (respbuf[1] != 0 && respbuf[1] != 1)) { return -RIG_EPROTO; } *split = respbuf[1] == 0 ? RIG_SPLIT_OFF : RIG_SPLIT_ON; if (*split == RIG_SPLIT_ON) { *tx_vfo = RIG_VFO_B; // Omni VII always transmits on VFO_B when in split } else { *tx_vfo = RIG_VFO_A; // VFO A when not in split } rig_debug(RIG_DEBUG_VERBOSE, "%s: split=%d tx_vfo=%s\n", __func__, *split, rig_strvfo(*tx_vfo)); return RIG_OK; } /* * tt588_set_ptt * Assumes rig!=NULL */ int tt588_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmdbuf[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*Txx" EOM); if (ptt) { cmdbuf[2] = 4; cmdbuf[3] = 1; // turn on ethernet RIPing } else { cmdbuf[2] = 0; cmdbuf[3] = 1; // turn on ethernet RIPing } retval = tt588_transaction(rig, cmdbuf, 5, NULL, 0); // no response if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt588_get_info * Assumes rig!=NULL * Returns statically allocated buffer */ const char *tt588_get_info(RIG *rig) { static char cmdbuf[16], firmware[64]; int firmware_len = sizeof(firmware), retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?V" EOM); memset(firmware, 0, sizeof(firmware)); rig_debug(RIG_DEBUG_VERBOSE, "%s: firmware_len=%d\n", __func__, firmware_len); retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), firmware, &firmware_len); // Response should be "VER 1010-588 " plus "RADIO x\r" or "REMOTEx\r" // if x=blank ham band transmit only // if x='M' MARS transmit only if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, firmware); return firmware; } /* * tt588_get_xit * tt588_get_rit is linked to this too since it's just one offset and the same command * Assumes rig!=NULL * Note that ?L can't query RIT/XIT separately...there's only one offset */ int tt588_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int resp_len, retval; char cmdbuf[16], respbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // get xit SNPRINTF(cmdbuf, sizeof(cmdbuf), "?L" EOM); resp_len = 5; retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'L' || respbuf[4] != 0x0d) { return -RIG_EPROTO; } *xit = (respbuf[2] * (short)256) | respbuf[3]; rig_debug(RIG_DEBUG_VERBOSE, "%s: rit=%d\n", __func__, (int)*xit); return RIG_OK; } // This routine handles both rit and xit setting // Though we can turn on both (which=3) there's no obvious condition for doing so // We can only query the one offset and don't really know for which it was set // And is there any reason to turn on both? If so, hamblib doesn't seem to support that. // static int set_rit_xit(RIG *rig, vfo_t vfo, shortfreq_t rit, int which) { int retval; char cmdbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s: rit=%d\n", __func__, (int)rit); if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // For some reason need an extra \r on here // This is with version 1.036 -- it appears to want 7 chars instead of 6 SNPRINTF(cmdbuf, sizeof(cmdbuf), "*Lxxx" EOM EOM); cmdbuf[2] = which; // set xit bit. 0=off,1=rit, 2=xit, 3=both cmdbuf[3] = rit >> 8; cmdbuf[4] = rit & 0xff; retval = tt588_transaction(rig, cmdbuf, 6, NULL, 0); // no response if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tt588_set_xit * Assumes rig!=NULL */ int tt588_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { return set_rit_xit(rig, vfo, xit, 2); // bit 2 is xit } /* * tt588_set_xit * Assumes rig!=NULL */ int tt588_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { return set_rit_xit(rig, vfo, rit, 1); // bit 1 is rit } #if 0 // commenting out prototypes that are only for remote use /* * This is a prototype function as C1V is only available in remote mode * tt588_get_ant * Assumes rig!=NULL */ int tt588_get_ant(RIG *rig, vfo_t vfo, ant_t *ant) { int resp_len, retval; char cmdbuf[16], respbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } // get xit SNPRINTF(cmdbuf, sizeof(cmdbuf), "*C1V" EOM); resp_len = 5; // this should be the only line needing change for remote operation retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (resp_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: bad response length, expected %d, got %d\n", __func__, 5, resp_len); } if (retval != RIG_OK) { return retval; } if (respbuf[0] != 'C' || respbuf[4] != 0x0d) { return -RIG_EPROTO; } *ant = respbuf[3]; rig_debug(RIG_DEBUG_VERBOSE, "%s: rit=%d\n", __func__, *ant); return RIG_OK; } /* * This is a prototype function as C1V is only available in remote mode * tt588_set_ant * Assumes rig!=NULL */ int tt588_set_ant(RIG *rig, vfo_t vfo, ant_t ant) { int retval, cmd_len; char cmdbuf[16]; if (check_vfo(vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ant=%d\n", __func__, ant); SNPRINTF(cmdbuf, sizeof(cmdbuf), "*C1Vx" EOM); // 0 = RX=TX=ANT1 // 1 = RX=TX=ANT2 // 2 = RX=RXAUX, TX=ANT1 // 3 = RX=RXAUC, TX=ANT2 cmdbuf[4] = ant; // this should be the only line needing change for remote operation retval = tt588_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, 0); // no response if (retval != RIG_OK) { return retval; } return RIG_OK; } #endif hamlib-4.6.2/rigs/tentec/rx340.c0000644000175000017500000003275714752216205013174 00000000000000/* * Hamlib TenTenc backend - RX-340 description * Copyright (c) 2003-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "num_stdio.h" #define RX340_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_DSB|\ RIG_MODE_AM|RIG_MODE_AMS) #define RX340_FUNCS (RIG_FUNC_NB) #define RX340_LEVELS (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_RF|RIG_LEVEL_IF| \ RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL| \ RIG_LEVEL_CWPITCH|RIG_LEVEL_AGC| \ RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define RX340_ANTS (RIG_ANT_1) #define RX340_PARMS (RIG_PARM_NONE) #define RX340_VFO (RIG_VFO_A) #define RX340_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO) /* TODO: levels.. */ #define RX340_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } #if 0 static int rx340_init(RIG *rig); static int rx340_cleanup(RIG *rig); #endif static int rx340_open(RIG *rig); static int rx340_close(RIG *rig); static int rx340_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int rx340_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int rx340_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int rx340_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int rx340_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int rx340_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *rx340_get_info(RIG *rig); /* * RX340 receiver capabilities. * * Protocol is documented at * http://radio.tentec.com/downloads/receivers/RX340 * * TODO: from/to memory, scan, get_level, .. * supposes non-multidrop */ struct rig_caps rx340_caps = { RIG_MODEL(RIG_MODEL_RX340), .model_name = "RX-340", .mfg_name = "Ten-Tec", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 75, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 400, .retry = 3, .has_get_func = RX340_FUNCS, .has_set_func = RX340_FUNCS, .has_get_level = RX340_LEVELS, .has_set_level = RIG_LEVEL_SET(RX340_LEVELS), .has_get_parm = RX340_PARMS, .has_set_parm = RX340_PARMS, .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 15, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM, RX340_MEM_CAP }, }, .rx_range_list1 = { {kHz(0), MHz(30), RX340_MODES, -1, -1, RX340_VFO, RX340_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(0), MHz(30), RX340_MODES, -1, -1, RX340_VFO, RX340_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RX340_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RX340_MODES, kHz(3.2)}, {RX340_MODES, Hz(100)}, {RX340_MODES, kHz(16)}, {RX340_MODES, 0}, RIG_FLT_END, }, .priv = (void *)NULL, .rig_open = rx340_open, .rig_close = rx340_close, .set_freq = rx340_set_freq, .get_freq = rx340_get_freq, .set_mode = rx340_set_mode, .get_mode = rx340_get_mode, .set_level = rx340_set_level, .get_level = rx340_get_level, .get_info = rx340_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #define BUFSZ 128 #define EOM "\015" /* CR */ #define RX340_AM '1' #define RX340_FM '2' #define RX340_CW '3' #define RX340_CW1 '4' #define RX340_ISB '5' #define RX340_LSB '6' #define RX340_USB '7' #define RX340_SAM '8' /* * rx340_transaction * read exactly data_len bytes * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! */ static int rx340_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } #if 0 /* * rx340_init: * Basically, it just sets up *priv */ int rx340_init(RIG *rig) { struct rx340_priv_data *priv; priv = (struct rx340_priv_data *)calloc(1, sizeof(struct rx340_priv_data)); if (!priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } memset(priv, 0, sizeof(struct rx340_priv_data)); /* * set arbitrary initial status */ STATE(rig)->priv = (rig_ptr_t)priv; return RIG_OK; } /* * Tentec generic rx340_cleanup routine * the serial port is closed by the frontend */ int rx340_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } #endif int rx340_open(RIG *rig) { #define REMOTE_CMD "*R1"EOM return write_block(RIGPORT(rig), (unsigned char *) REMOTE_CMD, strlen(REMOTE_CMD)); } int rx340_close(RIG *rig) { #define LOCAL_CMD "*R0"EOM return write_block(RIGPORT(rig), (unsigned char *) LOCAL_CMD, strlen(LOCAL_CMD)); } /* * rx340_set_freq */ int rx340_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; char freqbuf[16]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%.6f" EOM, freq / 1e6); retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); return retval; } /* * rx340_get_freq * Assumes rig!=NULL, freq!=NULL */ int rx340_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[BUFSZ]; int buf_len = 0; int retval; double f; #define REPORT_FREQ "TF"EOM retval = rx340_transaction(rig, REPORT_FREQ, strlen(REPORT_FREQ), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 2 || buf[0] != 'F' || num_sscanf(buf + 1, "%lf", &f) != 1) { return -RIG_EPROTO; } *freq = f * 1e6; return RIG_OK; } /* * rx340_set_mode * Assumes rig!=NULL */ int rx340_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char dmode; int retval; char mdbuf[32]; switch (mode) { case RIG_MODE_USB: dmode = RX340_USB; break; case RIG_MODE_LSB: dmode = RX340_LSB; break; case RIG_MODE_CW: dmode = RX340_CW; break; case RIG_MODE_FM: dmode = RX340_FM; break; case RIG_MODE_AM: dmode = RX340_AM; break; case RIG_MODE_AMS: dmode = RX340_SAM; break; case RIG_MODE_DSB: dmode = RX340_ISB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } /* * Set DETECTION MODE and IF FILTER */ SNPRINTF(mdbuf, sizeof(mdbuf), "D%cI%.02f" EOM, dmode, (float)width / 1e3); } else { /* * Set DETECTION MODE */ SNPRINTF(mdbuf, sizeof(mdbuf), "D%c" EOM, dmode); } retval = write_block(RIGPORT(rig), (unsigned char *) mdbuf, strlen(mdbuf)); return retval; } /* * rx340_get_mode * Assumes rig!=NULL, mode!=NULL */ int rx340_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[BUFSZ]; int buf_len = 0; int retval; double f; #define REPORT_MODEFILTER "TDI"EOM retval = rx340_transaction(rig, REPORT_MODEFILTER, strlen(REPORT_MODEFILTER), buf, &buf_len); if (retval < 0) { return retval; } if (buf_len < 4 || buf[0] != 'D' || buf[2] != 'I') { return -RIG_EPROTO; } switch (buf[1]) { case RX340_USB: *mode = RIG_MODE_USB; break; case RX340_LSB: *mode = RIG_MODE_LSB; break; case RX340_CW1: case RX340_CW: *mode = RIG_MODE_CW; break; case RX340_FM: *mode = RIG_MODE_FM; break; case RX340_AM: *mode = RIG_MODE_AM; break; case RX340_SAM: *mode = RIG_MODE_AMS; break; case RX340_ISB: *mode = RIG_MODE_DSB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode '%c'\n", __func__, buf[1]); return -RIG_EPROTO; } if (num_sscanf(buf + 3, "%lf", &f) != 1) { return -RIG_EPROTO; } *width = f * 1e3; return RIG_OK; } /* * rx340_set_level * Assumes rig!=NULL * cannot support PREAMP and ATT both at same time (make sense though) */ int rx340_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval = RIG_OK; char cmdbuf[32]; switch (level) { case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "K%c" EOM, val.i ? '3' : '1'); break; case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "K%c" EOM, val.i ? '2' : '1'); break; case RIG_LEVEL_AGC: /* default to MEDIUM */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "M%c" EOM, val.i == RIG_AGC_SLOW ? '3' : ( val.i == RIG_AGC_FAST ? '1' : '2')); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%d" EOM, 120 - (int)(val.f * 120)); break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "Q%d" EOM, 150 - (int)(val.f * 150)); break; case RIG_LEVEL_NOTCHF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "N%f" EOM, ((float)val.i) / 1e3); break; case RIG_LEVEL_IF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "P%f" EOM, ((float)val.i) / 1e3); break; case RIG_LEVEL_CWPITCH: /* only in CW mode */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "B%f" EOM, ((float)val.i) / 1e3); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) cmdbuf, strlen(cmdbuf)); return retval; } /* * rx340_get_level * Assumes rig!=NULL, val!=NULL */ int rx340_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; char lvlbuf[BUFSZ]; switch (level) { case RIG_LEVEL_STRENGTH: #define REPORT_STRENGTH "X"EOM retval = rx340_transaction(rig, REPORT_STRENGTH, strlen(REPORT_STRENGTH), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len < 2 || lvlbuf[0] != 'X') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer" "len=%d\n", __func__, lvl_len); return -RIG_EPROTO; } /* range 0-150 covering the dynamic range * of receiver -140..+10dBm */ val->i = atoi(lvlbuf + 1) - 140 + 73; break; case RIG_LEVEL_AGC: case RIG_LEVEL_ATT: case RIG_LEVEL_PREAMP: case RIG_LEVEL_RF: case RIG_LEVEL_IF: case RIG_LEVEL_SQL: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_NOTCHF: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * rx340_get_info * Assumes rig!=NULL */ const char *rx340_get_info(RIG *rig) { static char buf[BUFSZ]; /* FIXME: reentrancy */ int firmware_len = 0, retval; #define REPORT_FIRM "V"EOM retval = rx340_transaction(rig, REPORT_FIRM, strlen(REPORT_FIRM), buf, &firmware_len); if ((retval != RIG_OK) || (firmware_len > 10)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); return NULL; } return buf; } hamlib-4.6.2/rigs/tentec/orion.c0000644000175000017500000017644114752216205013441 00000000000000/* * Hamlib TenTenc backend - TT-565 description * Copyright (c) 2024 by Michael Black W9MDB * Copyright (c) 2004-2011 by Martin Ewing * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Edits by Martin Ewing AA6E, 23 Mar 2005 --> ?? * Added valid length settings before tentec_transaction calls. * Added vfo_curr initialization to VFO A * Fixed up VSWR & S-meter, set ATT, set AGC, add rough STR_CAL func. * Use local tt565_transaction due to quirky serial interface * Variable-length transaction read ok. * Calibrated S-meter response with signal generator. * Read re-tries implemented. * Added RIG_LEVEL_CWPITCH, RIG_LEVEL_KEYSPD, send_morse() * Added RIG_FUNC_TUNER, RIG_FUNC_LOCK and RIG_FUNC_VOX, fixed MEM_CAP. * Added VFO_OPS * Support LEVEL_VOX, VOXGAIN, ANTIVOX * Support LEVEL_NR as Orion NB setting (firmware bug), FUNC_NB -> NB=0,4 * Add get_, set_ant (ignores rx only ant) * Use binary mode for VFO read / write, for speed. * November, 2007: * Add RIG_LEVEL_STRENGTH capability (should have been there all along) * Implement auto-detect of firmware for S-meter cal, etc. * Fixed bug in tt565_reset (to send "XX" instead of "X") * Filtered rig info string to ensure all graphics. * Big reliability improvement (for fldigi, v 2.062a) 2/15/2008 * Jan., 2009: * Remove RIG_LEVEL_STRENGTH, so that frontend can handle it. * Dec., 2011: Implement VFO range checking. Adjust range_lists for max coverage. * Fix tt565_transaction for case of Morse (/) command. */ /* Known issues & to-do list: * Memory channels - emulate a more complete memory system? * Send_Morse() - needs to buffer more than 20 chars? * Figure out "granularities". * XCHG or other "fancy" VFO & MEM operations? */ /** * \addtogroup tentec_orion * @{ */ /** * \file orion.c * \brief Backend for Tentec Orion 565 / 566 * * This backend supports the Ten-Tec Orion (565) and Orion II (566) transceivers. * \n This backend tested mostly with firmware versions 1.372 and 2.062a */ #include #include #include #include #include /* String function definitions */ #include #include #include "serial.h" #include "misc.h" #include "orion.h" #ifdef TT565_TIME /** * \returns current time in secs/microsecs */ double tt565_timenow() /* returns current time in secs+microsecs */ { struct timeval tv; gettimeofday(&tv, NULL); return (double)tv.tv_sec + ((double)tv.tv_usec) / 1.0e+6; } #endif /** * \param rig Rig descriptor * \param cmd command to send * \param cmd_len length of command string * \param data string to receive return data from Orion (NULL if no return desired) * \param data_len length of data string * \returns RIG_OK or < 0 if error * \brief tt565_transaction, adapted from tentec_transaction (tentec.c) * * This is the basic I/O transaction to/from the Orion. * \n Read variable number of bytes, up to buffer size, if data & data_len != NULL. * \n We assume that rig!=NULL, STATE(rig)!= NULL. * Otherwise, you'll get a nice seg fault. You've been warned! */ static int tt565_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int data_len_init, itry; hamlib_port_t *rp = RIGPORT(rig); static int passcount = 0; #ifdef TT565_TIME double ft1, ft2; #endif MUTEX_LOCK(mutex); passcount++; // for debugging /* Capture buffer length for possible read re-try. */ data_len_init = (data && data_len) ? *data_len : 0; /* Allow transaction re-tries according to capabilities. */ for (itry = 0; itry < rig->caps->retry; itry++) { int retval; rig_flush(rp); /* discard pending i/p */ retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { MUTEX_UNLOCK(mutex); return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { /* If it's not a 'write' to rig or a Morse command, there must be data. */ if ((*cmd != '*') && (*cmd != '/')) { rig_debug(RIG_DEBUG_ERR, "%s: cmd reject 1\n", __func__); MUTEX_UNLOCK(mutex); return -RIG_ERJCTED; } MUTEX_UNLOCK(mutex); return RIG_OK; /* normal exit if write, but no read */ } #ifdef TT565_TIME ft1 = tt565_timenow(); #endif *data_len = data_len_init; /* restore orig. buffer length */ read_string(rp, (unsigned char *) data, *data_len, EOM, strlen(EOM), 0, 1); *data_len = strlen(data); rig_debug(RIG_DEBUG_ERR, "%s: data_len = %d\n", __func__, *data_len); if (!strncmp(data, "Z!", 2)) // command unrecognized?? { rig_debug(RIG_DEBUG_ERR, "%s: cmd reject 2\n", __func__); MUTEX_UNLOCK(mutex); return -RIG_ERJCTED; // what is a better error return? } /* XX and ?V are oddball commands. Thanks, Ten-Tec! */ if (!strncmp(cmd, "XX", 2)) // Was it a firmware reset cmd? { MUTEX_UNLOCK(mutex); return RIG_OK; // Then we accept the response. } if (!strncmp(cmd, "?V", 2)) // Was it a read firmware version cmd? { MUTEX_UNLOCK(mutex); return RIG_OK; // ditto } if (cmd[0] != '?') // was this a read cmd? { rig_debug(RIG_DEBUG_ERR, "%s: cmd reject 3\n", __func__); MUTEX_UNLOCK(mutex); return -RIG_ERJCTED; // No, but it should have been! } else // Yes, it was a 'read', phew! { if (strncmp(data + 1, cmd + 1, cmd_len - 2) == 0) //response matches cmd? { MUTEX_UNLOCK(mutex); return RIG_OK; // all is well, normal exit } else { /* The command read back does not match the command that was written. We report the problem if debugging, and issue another read in hopes of eventual success. */ rig_debug(RIG_DEBUG_WARN, "** retry after delay (io=%d, retry=%d) **\n", passcount, itry); *data_len = data_len_init; /* restore orig. buffer length */ read_string(rp, (unsigned char *) data, *data_len, EOM, strlen(EOM), 0, 1); // purge the input stream... continue; // now go retry the full command } } #ifdef TT565_TIME ft2 = tt565_timenow(); if (*data_len == -RIG_ETIMEOUT) rig_debug(RIG_DEBUG_ERR, "Timeout %d: Elapsed = %f secs.\n", itry, ft2 - ft1); else rig_debug(RIG_DEBUG_ERR, "Other Error #%d, itry=%d: Elapsed = %f secs.\n", *data_len, itry, ft2 - ft1); #endif } /* end of itry loop */ rig_debug(RIG_DEBUG_ERR, "** Ran out of retries io=%d **\n", passcount); MUTEX_UNLOCK(mutex); return -RIG_ETIMEOUT; } /** * \param rig * \returns RIG_OK or < 0 * \brief Basically, it just sets up *priv */ int tt565_init(RIG *rig) { struct tt565_priv_data *priv; STATE(rig)->priv = (struct tt565_priv_data *)calloc(1, sizeof( struct tt565_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } /* no memory available */ priv = STATE(rig)->priv; memset(priv, 0, sizeof(struct tt565_priv_data)); priv->ch = 0; /* set arbitrary initial status */ priv->vfo_curr = RIG_VFO_A; return RIG_OK; } int tt565_close(RIG *rig) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; priv->threadrun = 0; pthread_join(priv->threadid, NULL); return RIG_OK; } /** * \param rig * \brief tt565_cleanup routine * * the serial port is closed by the frontend */ int tt565_cleanup(RIG *rig) { if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } static void *read_device(void *p) { RIG *rig = p; struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; priv->threadrun = 1; while (priv->threadrun) { tt565_get_freq(rig, RIG_VFO_A, &priv->freqA); tt565_get_mode(rig, RIG_VFO_A, &priv->mode, &priv->width); tt565_get_freq(rig, RIG_VFO_B, &priv->freqB); tt565_get_split_vfo(rig, RIG_VFO_A, &priv->tx_vfo, &priv->split); hl_usleep(100 * 1000); } return NULL; } static void start_thread(RIG *rig) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; pthread_attr_t attr; int ret; pthread_attr_init(&attr); ret = pthread_create(&priv->threadid, &attr, read_device, rig); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Orion unable to start thread\n", __func__); } } /** * \param rig * \brief tt565_open routine * * Open the rig - check f * This backend supports the Ten-Tec Orion (565) and Orion II (566) transceivers. irmware version issues */ int tt565_open(RIG *rig) { cal_table_t cal1 = TT565_STR_CAL_V1, cal2 = TT565_STR_CAL_V2; char *buf; /* Detect version 1 or version 2 firmware. V2 is default. */ /* The only difference for us is the S-meter cal table */ /* Get Orion's Version string (?V command response) */ buf = (char *)tt565_get_info(rig); /* Is Orion firmware version 1.* or 2.*? */ if (!strstr(buf, "1.")) { /* Not v1 means probably v2 */ memcpy(&STATE(rig)->str_cal, &cal2, sizeof(cal_table_t)); } else { memcpy(&STATE(rig)->str_cal, &cal1, sizeof(cal_table_t)); } start_thread(rig); return RIG_OK; } /** * \param rig * \param vfo RIG_VFO_MAIN or RIG_VFO_SUB * \returns 'M' or 'S' for main or subreceiver or <0 error * \brief vfo must be RIG_VFO_MAIN or RIG_VFO_SUB * * Note that Orion's "VFO"s are supposed to be logically independent * of the main/sub receiver selection. (In reality, they are not quite * independent.) */ static char which_receiver(const RIG *rig, vfo_t vfo) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: case RIG_VFO_B: case RIG_VFO_MAIN: return 'M'; case RIG_VFO_SUB: return 'S'; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported Receiver %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } } /** * \param rig * \param vfo RIG_VFO_A, RIG_VFO_B, or RIG_VFO_NONE * \returns 'A' or 'B' or 'N' for VFO A, B, or null VFO, or <0 error * \brief vfo must be RIG_VFO_A, RIG_VFO_B, or RIG_VFO_NONE. */ static char which_vfo(const RIG *rig, vfo_t vfo) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } switch (vfo) { case RIG_VFO_A: return 'A'; case RIG_VFO_B: return 'B'; case RIG_VFO_NONE: return 'N'; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } } /** * \param rig must != NULL * \param vfo RIG_VFO_A or RIG_VFO_B * \param freq * \brief Set a frequency into the specified VFO * * assumes STATE(rig)->priv!=NULL * \n assumes priv->mode in AM,CW,LSB or USB. */ int tt565_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval, i, in_range; freq_range_t this_range; char cmdbuf[TT565_BUFSIZE]; /* Check for valid frequency request. * Find freq range that includes current request and * matches the VFO A/B setting. c.f. rig_get_range(). * Recall VFOA = ham only, VFOB = gen coverage for Hamlib. * (We assume VFOA = Main RXTX and VFOB = Sub RX.) * If outside range, return RIG_ERJECTED for compatibility vs icom.c etc. */ in_range = FALSE; for (i = 0; i < HAMLIB_FRQRANGESIZ; i++) { this_range = STATE(rig)->rx_range_list[i]; if (this_range.startf == 0 && this_range.endf == 0) { break; /* have come to early end of range list */ } /* We don't care about mode setting, but vfo must match. */ if (freq >= this_range.startf && freq <= this_range.endf && (this_range.vfo == STATE(rig)->current_vfo)) { in_range = TRUE; break; } } if (!in_range) { return -RIG_ERJCTED; } /* Sorry, invalid freq request */ #ifdef TT565_ASCII_FREQ /* Use ASCII mode to set frequencies */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*%cF%"PRIll EOM, which_vfo(rig, vfo), (int64_t)freq); #else /* Use binary mode */ /* Set frequency using Orion's binary mode (short) sequence. The short sequence transfers faster and may require less Orion firmware effort, but some bugs are reported. */ /* Construct command packet by brute force. */ unsigned int myfreq; myfreq = freq; cmdbuf[0] = '*'; cmdbuf[1] = which_vfo(rig, vfo); cmdbuf[2] = (myfreq & 0xff000000) >> 24; cmdbuf[3] = (myfreq & 0x00ff0000) >> 16; cmdbuf[4] = (myfreq & 0x0000ff00) >> 8; cmdbuf[5] = myfreq & 0x000000ff; cmdbuf[6] = '\r'; /* i.e. EOM */ cmdbuf[7] = 0; #endif retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); if (retval == RIG_OK) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_A) { priv->freqA = freq; } else if (vfo == RIG_VFO_B) { priv->freqB = freq; } } return retval; } /** * \param rig must != NULL * \param vfo RIG_VFO_A or RIG_VFO_B * \param freq must != NULL * \brief Get the frequency currently set in the specified VFO (A or B) * * Performs query on physical rig */ int tt565_get_freq_cache(RIG *rig, vfo_t vfo, freq_t *freq) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_B) { *freq = priv->freqB; } else { *freq = priv->freqA; } return RIG_OK; } int tt565_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; unsigned int binf; #ifdef TT565_ASCII_FREQ /* use ASCII mode */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "?%cF" EOM, which_vfo(rig, vfo)); #else /* Get freq with Orion binary mode short sequence. */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "?%c" EOM, which_vfo(rig, vfo)); #endif resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } #ifdef TT565_ASCII_FREQ respbuf[12] = '\0'; sscanf(respbuf + 3, "%8u", &binf); *freq = (freq_t) binf; #else /* Test for valid binary mode return. */ if (respbuf[1] != which_vfo(rig, vfo) || resp_len <= 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } /* Convert binary to integer, endedness independent */ binf = (unsigned char)respbuf[2] << 24 | (unsigned char)respbuf[3] << 16 | (unsigned char)respbuf[4] << 8 | (unsigned char)respbuf[5]; *freq = (freq_t) binf; #endif return RIG_OK; } /** * \param rig must != NULL * \param vfo RIG_VFO_MAIN or RIG_VFO_SUB * \returns RIG_OK or < 0 * \brief set RIG_VFO_CURR and send info to physical rig. * * Places Orion into Main or Sub Rx active state */ int tt565_set_vfo(RIG *rig, vfo_t vfo) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { return RIG_OK; } if (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) { char vfobuf[TT565_BUFSIZE]; /* Select Sub or Main RX */ SNPRINTF(vfobuf, sizeof(vfobuf), "*K%c" EOM, vfo == RIG_VFO_SUB ? 'S' : 'M'); return tt565_transaction(rig, vfobuf, strlen(vfobuf), NULL, NULL); } priv->vfo_curr = vfo; return RIG_OK; } /** * \param rig must != NULL * \param vfo Set = stored state of current VFO state * \returns RIG_OK */ int tt565_get_vfo(RIG *rig, vfo_t *vfo) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *vfo = priv->vfo_curr; return RIG_OK; } /** * \param rig must != NULL * \param vfo Rx vfo specifier token * \param split * \param tx_vfo Tx vfo specifier token * \returns RIG_OK or < 0 * \brief Set split operating mode * * Sets Main Rx to "vfo"( A or B) , Main Tx to "tx_vfo" (A, B, or N). * \n Sub Rx is set to "None". That should be fixed! */ int tt565_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval; char cmdbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*KV%c%c%c" EOM, which_vfo(rig, vfo), 'N', /* FIXME */ which_vfo(rig, RIG_SPLIT_ON == split ? tx_vfo : vfo)); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param c * \returns RIG_VFO_x, x= A, B, or NONE * \brief Translate an Orion command character to internal token form. */ static vfo_t tt2vfo(char c) { switch (c) { case 'A': return RIG_VFO_A; case 'B': return RIG_VFO_B; case 'N': return RIG_VFO_NONE; } return RIG_VFO_NONE; } /** * \param rig must != NULL * \param vfo * \param split Returned with RIG_SPLIT_ON if Tx <> Rx vfo, .._OFF otherwise * \param tx_vfo Returned RIG_VFO_x, signifying selected Tx vfo * \returns RIG_OK or < 0 * \brief Get the current split status and Tx vfo selection. */ int tt565_get_split_vfo_cache(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = priv->tx_vfo; return RIG_OK; } int tt565_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; char ttreceiver; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?KV" EOM); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[2] != 'V' || resp_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } ttreceiver = vfo == RIG_VFO_SUB ? respbuf[4] : respbuf[3]; *tx_vfo = tt2vfo(respbuf[5]); *split = ttreceiver == respbuf[5] ? RIG_SPLIT_OFF : RIG_SPLIT_ON; priv->tx_vfo = *tx_vfo; priv->split = *split; return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param mode * \param width passband in Hz or = RIG_PASSBAND_NORMAL (=0) which gives a nominal value * \brief Set operating mode to RIG_MODE_x with indicated passband width. * * Supported modes x= USB, LSB, CW, CWR, AM, FM, RTTY * \n This applies to currently selected receiver (Main Rx=Tx or Sub Rx) * \sa tt565_set_vfo * * \remarks Note widespread confusion between "VFO" and "Receiver". The Orion * has VFOs A and B which may be mapped to Main and Sub Receivers independently. * But Hamlib may have different ideas! */ int tt565_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; char ttmode, ttreceiver; int retval; char mdbuf[TT565_BUFSIZE]; switch (mode) { case RIG_MODE_USB: ttmode = TT565_USB; break; case RIG_MODE_LSB: ttmode = TT565_LSB; break; case RIG_MODE_CW: ttmode = TT565_CW; break; case RIG_MODE_CWR: ttmode = TT565_CWR; break; case RIG_MODE_AM: ttmode = TT565_AM; break; case RIG_MODE_FM: ttmode = TT565_FM; break; case RIG_MODE_RTTY: ttmode = TT565_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } ttreceiver = which_receiver(rig, vfo); if (rig->caps->rig_model == RIG_MODEL_TT599) { // Additional R%CF0 puts bandwidth control back to bandwidth knob SNPRINTF(mdbuf, sizeof(mdbuf), "*R%cM%c" EOM "*R%cF%d" EOM "R%cF0" EOM, ttreceiver, ttmode, ttreceiver, (int)width, ttreceiver ); } else { SNPRINTF(mdbuf, sizeof(mdbuf), "*R%cM%c" EOM "*R%cF%d" EOM, ttreceiver, ttmode, ttreceiver, (int)width ); } retval = write_block(RIGPORT(rig), (unsigned char *) mdbuf, strlen(mdbuf)); priv->mode = mode; priv->width = width; return retval; } /** * \param rig must != NULL * \param vfo * \param mode Receives current mode setting, must be != NULL * \param width Receives current bandwidth setting, must be != NULL * \returns RIG_OK or < 0 * \brief Get op. mode and bandwidth for selected vfo * * \remarks Confusion of VFO and Main/Sub TRx/Rx. See tt565_set_mode. */ int tt565_get_mode_cache(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *mode = priv->mode; *width = priv->width; return RIG_OK; } int tt565_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; char ttmode, ttreceiver; int retry; int timeout; int widthOld = CACHE(rig)->widthMainA; struct rig_state *rs = STATE(rig); ttreceiver = which_receiver(rig, vfo); /* Query mode */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cM" EOM, ttreceiver); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: tt565_transaction failed\n", __func__); return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'M' || resp_len <= 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } ttmode = respbuf[4]; switch (ttmode) { case TT565_USB: *mode = RIG_MODE_USB; break; case TT565_LSB: *mode = RIG_MODE_LSB; break; case TT565_CW: *mode = RIG_MODE_CW; break; case TT565_CWR: *mode = RIG_MODE_CWR; break; case TT565_AM: *mode = RIG_MODE_AM; break; case TT565_FM: *mode = RIG_MODE_FM; break; case TT565_RTTY: *mode = RIG_MODE_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, ttmode); return -RIG_EPROTO; } /* Query passband width (filter) */ // since this fails at 80ms sometimes we won't retry and will reduce the timeout // Normally this comes back in about 30ms retry = rs->retry; timeout = rs->timeout; rs->retry = 0; rs->timeout = 100; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cF" EOM, ttreceiver); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); rs->retry = retry; rs->timeout = timeout; if (retval != RIG_OK) { // if the width call fails we will just reuse the old width *width = widthOld; return RIG_OK; } if (respbuf[1] != 'R' || respbuf[3] != 'F' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *width = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param ts Tuning Step, Hz * \returns RIG_OK or < 0 * \brief Set Tuning Step for VFO A or B. */ int tt565_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int retval; char cmdbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cI%d" EOM, which_receiver(rig, vfo), (int)ts); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must != NULL * \param vfo * \param ts Receives Tuning Step, Hz * \returns RIG_OK or < 0 * \brief Get Tuning Step for VFO A or B. */ int tt565_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cI" EOM, which_receiver(rig, vfo)); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'I' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *ts = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param rit Rx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Set Rx incremental tuning * Note: command rit != 0 ==> rit "on"; rit == 0 ==> rit "off" */ int tt565_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int retval; char cmdbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cR%d" EOM, which_receiver(rig, vfo), (int)rit); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must != NULL * \param vfo * \param rit Receives Rx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Get Rx incremental tuning */ int tt565_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cR" EOM, which_receiver(rig, vfo)); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'R' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *rit = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param xit Tx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Set Tx incremental tuning (Main TRx only) * Note: command xit != 0 ==> xit "on"; xit == 0 ==> xit "off" */ int tt565_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { int retval; char cmdbuf[TT565_BUFSIZE]; /* Sub receiver does not contain an XIT setting */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cX%d" EOM, 'M', (int)xit); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must != NULL * \param vfo * \param xit Receives Tx incremental tuning, Hz * \returns RIG_OK or < 0 * \brief Get Tx incremental tuning (Main TRx only) */ int tt565_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int resp_len, retval; char cmdbuf[TT565_BUFSIZE], respbuf[TT565_BUFSIZE]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cX" EOM, 'M'); resp_len = sizeof(respbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'R' || respbuf[3] != 'X' || resp_len <= 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, respbuf); return -RIG_EPROTO; } *xit = atoi(respbuf + 4); return RIG_OK; } /** * \param rig must != NULL * \param vfo * \param ptt RIG_PTT_ON or RIG_PTT_OFF * \returns RIG_OK or < 0 * \brief Set push to talk (Tx on/off) */ int tt565_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; int retval = write_block(RIGPORT(rig), (unsigned char *)(ptt == RIG_PTT_ON ? "*TK" EOM : "*TU" EOM), 4); if (retval == RIG_OK) { priv->ptt = ptt; } return retval; } /** * \param rig must != NULL * \param vfo * \param ptt Receives RIG_PTT_ON or RIG_PTT_OFF * \returns RIG_OK or < 0 * \brief Get push to talk (Tx on/off) */ int tt565_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *ptt = priv->ptt; return RIG_OK; } /** * \param rig must != NULL * \param reset (not used) * \returns RIG_OK or < 0 * \brief Restart Orion firmware * * Sends an "X" command and listens for reply = "ORION START". This only * seems to test for healthy connection to the firmware. There is no effect * on Orion's state, AFAIK. */ int tt565_reset(RIG *rig, reset_t reset) { int retval, reset_len; char reset_buf[TT565_BUFSIZE]; if (reset == RIG_RESET_NONE) { return RIG_OK; } /* No operation requested. */ reset_len = sizeof(reset_buf); retval = tt565_transaction(rig, "XX" EOM, 3, reset_buf, &reset_len); if (retval != RIG_OK) { return retval; } if (!strstr(reset_buf, "ORION START")) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, reset_buf); return -RIG_EPROTO; } return RIG_OK; } /** * \param rig must != NULL * \returns firmware identification string or NULL * \brief Get firmware identification, e.g., "Version 1.372" * * Re-entrancy issue (what else is new?) */ const char *tt565_get_info(RIG *rig) { static char buf[TT565_BUFSIZE]; /* FIXME: reentrancy */ int firmware_len, retval, i; firmware_len = sizeof(buf); retval = tt565_transaction(rig, "?V" EOM, 3, buf, &firmware_len); if (retval != RIG_OK || firmware_len < 8) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG, len=%d\n", __func__, firmware_len); buf[0] = '\0'; return buf; } buf[firmware_len] = '\0'; /* filter out any non-graphic characters */ for (i = 0; i < strlen(buf); i++) if (!isgraph((int)buf[i])) { buf[i] = ' '; } // bad chars -> spaces return buf; } /** * \param rig must != NULL * \param vfo * \param level A level id token, e.g. RIG_LEVEL_AF * \param val Value for the level, on a scale or via a token * \returns RIG_OK or < 0 * \brief Sets any of Orion's "Level" adjustments * * Unfortunately, "val" type is not well defined. Sometimes it is a float (AF gain), * an integer (RF Atten.), or an enum (RIG_AGC_FAST)... * * Supported Levels and Units * \n -RIG_LEVEL_RFPOWER, float 0.0 - 1.0 * \n -RIG_LEVEL_AGC, int RIG_AGC_x, x= OFF, FAST, MEDIUM, SLOW, USER * \n -RIG_LEVEL_AF, float 0.0 - 1.0 * \n -RIG_LEVEL_IF, passband tuning, int Hz * \n -RIG_LEVEL_RF, IF gain (!), float 0.0 - 1.0 * \n -RIG_LEVEL_ATT, Atten. setting, int dB (we pick 0, 6, 12, or 18 dB) * \n -RIG_LEVEL_PREAMP, Preamp on/off, 0-1 (main Rx only) * \n -RIG_LEVEL_SQL, squelch, float 0.0 - 1.0 * \n -RIG_LEVEL_MICGAIN, float 0.0 - 1.0 * \n -RIG_LEVEL_COMP, speech compression, float 0.0 - 1.0 * \n -RIG_LEVEL_CWPITCH, int Hz * \n -RIG_LEVEL_KEYSPD, int wpm * \n -RIG_LEVEL_NR, noise reduction/blank, float 0.0 - 1.0 * \n -RIG_LEVEL_VOXDELAY, vox delay, float x 1/10 second * \n -RIG_LEVEL_VOXGAIN, float 0.0 - 1.0 * \n -RIG_LEVEL_ANTIVOX, float 0.0 - 1.0 * * \n FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int tt565_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, ii; char cmdbuf[TT565_BUFSIZE], cc; switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TP%d" EOM, (int)(val.f * 100)); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: cc = 'O'; break; case RIG_AGC_FAST: cc = 'F'; break; case RIG_AGC_MEDIUM: cc = 'M'; break; case RIG_AGC_SLOW: cc = 'S'; break; case RIG_AGC_USER: cc = 'P'; break; default: cc = 'M'; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cA%c" EOM, which_receiver(rig, vfo), cc); break; case RIG_LEVEL_AF: /* AF Gain, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*U%c%d" EOM, which_receiver(rig, vfo), (int)(val.f * 255)); break; case RIG_LEVEL_IF: /* This is passband tuning int Hz */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cP%d" EOM, which_receiver(rig, vfo), val.i); break; case RIG_LEVEL_RF: /* This is IF Gain, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cG%d" EOM, which_receiver(rig, vfo), (int)(val.f * 100)); break; case RIG_LEVEL_ATT: /* RF Attenuator, int dB */ ii = -1; /* Request 0-5 dB -> 0, 6-11 dB -> 6, etc. */ while (rig->caps->attenuator[++ii] != RIG_DBLST_END) { if (rig->caps->attenuator[ii] > val.i) { break; } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cT%d" EOM, which_receiver(rig, vfo), ii); break; case RIG_LEVEL_PREAMP: /* Sub receiver does not contain a Preamp */ if (which_receiver(rig, vfo) == 'S') { return -RIG_EINVAL; } /* RF Preamp (main Rx), int 0 or 1 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*RME%d" EOM, val.i == 0 ? 0 : 1); break; case RIG_LEVEL_SQL: /* Squelch level, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cS%d" EOM, which_receiver(rig, vfo), (int)((val.f * 127) - 127)); break; case RIG_LEVEL_MICGAIN: /* Mic gain, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TM%d" EOM, (int)(val.f * 100)); break; case RIG_LEVEL_COMP: /* Speech Processor, float 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TS%d" EOM, (int)(val.f * 9)); break; case RIG_LEVEL_CWPITCH: /* "CWPITCH" is the "Tone" button on the Orion. Manual menu adjustment works down to 100 Hz, but not via computer. int Hz. */ if (val.i > TT565_TONE_MAX) { val.i = TT565_TONE_MAX; } else if (val.i < TT565_TONE_MIN) { val.i = TT565_TONE_MIN; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*CT%d" EOM, val.i); break; case RIG_LEVEL_KEYSPD: /* Keyer speed setting does not imply Keyer = "on". That is a command which should be a hamlib function, but is not. Keyer speed determines the rate of computer sent CW also. */ if (val.i > TT565_CW_MAX) { val.i = TT565_CW_MAX; } else if (val.i < TT565_CW_MIN) { val.i = TT565_CW_MIN; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "*CS%d" EOM, val.i); break; case RIG_LEVEL_NR: if (rig->caps->rig_model == RIG_MODEL_TT599) { ii = (int)(val.f * 10); if (ii > 9) { ii = 9; } // cannot set NR level 10 apparently SNPRINTF(cmdbuf, sizeof(cmdbuf), "*RMNN%c" EOM, ii); } else { /* Noise Reduction (blanking) Float 0.0 - 1.0 For some reason NB setting is supported in 1.372, but NR, NOTCH, and AN are not. FOR NOW -- RIG_LEVEL_NR controls the Orion NB setting */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*R%cNB%d" EOM, which_receiver(rig, vfo), (int)(val.f * 9)); } break; case RIG_LEVEL_VOXDELAY: /* VOX delay, float tenths of seconds */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TH%4.2f" EOM, 0.1 * val.f); break; case RIG_LEVEL_VOXGAIN: /* Float, 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TG%d" EOM, (int)(100.0 * val.f)); break; case RIG_LEVEL_ANTIVOX: /* Float, 0.0 - 1.0 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "*TA%d" EOM, (int)(100.0 * val.f)); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig must be != NULL * \param vfo * \param level identifier for level of interest * \param val Receives level's value, must != NULL * \brief Get the current value of an Orion "level" * * \sa tt565_get_level * Supported rx levels: * \n -RIG_LEVEL_SWR * \n -RIG_LEVEL_RAWSTR, int raw rx signal strength (rig units) * \n -RIG_LEVEL_RFPOWER * \n -RIG_LEVEL_AGC * \n -RIG_LEVEL_AF * \n -RIG_LEVEL_IF * \n -RIG_LEVEL_RF * \n -RIG_LEVEL_ATT * \n -RIG_LEVEL_PREAMP * \n -RIG_LEVEL_SQL * \n -RIG_LEVEL_MICGAIN * \n -RIG_LEVEL_COMP * \n -RIG_LEVEL_CWPITCH * \n -RIG_LEVEL_KEYSPED * \n -RIG_LEVEL_NR * \n -RIG_LEVEL_VOX * \n -RIG_LEVEL_VOXGAIN * \n -RIG_LEVEL_ANTIVOX * * (RIG_LEVEL_STRENGTH, int calibrated signal strength (dB, S9 = 0) is * handled in settings.c) */ int tt565_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; char cmdbuf[TT565_BUFSIZE], lvlbuf[TT565_BUFSIZE]; /* Optimize: sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_SWR: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?S" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (rig->caps->rig_model == RIG_MODEL_TT599) { /* in Xmit, response is @STF99R10 99 watts forward,1.0 watt reflected uu = fwd watts vv = rev watts x 10 in Rcv, response is @SRM16 Indicates 16 dbm uuu = 000-100 (apx) Main S meter */ if (lvlbuf[1] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[2] == 'T') { double fwd, ref; ref = atof(strchr(lvlbuf + 2, 'R') + 1) / 10.0; /* reflected power */ fwd = atof(strchr(lvlbuf + 2, 'F') + 1); /* forward power */ if (fwd == 0.0) { val->f = 0.0; /* no forward power */ } else if (fwd == ref) /* too high SWR */ { val->f = 9.99; } else { val->f = (1 + sqrt(ref / fwd)) / (1 - sqrt(ref / fwd)); /* calculate SWR */ } if (val->f < 1.0) { val->f = 9.99; } /* high VSWR */ } else { val->f = 0.0; } /* SWR in Receive = 0.0 */ } else { /* in Xmit, response is @STFuuuRvvvSwww (or ...Swwww) uuu = 000-100 (apx) fwd watts vvv = 000-100 rev watts www = 256-999 256 * VSWR in Rcv, response is @SRMuuuSvvv uuu = 000-100 (apx) Main S meter vvv = 000-100 (apx) Sub S meter */ if (lvlbuf[1] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[2] == 'T') { val->f = atof(strchr(lvlbuf + 5, 'S') + 1) / 256.0; if (val->f < 1.0) { val->f = 9.99; } /* high VSWR */ } else { val->f = 0.0; } /* SWR in Receive = 0.0 */ } break; case RIG_LEVEL_RAWSTR: /* provide uncalibrated raw strength, int */ /* NB: RIG_LEVEL_STRENGTH is handled in the frontend */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?S" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[2] == 'R') { char *raw_field; /* response is @SRMnnnSnnn, incl main & sub rx. */ /* TT's spec indicates variable length data 1-3 digits */ if (vfo == RIG_VFO_SUB) /* look at sub rx info */ { raw_field = strchr(lvlbuf + 3, 'S') + 1; /* length may vary */ } else /* look at main rx info */ { char *raw_field2; raw_field = lvlbuf + 4; raw_field2 = strchr(raw_field, 'S'); /* position may vary */ if (raw_field2) { *raw_field2 = '\0'; } /* valid string */ } val->i = atoi(raw_field); /* get raw value */ } else { val->i = 0; } /* S-meter in xmit => 0 */ break; case RIG_LEVEL_RFPOWER: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TP" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'P' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 100.0; break; case RIG_LEVEL_AGC: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cA" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'A' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } switch (lvlbuf[4]) { case 'O': val->i = RIG_AGC_OFF; break; case 'F': val->i = RIG_AGC_FAST; break; case 'M': val->i = RIG_AGC_MEDIUM; break; case 'S': val->i = RIG_AGC_SLOW; break; case 'P': val->i = RIG_AGC_USER; break; default: return -RIG_EPROTO; } break; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?U%c" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'U' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 255.0; break; case RIG_LEVEL_IF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cP" EOM, /* passband tuning */ which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'P' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = atoi(lvlbuf + 4); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cG" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'G' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 4) / 100.0; break; case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cT" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'T' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } if (lvlbuf[4] == '0') { val->i = 0; } else { val->i = rig->caps->attenuator[lvlbuf[4] - '1']; } break; case RIG_LEVEL_PREAMP: /* Sub receiver does not contain a Preamp */ if (which_receiver(rig, vfo) == 'S') { val->i = 0; break; } lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?RME" EOM, 5, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'E' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = lvlbuf[4] == '0' ? 0 : rig->caps->preamp[0]; break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cS" EOM, which_receiver(rig, vfo)); lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvlbuf[3] != 'S' || lvl_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = (atof(lvlbuf + 4) + 127.0) / 127.0; break; case RIG_LEVEL_MICGAIN: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TM" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'M' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 100.0; break; case RIG_LEVEL_COMP: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'S' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = atof(lvlbuf + 3) / 9.0; break; case RIG_LEVEL_CWPITCH: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?CT" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'C' || lvlbuf[2] != 'T' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = atoi(lvlbuf + 3); break; case RIG_LEVEL_KEYSPD: lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?CS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'C' || lvlbuf[2] != 'S' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->i = atoi(lvlbuf + 3); break; case RIG_LEVEL_NR: /* RIG_LEVEL_NR controls Orion NB setting - TEMP */ if (rig->caps->rig_model == RIG_MODEL_TT599) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "?RMNN" EOM) } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "?R%cNB" EOM, which_receiver(rig, vfo)); } lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'R' || lvl_len < 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } sscanf(lvlbuf + 5, "%f", &val->f); val->f /= 10.0; break; case RIG_LEVEL_VOXDELAY: /* =VOXDELAY, tenths of secs. */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TH" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'H' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = 10.0 * atof(lvlbuf + 3); break; case RIG_LEVEL_VOXGAIN: /* Float, 0.0 - 1.0 */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TG" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'G' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = 0.01 * atof(lvlbuf + 3); break; case RIG_LEVEL_ANTIVOX: /* Float, 0.0 - 1.0 */ lvl_len = sizeof(lvlbuf); retval = tt565_transaction(rig, "?TA" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[1] != 'T' || lvlbuf[2] != 'A' || lvl_len < 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer '%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f = 0.01 * atof(lvlbuf + 3); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /** * \param rig !=NULL * \param vfo * \param ch Channel number * \returns RIG_OK * \brief This only sets the current memory channel locally. No Orion I/O. * * Use RIG_OP_TO_VFO and RIG_OP_FROM_VFO to get/store a freq in the channel. * \sa tt565_vfo_op */ int tt565_set_mem(RIG *rig, vfo_t vfo, int ch) { struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; priv->ch = ch; /* See RIG_OP_TO/FROM_VFO */ return RIG_OK; } /** * \param rig != NULL * \param vfo * \param ch to receive the current channel number * \returns RIG_OK * \brief Get the current memory channel number (only) */ int tt565_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; *ch = priv->ch; return RIG_OK; } /** * \param rig != NULL * \param vfo * \param op Operation to perform, a RIG_OP token * \returns RIG_OK or < 0 * \brief perform a RIG_OP operation * * Supported operations: * \n RIG_OP_TO_VFO memory channel to VFO (includes bw, mode, etc) * \n RIG_OP_FROM_VFO stores VFO (& other data) to memory channel * \n RIG_OP_TUNE initiates a tuner cycle (if tuner present) MAY BE BROKEN * \n RIG_OP_UP increment VFO freq by tuning step * \n RIG_OP_DOWN decrement VFO freq by tuning step */ int tt565_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct tt565_priv_data *priv = (struct tt565_priv_data *)STATE(rig)->priv; char cmdbuf[TT565_BUFSIZE]; int retval; switch (op) { case RIG_OP_TO_VFO: case RIG_OP_FROM_VFO: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*K%c%c%d" EOM, op == RIG_OP_TO_VFO ? 'R' : 'W', which_vfo(rig, vfo), priv->ch); break; case RIG_OP_TUNE: strcpy(cmdbuf, "*TTT" EOM); break; case RIG_OP_UP: case RIG_OP_DOWN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "*%cS%c1" EOM, which_vfo(rig, vfo), op == RIG_OP_UP ? '+' : '-'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported op %d\n", __func__, op); return -RIG_EINVAL; } retval = tt565_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); return retval; } /** * \param rig * \param vfo * \param msg A message string (<= 20 char) * \returns RIG_OK * \brief Send a string as morse characters * * Orion keyer must be on for morse, but we do not have a "keyer on" function in * hamlib (yet). Keyer will be forced on. * * Orion can queue up to about 20 characters. * We could batch a longer message into 20 char chunks, but there is no * simple way to tell if message has completed. We could calculate a * duration based on keyer speed and the text that was sent, but * what we really need is a handshake for "message complete". * Without it, you can't easily use the Orion as a code practice machine. * For now, we let the user do the batching. * Note that rig panel is locked up for duration of message. */ int tt565_send_morse(RIG *rig, vfo_t vfo, const char *msg) { int msg_len, retval, ic; char morsecmd[8]; static int keyer_set = FALSE; /*Shouldn't be here!*/ /* Force keyer on. */ if (!keyer_set) { retval = tt565_transaction(rig, "*CK1" EOM, 5, NULL, NULL); if (retval != RIG_OK) { return retval; } keyer_set = TRUE; hl_usleep(100000); /* 100 msec - guess */ } msg_len = strlen(msg); if (msg_len > 20) { msg_len = 20; } /* sanity limit 20 chars */ for (ic = 0; ic < msg_len; ic++) { SNPRINTF(morsecmd, sizeof(morsecmd), "/%c" EOM, msg[ic]); retval = tt565_transaction(rig, morsecmd, strlen(morsecmd), NULL, NULL); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /** * \param rig != NULL * \param vfo * \param func Identifier for function to be performed * \param status data for function * \returns RIG_OK or < 0 * \brief Set an Orion "function" * * Note that vfo must == RIG_VFO_CURR * * Supported functions & data * \n RIG_FUNC_TUNER, off/on, 0/1 * \n RIG_FUNC_VOX, off/on, 0/1 * \n RIG_FUNC_LOCK, unlock/lock, 0/1 * \n RIG_FUNC_NB, off/on, 0/1 (sets Orion NB=0 or =4), compare RIG_LEVEL_NR * */ int tt565_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char fcmdbuf[TT565_BUFSIZE]; int retval; if (vfo != RIG_VFO_CURR) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_TUNER: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*TT%c" EOM, !status ? 0 : 1); break; case RIG_FUNC_VOX: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*TV%c" EOM, !status ? 0 : 1); break; case RIG_FUNC_LOCK: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*%c%c" EOM, which_vfo(rig, vfo), !status ? 'U' : 'L'); break; case RIG_FUNC_NB: /* NB "on" sets Orion NB=4; "off" -> NB=0. See also RIG_LEVEL_NR which maps to NB setting due to firmware limitation. */ SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "*R%cNB%c" EOM, which_receiver(rig, vfo), !status ? '0' : '4'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /** * \param rig != NULL * \param vfo must == RIG_VFO_CURR * \param func * \param status receives result of function query * \returns RIG_OK or < 0 * \brief get state of an Orion "function" * * \sa tt565_set_func */ int tt565_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char fcmdbuf[TT565_BUFSIZE], frespbuf[TT565_BUFSIZE]; int retval, fresplen; if (vfo != RIG_VFO_CURR) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_TUNER: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?TT" EOM); break; case RIG_FUNC_VOX: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?TV" EOM); break; case RIG_FUNC_LOCK: SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?%cU" EOM, which_vfo(rig, vfo)); /* needs special treatment */ fresplen = sizeof(frespbuf); retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } /* response is @AL @AU or @BL @BU */ *status = frespbuf[ 2 ] == 'L' ? 1 : 0; return RIG_OK; case RIG_FUNC_NB: /* Note NB should be a LEVEL for Orion. It is also available through LEVEL_NR */ SNPRINTF(fcmdbuf, sizeof(fcmdbuf), "?R%cNB" EOM, which_receiver(rig, vfo)); /* needs special treatment */ fresplen = sizeof(frespbuf); retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } /* response is @RxNBn, n=0--9. Return 0 iff receive NB=0 */ *status = frespbuf[ 5 ] == '0' ? 0 : 1; return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } fresplen = sizeof(frespbuf); retval = tt565_transaction(rig, fcmdbuf, strlen(fcmdbuf), frespbuf, &fresplen); if (retval != RIG_OK) { return retval; } *status = frespbuf[ 3 ] == '1' ? 1 : 0; return RIG_OK; } /** * \param rig != NULL * \param vfo * \param ant antenna identifier RIG_ANT_1 or RIG_ANT_2 * \returns RIG_OK or < 0 * \brief Antenna selection for Orion * * We support Ant_1 and Ant_2 for M and S receivers. * \n Note that Rx-only antenna (Ant_3?) is not supported at this time. * \n Orion command assigns MSBN (main rtx, sub rx, both, or none) to each ant, * but hamlib wants to assign an ant to rx/tx! * The efficient way would be to keep current config in rig priv area, but we will * ask the rig what its state is each time... */ int tt565_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char respbuf[TT565_BUFSIZE]; int resp_len, retval; ant_t main_ant, sub_ant; /* First, find out what antenna config is now. */ resp_len = sizeof(respbuf); retval = tt565_transaction(rig, "?KA" EOM, 4, respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (resp_len != 7 || respbuf[1] != 'K' || respbuf[2] != 'A') { rig_debug(RIG_DEBUG_ERR, "%s; tt565_set_ant: ?KA NG %s\n", __func__, respbuf); return -RIG_EPROTO; } /* respbuf="@KAxxx" * x='M'|'S'|'B'|'N'=main/sub/both/none for ants 1,2,3. * but hardware will not permit all combinations! * respbuf [3,4] can be MS, SM, BN, NB * decode to rx-centric view */ if (respbuf[3] == 'M' || respbuf[3] == 'B') { main_ant = RIG_ANT_1; } else { main_ant = RIG_ANT_2; } if (respbuf[3] == 'S' || respbuf[3] == 'B') { sub_ant = RIG_ANT_1; } else { sub_ant = RIG_ANT_2; } switch (which_receiver(rig, vfo)) { case 'M': main_ant = ant; break; case 'S': sub_ant = ant; break; default: { /* no change? */ } } /* re-encode ant. settings into command */ if (main_ant == RIG_ANT_1) { if (sub_ant == RIG_ANT_1) { respbuf[3] = 'B'; respbuf[4] = 'N'; } else { respbuf[3] = 'M'; respbuf[4] = 'S'; } } else if (sub_ant == RIG_ANT_2) { respbuf[3] = 'N'; respbuf[4] = 'B'; } else { respbuf[3] = 'S'; respbuf[4] = 'M'; } respbuf[0] = '*'; /* respbuf becomes a store command */ respbuf[5] = 'N'; /* Force no rx on Ant 3 */ respbuf[6] = EOM[0]; respbuf[7] = 0; retval = tt565_transaction(rig, respbuf, 7, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /** * \param rig != NULL * \param vfo * \param ant receives antenna identifier * \returns RIG_OK or < 0 * \brief Find what antenna is "attached" to our vfo * * \sa tt565_set_ant */ int tt565_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char respbuf[TT565_BUFSIZE]; int resp_len, retval; resp_len = sizeof(respbuf); retval = tt565_transaction(rig, "?KA" EOM, 4, respbuf, &resp_len); if (retval != RIG_OK) { return retval; } if (respbuf[1] != 'K' || respbuf[2] != 'A' || resp_len != 7) { rig_debug(RIG_DEBUG_ERR, "%s; tt565_get_ant: NG %s\n", __func__, respbuf); return -RIG_EPROTO; } /* Look for first occurrence of M or S in ant 1, 2, 3 characters */ if (respbuf[3] == which_receiver(rig, vfo) || respbuf[3] == 'B') { *ant_curr = RIG_ANT_1; return RIG_OK; } if (respbuf[4] == which_receiver(rig, vfo) || respbuf[4] == 'B') { *ant_curr = RIG_ANT_2; return RIG_OK; } *ant_curr = RIG_ANT_NONE; /* ignore possible RIG_ANT_3 = rx only ant */ return RIG_OK; } /* End of orion.c */ /** @} */ hamlib-4.6.2/rigs/tentec/tentec.h0000644000175000017500000000556314752216205013576 00000000000000/* * Hamlib Tentec backend - main header * Copyright (c) 2001-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /** * \addtogroup tentec * @{ */ /** * \file tentec.h * \brief Includes for Tentec Backends */ #ifndef _TENTEC_H #define _TENTEC_H 1 #include // The include order will determine which BACKEND_VER is used // tentec2.h may also be included and the last include is the BACKEND_VER used #undef BACKEND_VER #define BACKEND_VER "20200113" /** * \brief Private tentec info */ struct tentec_priv_data { rmode_t mode; /*!< detection mode */ freq_t freq; /*!< tuned frequency */ pbwidth_t width; /*!< filter bandwidth in Hz */ int cwbfo; /*!< BFO frequency: 1000 [0-2000Hz] */ int pbt; /*!< Passband Tuning, IF shift: 0 [-2000Hz to 2000Hz] */ float lnvol; /*!< line-out volume: 30 [0..63] */ float spkvol; /*!< speaker volume: 30 [0..63] */ int agc; /*!< AGC: medium */ /* calculated by tentec_tuning_factor_calc() */ int ctf; /*!< Coarse Tune Factor */ int ftf; /*!< Fine Tune Factor */ int btf; /*!< Bfo Tune Factor, btval is ignored by RX-320 in AM MODE */ }; int tentec_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); int tentec_init(RIG *rig); int tentec_cleanup(RIG *rig); int tentec_trx_open(RIG *rig); int tentec_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int tentec_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int tentec_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int tentec_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int tentec_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int tentec_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); const char* tentec_get_info(RIG *rig); extern struct rig_caps rx320_caps; extern struct rig_caps rx340_caps; extern struct rig_caps rx350_caps; extern struct rig_caps tt516_caps; extern struct rig_caps tt538_caps; extern struct rig_caps tt585_caps; extern struct rig_caps tt588_caps; extern struct rig_caps tt550_caps; extern struct rig_caps tt565_caps; extern struct rig_caps tt599_caps; extern struct rig_caps rx331_caps; #endif /* _TENTEC_H */ /** @} */ hamlib-4.6.2/rigs/motorola/0000755000175000017500000000000014752216245012570 500000000000000hamlib-4.6.2/rigs/motorola/Makefile.am0000644000175000017500000000022414752216205014536 00000000000000RSSRC = motorola.c micom.c motorola.h noinst_LTLIBRARIES = libhamlib-motorola.la libhamlib_motorola_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/motorola/motorola.h0000644000175000017500000000020314752216205014504 00000000000000#ifndef _MOTOROLA_H #define _MOTOROLADUMMY_H 1 #include "hamlib/rig.h" extern struct rig_caps micom_caps; #endif // _MOTOROLA_H hamlib-4.6.2/rigs/motorola/Makefile.in0000644000175000017500000005243214752216216014561 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/motorola ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_motorola_la_LIBADD = am__objects_1 = motorola.lo micom.lo am_libhamlib_motorola_la_OBJECTS = $(am__objects_1) libhamlib_motorola_la_OBJECTS = $(am_libhamlib_motorola_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/micom.Plo ./$(DEPDIR)/motorola.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_motorola_la_SOURCES) DIST_SOURCES = $(libhamlib_motorola_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RSSRC = motorola.c micom.c motorola.h noinst_LTLIBRARIES = libhamlib-motorola.la libhamlib_motorola_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/motorola/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/motorola/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-motorola.la: $(libhamlib_motorola_la_OBJECTS) $(libhamlib_motorola_la_DEPENDENCIES) $(EXTRA_libhamlib_motorola_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_motorola_la_OBJECTS) $(libhamlib_motorola_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/micom.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motorola.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/micom.Plo -rm -f ./$(DEPDIR)/motorola.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/micom.Plo -rm -f ./$(DEPDIR)/motorola.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/motorola/motorola.c0000644000175000017500000000205014752216205014501 00000000000000/* * Hamlib Motorola backend - main file * Copyright (c) 2024 Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "motorola.h" #include DECLARE_INITRIG_BACKEND(motorola) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&micom_caps); return RIG_OK; } hamlib-4.6.2/rigs/motorola/micom.c0000644000175000017500000001617314752216205013764 00000000000000/* * Hamlib Motorola Micom backend - main file * Copyright (c) 2024 Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include // char* to start of checksum for len bytes unsigned int checksum(unsigned char *buf, int len) { int checksum = 0; int i; // simple 1-byte checksum for (i = 0; i < len; ++i) { checksum += buf[i]; } return checksum & 0xff; } static int micom_open(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } // returns bytes read // format has length in byte[1] plus 5 bytes 0x24/len/cmd at start and checksum+0x03 at end // So a data "length" of 5 is 10 bytes for example static int micom_read_frame(RIG *rig, unsigned char *buf, int maxlen) { hamlib_port_t *rp = RIGPORT(rig); int bytes; //const char stopset[1] = {0x03}; ENTERFUNC; bytes = read_block(rp, buf, 3); if (bytes + buf[1] + 2 > maxlen) { rig_debug(RIG_DEBUG_ERR, "%s: buffer overrun...expected max of %d, got %d\n", __func__, maxlen, bytes + buf[1] + 2); dump_hex(buf, bytes); RETURNFUNC(-RIG_EPROTO); } bytes += read_block(rp, &buf[3], buf[1] + 2); dump_hex(buf, bytes); RETURNFUNC(bytes); } /* Example of set of commands that works 24 06 18 05 01 00 38 ea 50 ba 03 15 24 05 18 36 fe 7b ef 01 e0 03 15 24 05 18 36 ff 7b ef 01 e1 03 15 24 05 18 36 df 7b ef 01 c1 03 15 24 05 18 36 ff 7b ef 01 e1 03 */ static int micom_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { hamlib_port_t *rp = RIGPORT(rig); unsigned char rxcmd[12] = { 0x24, 0x06, 0x18, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x15 }; unsigned char cmd2[11] = { 0x24, 0x05, 0x18, 0x36, 0xfe, 0x7b, 0xef, 0x01, 0xe0, 0x03, 0x15 }; unsigned char cmd3[11] = { 0x24, 0x05, 0x18, 0x36, 0xfe, 0x7b, 0xef, 0x01, 0xe1, 0x03, 0x15 }; unsigned char cmd4[11] = { 0x24, 0x05, 0x18, 0x36, 0xdf, 0x7b, 0xef, 0x01, 0xc1, 0x03, 0x15 }; unsigned char cmd5[10] = { 0x24, 0x05, 0x18, 0x36, 0xff, 0x7b, 0xef, 0x01, 0xe1, 0x03 }; //unsigned char txcmd[11] = { 0x24, 0x05, 0x81, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 }; unsigned int ifreq = freq; unsigned char reply[11]; int retval; rxcmd[5] = (ifreq >> 24) & 0xff; rxcmd[6] = (ifreq >> 16) & 0xff; rxcmd[7] = (ifreq >> 8) & 0xff; rxcmd[8] = ifreq & 0xff; rxcmd[9] = checksum(rxcmd, 9); set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, rxcmd, sizeof(rxcmd)); micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd2, sizeof(cmd2)); } micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd3, sizeof(cmd3)); } micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd4, sizeof(cmd4)); } micom_read_frame(rig, reply, sizeof(reply)); if (retval == RIG_OK) { retval = write_block(rp, cmd5, sizeof(cmd5)); } micom_read_frame(rig, reply, sizeof(reply)); micom_read_frame(rig, reply, sizeof(reply)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err: %s\n", __func__, rigerror(retval)); set_transaction_inactive(rig); return retval; } micom_read_frame(rig, reply, sizeof(reply)); #if 0 // this method doesn't work txcmd[5] = (ifreq >> 16) & 0xff; txcmd[6] = (ifreq >> 8) & 0xff; txcmd[7] = ifreq & 0xff; txcmd[8] = checksum(txcmd, 8); txcmd[5] = (ifreq >> 24) & 0xff; txcmd[6] = (ifreq >> 16) & 0xff; txcmd[7] = (ifreq >> 8) & 0xff; txcmd[8] = ifreq & 0xff; txcmd[9] = checksum(rxcmd, 9); retval = write_block(rp, txcmd, sizeof(txcmd)); micom_read_frame(rig, reply, sizeof(reply)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err: %s\n", __func__, rigerror(retval)); set_transaction_inactive(rig); return retval; } #endif set_transaction_inactive(rig); return retval; } static int micom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { hamlib_port_t *rp = RIGPORT(rig); unsigned char cmd[6] = { 0x24, 0x01, 0x18, 0x06, 0x06, 0x03 }; unsigned char ack[6] = { 0x24, 0x01, 0x18, 0xf3, 0xff, 0x03 }; unsigned char reply[11]; int retval; cmd[4] = checksum(cmd, 4); set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, cmd, sizeof(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err: %s\n", __func__, rigerror(retval)); set_transaction_inactive(rig); return retval; } // expecting 24 01 80 fe 98 03 -- an ack packet? micom_read_frame(rig, reply, sizeof(reply)); if (reply[3] != 0xfe) { rig_debug(RIG_DEBUG_ERR, "%s: unknown packet...expected byte 4 = 0xfe\n", __func__); } micom_read_frame(rig, reply, sizeof(reply)); write_block(rp, ack, sizeof(ack)); set_transaction_inactive(rig); *freq = (reply[4] << 24) | (reply[5] << 16) | (reply[6] << 8) | reply[7]; RETURNFUNC2(RIG_OK); } static int micom_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { hamlib_port_t *rp = RIGPORT(rig); unsigned char on[] = { 0x24, 0x02, 0x81, 0x13, 0x01, 0xBB, 0x03 }; unsigned char off[] = { 0x24, 0x02, 0x81, 0x14, 0x01, 0xBC, 0x03 }; int retval; set_transaction_active(rig); rig_flush(rp); retval = write_block(rp, ptt ? on : off, sizeof(on)); set_transaction_inactive(rig); return retval; } struct rig_caps micom_caps = { RIG_MODEL(RIG_MODEL_MICOM2), .model_name = "Micom 2/3", .mfg_name = "Micom", .version = "20240504.0", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .timeout = 500, .rig_open = micom_open, .set_freq = micom_set_freq, .get_freq = micom_get_freq, .set_ptt = micom_set_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/motorola/Android.mk0000644000175000017500000000040614752216205014415 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := motorola.c micom.c LOCAL_MODULE := motorola LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/jrc/0000755000175000017500000000000014752216243011510 500000000000000hamlib-4.6.2/rigs/jrc/jrc.h0000644000175000017500000000524614752216205012364 00000000000000/* * Hamlib JRC backend - main header * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _JRC_H #define _JRC_H 1 #include #define BACKEND_VER "20200320" struct jrc_priv_caps { int max_freq_len; int info_len; int mem_len; int pbs_info_len; int pbs_len; int beep; int beep_len; const char * cw_pitch; }; int jrc_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); int jrc_open(RIG *rig); int jrc_close(RIG *rig); int jrc_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int jrc_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int jrc_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int jrc_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int jrc_set_vfo(RIG *rig, vfo_t vfo); int jrc_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int jrc_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int jrc_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int jrc_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int jrc_set_parm(RIG *rig, setting_t parm, value_t val); int jrc_get_parm(RIG *rig, setting_t parm, value_t *val); int jrc_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int jrc_set_trn(RIG *rig, int trn); int jrc_set_mem(RIG *rig, vfo_t vfo, int ch); int jrc_get_mem(RIG *rig, vfo_t vfo, int *ch); int jrc_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan); int jrc_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int jrc_set_powerstat(RIG *rig, powerstat_t status); int jrc_get_powerstat(RIG *rig, powerstat_t *status); int jrc_reset(RIG *rig, reset_t reset); int jrc_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int jrc_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); int jrc_decode_event(RIG *rig); extern struct rig_caps nrd535_caps; extern struct rig_caps nrd545_caps; extern struct rig_caps nrd525_caps; extern struct rig_caps jst145_caps; extern struct rig_caps jst245_caps; #endif /* _JRC_H */ hamlib-4.6.2/rigs/jrc/nrd535.c0000644000175000017500000001370414752216205012617 00000000000000/* * Hamlib JRC backend - NRD-535 DSP description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "jrc.h" #define NRD535_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_ECSS|RIG_MODE_FAX) /* + FAX */ #define NRD535_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB) #define NRD535_LEVEL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ATT|RIG_LEVEL_IF|RIG_LEVEL_AGC|RIG_LEVEL_CWPITCH) /*RIG_LEVEL_BWC*/ /* FIXME: add more from "U" command */ #define NRD535_PARM (RIG_PARM_TIME|RIG_PARM_BEEP) #define NRD535_VFO (RIG_VFO_VFO|RIG_VFO_MEM) /* * NRD-535, specs from http://mods.dk * * FIXME: measure S-meter levels */ #define NRD535_STR_CAL { 16, { \ { 0, 60 }, \ { 71, 50 }, \ { 75, 40 }, \ { 81, 30 }, \ { 87, 20 }, \ { 93, 10 }, \ { 100, 0 }, \ { 103, -6 }, \ { 107, -12 }, \ { 112, -18 }, \ { 118, -24 }, \ { 124, -30 }, \ { 133, -36 }, \ { 143, -42 }, \ { 152, -48 }, \ { 255, -60 }, \ } } /* * channel caps. */ #define NRD535_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .funcs = RIG_FUNC_FAGC, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_AGC, \ } static const struct jrc_priv_caps nrd535_priv_caps = { .max_freq_len = 8, .info_len = 14, .mem_len = 17, .pbs_info_len = 7, .pbs_len = 4, .beep = 90, .beep_len = 2, .cw_pitch = "U2" }; /* * NRD-535 rig capabilities. * */ struct rig_caps nrd535_caps = { RIG_MODEL(RIG_MODEL_NRD535), .model_name = "NRD-535D", .mfg_name = "JRC", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 21, .timeout = 250, .retry = 3, .has_get_func = NRD535_FUNC, .has_set_func = NRD535_FUNC, .has_get_level = NRD535_LEVEL, .has_set_level = RIG_LEVEL_SET(NRD535_LEVEL), .has_get_parm = RIG_PARM_TIME, .has_set_parm = RIG_PARM_SET(NRD535_PARM), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 20 } }, [LVL_IF] = { .min = { .i = -2000 }, .max = { .i = 2000 } }, [LVL_CWPITCH] = { .min = { .i = -5000 }, .max = { .i = 5000 } }, /*[LVL_BWC] = { .min = { .i = 500 }, .max = { .i = 5500 }, .step = { .i = 10} },*/ }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_STOP | RIG_SCAN_SLCT, .bank_qty = 0, .chan_desc_sz = 0, .priv = (void *)& nrd535_priv_caps, .chan_list = { { 0, 199, RIG_MTYPE_MEM, NRD535_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(30), NRD535_MODES, -1, -1, NRD535_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), NRD535_MODES, -1, -1, NRD535_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {NRD535_MODES, 1}, {NRD535_MODES, 10}, {NRD535_MODES, 100}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(2)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .str_cal = NRD535_STR_CAL, .rig_open = jrc_open, .rig_close = jrc_close, .set_freq = jrc_set_freq, .get_freq = jrc_get_freq, .set_mode = jrc_set_mode, .get_mode = jrc_get_mode, .set_vfo = jrc_set_vfo, .set_func = jrc_set_func, .get_func = jrc_get_func, .set_level = jrc_set_level, .get_level = jrc_get_level, .set_parm = jrc_set_parm, .get_parm = jrc_get_parm, .get_dcd = jrc_get_dcd, .set_trn = jrc_set_trn, .reset = jrc_reset, .set_mem = jrc_set_mem, .get_mem = jrc_get_mem, .set_channel = jrc_set_chan, .get_channel = jrc_get_chan, .vfo_op = jrc_vfo_op, .scan = jrc_scan, .set_powerstat = jrc_set_powerstat, .get_powerstat = jrc_get_powerstat, .decode_event = jrc_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/jrc/nrd545.c0000644000175000017500000001455214752216205012622 00000000000000/* * Hamlib JRC backend - NRD-545 DSP description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "jrc.h" #define NRD545_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_AMS|RIG_MODE_ECSS) #define NRD545_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_LOCK|RIG_FUNC_BC|RIG_FUNC_NR|RIG_FUNC_MN) #define NRD545_LEVEL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ATT|RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_IF|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|RIG_LEVEL_SQL|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH) /*RIG_LEVEL_BWC*/ /* FIXME: add more from "U" command */ #define NRD545_PARM (RIG_PARM_TIME|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define NRD545_VFO (RIG_VFO_VFO|RIG_VFO_MEM) /* * FIXME: measure S-meter levels */ #define NRD545_STR_CAL { 16, { \ { 0, -60 }, \ { 36, -48 }, \ { 42, -42 }, \ { 48, -36 }, \ { 55, -30 }, \ { 60, -24 }, \ { 67, -18 }, \ { 72, -12 }, \ { 78, -6 }, \ { 87, 0 }, \ { 107, 10 }, \ { 126, 20 }, \ { 146, 30 }, \ { 164, 40 }, \ { 186, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define NRD545_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_AGC, \ } static const struct jrc_priv_caps nrd545_priv_caps = { .max_freq_len = 10, .info_len = 18, .mem_len = 21, .pbs_info_len = 6, .pbs_len = 3, .beep = 100, .beep_len = 3, .cw_pitch = "U14" }; /* * NRD-545 rig capabilities. * */ struct rig_caps nrd545_caps = { RIG_MODEL(RIG_MODEL_NRD545), .model_name = "NRD-545 DSP", .mfg_name = "JRC", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = NRD545_FUNC, .has_set_func = NRD545_FUNC, .has_get_level = NRD545_LEVEL, .has_set_level = RIG_LEVEL_SET(NRD545_LEVEL), .has_get_parm = RIG_PARM_TIME, .has_set_parm = RIG_PARM_SET(NRD545_PARM), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 20 } }, [LVL_IF] = { .min = { .i = -2550 }, .max = { .i = 2550 }, .step = { .i = 10} }, [LVL_NOTCHF] = { .min = { .i = -1023 }, .max = { .i = 1023 } }, [LVL_CWPITCH] = { .min = { .i = -2550 }, .max = { .i = 2550 } }, /*[LVL_BWC] = { .min = { .i = 10 }, .max = { .i = 9990 }, .step = { .i = 10} },*/ }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, /* To be confirmed */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(2.3), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .vfo_ops = RIG_OP_FROM_VFO | RIG_OP_UP | RIG_OP_DOWN, .scan_ops = RIG_SCAN_STOP | RIG_SCAN_SLCT, .bank_qty = 0, .chan_desc_sz = 0, .priv = (void *)& nrd545_priv_caps, .chan_list = { { 0, 999, RIG_MTYPE_MEM, NRD545_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), NRD545_MODES, -1, -1, NRD545_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {NRD545_MODES, 1}, {NRD545_MODES, 10}, {NRD545_MODES, 100}, {NRD545_MODES, kHz(1)}, {NRD545_MODES, kHz(5)}, {NRD545_MODES, kHz(6.25)}, {NRD545_MODES, kHz(9)}, {NRD545_MODES, kHz(10)}, {NRD545_MODES, kHz(12.5)}, {NRD545_MODES, kHz(20)}, {NRD545_MODES, kHz(25)}, {NRD545_MODES, kHz(30)}, {NRD545_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_AMS | RIG_MODE_ECSS | RIG_MODE_FM, kHz(10)}, {RIG_MODE_AM | RIG_MODE_AMS | RIG_MODE_ECSS | RIG_MODE_FM, kHz(4.5)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(4.5)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2.4)}, RIG_FLT_END, }, .str_cal = NRD545_STR_CAL, .rig_open = jrc_open, .rig_close = jrc_close, .set_freq = jrc_set_freq, .get_freq = jrc_get_freq, .set_mode = jrc_set_mode, .get_mode = jrc_get_mode, .set_vfo = jrc_set_vfo, .set_func = jrc_set_func, .get_func = jrc_get_func, .set_level = jrc_set_level, .get_level = jrc_get_level, .set_parm = jrc_set_parm, .get_parm = jrc_get_parm, .get_dcd = jrc_get_dcd, .set_trn = jrc_set_trn, .reset = jrc_reset, .set_mem = jrc_set_mem, .get_mem = jrc_get_mem, .set_channel = jrc_set_chan, .get_channel = jrc_get_chan, .vfo_op = jrc_vfo_op, .scan = jrc_scan, .set_powerstat = jrc_set_powerstat, .get_powerstat = jrc_get_powerstat, .decode_event = jrc_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/jrc/Makefile.am0000644000175000017500000000023614752216205013463 00000000000000JRCSRC = nrd535.c nrd545.c nrd525.c jrc.c jrc.h jst145.c noinst_LTLIBRARIES = libhamlib-jrc.la libhamlib_jrc_la_SOURCES = $(JRCSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/jrc/jst145.c0000644000175000017500000003673014752216205012635 00000000000000/* * Hamlib JRC backend - JST-145 description * Copyright (c) 2001-2009 by Stephane Fillod * Copyright (c) 2021 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "iofunc.h" #include "jrc.h" static int jst145_init(RIG *rig); static int jst145_open(RIG *rig); static int jst145_close(RIG *rig); static int jst145_set_vfo(RIG *rig, vfo_t vfo); static int jst145_get_vfo(RIG *rig, vfo_t *vfo); static int jst145_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int jst145_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int jst145_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int jst145_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int jst145_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int jst145_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int jst145_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int jst145_set_mem(RIG *rig, vfo_t vfo, int ch); static int jst145_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int jst145_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); #define MAX_LEN 24 #define JST145_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_FAX) #define JST145_LEVEL (RIG_LEVEL_AGC) // Rig has VFOB but for now we won't do much with it except set freq #define JST145_VFO (RIG_VFO_VFO) #define JST145_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_AGC, \ } struct jst145_priv_data { ptt_t ptt; freq_t freqA, freqB; mode_t mode; }; /* * JST-145 rig capabilities. * */ struct rig_caps jst145_caps = { RIG_MODEL(RIG_MODEL_JST145), .model_name = "JST-145", .mfg_name = "JRC", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 1, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = JST145_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_NONE, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, JST145_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(100), MHz(30), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {JST145_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2)}, {RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .rig_open = jst145_open, .rig_close = jst145_close, .set_vfo = jst145_set_vfo, .get_vfo = jst145_get_vfo, .set_freq = jst145_set_freq, .get_freq = jst145_get_freq, .set_mode = jst145_set_mode, .get_mode = jst145_get_mode, .set_func = jst145_set_func, .set_level = jst145_set_level, .set_mem = jst145_set_mem, .vfo_op = jst145_vfo_op, .set_ptt = jst145_set_ptt, .get_ptt = jst145_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * JST-245 rig capabilities. * */ struct rig_caps jst245_caps = { RIG_MODEL(RIG_MODEL_JST245), .model_name = "JST-245", .mfg_name = "JRC", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = JST145_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_NONE, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, JST145_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(100), MHz(54), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(54), JST145_MODES, -1, -1, JST145_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {JST145_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2)}, {RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .rig_init = jst145_init, .rig_open = jst145_open, .rig_close = jst145_close, .set_vfo = jst145_set_vfo, .get_vfo = jst145_get_vfo, .set_freq = jst145_set_freq, .get_freq = jst145_get_freq, .set_mode = jst145_set_mode, .get_mode = jst145_get_mode, .set_func = jst145_set_func, .set_level = jst145_set_level, .set_mem = jst145_set_mem, .vfo_op = jst145_vfo_op, .set_ptt = jst145_set_ptt, .get_ptt = jst145_get_ptt }; /* * Function definitions below */ static int jst145_init(RIG *rig) { struct jst145_priv_data *priv; priv = (struct jst145_priv_data *)calloc(1, sizeof(struct jst145_priv_data)); if (!priv) { return -RIG_ENOMEM; } STATE(rig)->priv = (void *)priv; return RIG_OK; } static int jst145_open(RIG *rig) { int retval; freq_t freq; rmode_t mode; pbwidth_t width; struct jst145_priv_data *priv = STATE(rig)->priv; retval = write_block(RIGPORT(rig), (unsigned char *) "H1\r", 3); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: H1 failed: %s\n", __func__, rigerror(retval)); return retval; } rig_get_freq(rig, RIG_VFO_A, &freq); priv->freqA = freq; rig_get_freq(rig, RIG_VFO_B, &freq); priv->freqB = freq; rig_get_mode(rig, RIG_VFO_A, &mode, &width); priv->mode = mode; return retval; } static int jst145_close(RIG *rig) { return write_block(RIGPORT(rig), (unsigned char *) "H0\r", 3); } static int jst145_set_vfo(RIG *rig, vfo_t vfo) { char cmd[MAX_LEN]; SNPRINTF(cmd, sizeof(cmd), "F%c\r", vfo == RIG_VFO_A ? 'A' : 'B'); return write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); } static int jst145_get_vfo(RIG *rig, vfo_t *vfo) { char cmd[MAX_LEN]; char channel[MAX_LEN]; int channel_size = sizeof(channel); int retval; ptt_t ptt; int retry = 1; jst145_get_ptt(rig, RIG_VFO_A, &ptt); // set priv->ptt to current transmit status CACHE(rig)->ptt = ptt; ptt_retry: if (ptt) // can't get vfo while transmitting { *vfo = STATE(rig)->current_vfo; return RIG_OK; } SNPRINTF(cmd, sizeof(cmd), "L\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), channel, &channel_size); if (retval != RIG_OK) { if (retry-- > 0) { goto ptt_retry; } rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction error: %s\n", __func__, rigerror(retval)); return retval; } *vfo = channel[1] == 'A' ? RIG_VFO_A : RIG_VFO_B; return RIG_OK; } static int jst145_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[MAX_LEN]; int retval; struct jst145_priv_data *priv = STATE(rig)->priv; vfo_t save_vfo = STATE(rig)->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = save_vfo; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%08u%c\r", (unsigned)(freq), vfo == RIG_VFO_A ? 'A' : 'B'); if (vfo == RIG_VFO_B) { priv->freqB = freq; } else { priv->freqA = freq; } retval = write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: write_block: %s\n", __func__, rigerror(retval)); return retval; } if (vfo != save_vfo) { retval = rig_set_vfo(rig, save_vfo); } return retval; } static int jst145_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[MAX_LEN]; char cmd[MAX_LEN]; int freqbuf_size = sizeof(freqbuf); int retval; int n; vfo_t save_vfo = STATE(rig)->current_vfo; //struct jst145_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(save_vfo)); if (vfo == RIG_VFO_CURR) { vfo = save_vfo; } if (save_vfo != vfo) { rig_set_vfo(rig, vfo); } SNPRINTF(cmd, sizeof(cmd), "I\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), freqbuf, &freqbuf_size); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction error: %s\n", __func__, rigerror(retval)); return retval; } n = sscanf(freqbuf, "I%*c%*c%*c%8lf", freq); if (n != 1) { retval = -RIG_EPROTO; } if (save_vfo != vfo) { rig_set_vfo(rig, save_vfo); } return retval; } static int jst145_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char *modestr; struct jst145_priv_data *priv = STATE(rig)->priv; switch (mode) { case RIG_MODE_RTTY: modestr = "D0\r"; break; case RIG_MODE_CW: modestr = "D1\r"; break; case RIG_MODE_USB: modestr = "D2\r"; break; case RIG_MODE_LSB: modestr = "D3\r"; break; case RIG_MODE_AM: modestr = "D4\r"; break; case RIG_MODE_FM: modestr = "D5\r"; break; default: return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) modestr, strlen(modestr)); if (retval != RIG_OK) { return retval; } priv->mode = mode; if (RIG_PASSBAND_NOCHANGE == width) { return retval; } // TODO: width -- could use B command but let user handle it for now return retval; } static int jst145_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char cmd[MAX_LEN]; char modebuf[MAX_LEN]; int modebuf_len = sizeof(modebuf); int retval; SNPRINTF(cmd, sizeof(cmd), "I\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), modebuf, &modebuf_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction failed: %s\n", __func__, rigerror(retval)); } switch (modebuf[3]) { case '0': *mode = RIG_MODE_RTTY; break; case '1': *mode = RIG_MODE_CW; break; case '2': *mode = RIG_MODE_USB; break; case '3': *mode = RIG_MODE_LSB; break; case '4': *mode = RIG_MODE_AM; break; case '5': *mode = RIG_MODE_FM; break; } return retval; } static int jst145_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { return -RIG_ENIMPL; } static int jst145_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { switch (level) { case RIG_LEVEL_AGC: { char *cmd = val.i == RIG_AGC_SLOW ? "G0\r" : (val.i == RIG_AGC_FAST ? "G1\r" : "G2\r"); return write_block(RIGPORT(rig), (unsigned char *) cmd, 3); } default: return -RIG_EINVAL; } return -RIG_EINVAL; } static int jst145_set_mem(RIG *rig, vfo_t vfo, int ch) { char membuf[MAX_LEN]; SNPRINTF(membuf, sizeof(membuf), "C%03d\r", ch); return write_block(RIGPORT(rig), (unsigned char *) membuf, strlen(membuf)); } static int jst145_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { switch (op) { case RIG_OP_FROM_VFO: return write_block(RIGPORT(rig), (unsigned char *) "E1\r", 3); default: return -RIG_EINVAL; } return -RIG_EINVAL; } static int jst145_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmd[MAX_LEN]; struct jst145_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: entered\n", __func__); SNPRINTF(cmd, sizeof(cmd), "X%c\r", ptt ? '1' : '0'); priv->ptt = ptt; return write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); } static int jst145_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char cmd[MAX_LEN]; char pttstatus[MAX_LEN]; int pttstatus_size = sizeof(pttstatus); int retval; struct jst145_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: entered\n", __func__); SNPRINTF(cmd, sizeof(cmd), "X\r"); retval = jrc_transaction(rig, cmd, strlen(cmd), pttstatus, &pttstatus_size); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: jrc_transaction error: %s\n", __func__, rigerror(retval)); return retval; } if (pttstatus[1] == '1') { *ptt = RIG_PTT_ON; } else { *ptt = RIG_PTT_OFF; } priv->ptt = CACHE(rig)->ptt = *ptt; return RIG_OK; } hamlib-4.6.2/rigs/jrc/Makefile.in0000644000175000017500000005337414752216216013511 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/jrc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_jrc_la_LIBADD = am__objects_1 = nrd535.lo nrd545.lo nrd525.lo jrc.lo jst145.lo am_libhamlib_jrc_la_OBJECTS = $(am__objects_1) libhamlib_jrc_la_OBJECTS = $(am_libhamlib_jrc_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/jrc.Plo ./$(DEPDIR)/jst145.Plo \ ./$(DEPDIR)/nrd525.Plo ./$(DEPDIR)/nrd535.Plo \ ./$(DEPDIR)/nrd545.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_jrc_la_SOURCES) DIST_SOURCES = $(libhamlib_jrc_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ JRCSRC = nrd535.c nrd545.c nrd525.c jrc.c jrc.h jst145.c noinst_LTLIBRARIES = libhamlib-jrc.la libhamlib_jrc_la_SOURCES = $(JRCSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/jrc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/jrc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-jrc.la: $(libhamlib_jrc_la_OBJECTS) $(libhamlib_jrc_la_DEPENDENCIES) $(EXTRA_libhamlib_jrc_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_jrc_la_OBJECTS) $(libhamlib_jrc_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jrc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jst145.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrd525.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrd535.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrd545.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/jrc.Plo -rm -f ./$(DEPDIR)/jst145.Plo -rm -f ./$(DEPDIR)/nrd525.Plo -rm -f ./$(DEPDIR)/nrd535.Plo -rm -f ./$(DEPDIR)/nrd545.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/jrc.Plo -rm -f ./$(DEPDIR)/jst145.Plo -rm -f ./$(DEPDIR)/nrd525.Plo -rm -f ./$(DEPDIR)/nrd535.Plo -rm -f ./$(DEPDIR)/nrd545.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/jrc/Android.mk0000644000175000017500000000041714752216205013341 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := nrd535.c nrd545.c nrd525.c jrc.c LOCAL_MODULE := jrc LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/jrc/jrc.c0000644000175000017500000011604714752216205012361 00000000000000/* * Hamlib JRC backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "cal.h" #include "register.h" #include "jrc.h" /* * Carriage return */ #define EOM "\r" #define BUFSZ 32 /* * modes in use by the "2G" command */ #define MD_RTTY '0' #define MD_CW '1' #define MD_USB '2' #define MD_LSB '3' #define MD_AM '4' #define MD_FM '5' #define MD_AMS '6' #define MD_FAX '6' #define MD_ECSS_USB '7' #define MD_ECSS_LSB '8' #define MD_WFM '9' /* * jrc_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ int jrc_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); set_transaction_active(rig); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { set_transaction_inactive(rig); return retval; } if (!data || !data_len) { set_transaction_inactive(rig); return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); set_transaction_inactive(rig); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } static int jrc2rig_mode(RIG *rig, char jmode, char jwidth, rmode_t *mode, pbwidth_t *width) { switch (jmode) { case MD_RTTY: *mode = RIG_MODE_RTTY; break; case MD_CW: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FM: *mode = RIG_MODE_FM; break; case MD_AMS: if (rig->caps->rig_model == RIG_MODEL_NRD535) { *mode = RIG_MODE_FAX; } else { *mode = RIG_MODE_AMS; } break; case MD_ECSS_USB: *mode = RIG_MODE_ECSSUSB; break; case MD_ECSS_LSB: *mode = RIG_MODE_ECSSLSB; break; case MD_WFM: *mode = RIG_MODE_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %c\n", __func__, jmode); *mode = RIG_MODE_NONE; return -RIG_EINVAL; } /* * determine passband */ switch (jwidth) { case '0': *width = s_Hz(6000); //wide break; case '1': *width = s_Hz(2000); //inter break; case '2': *width = s_Hz(1000); //narr break; case '3': *width = s_Hz(12000); //aux - nrd535 only break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported width %c\n", __func__, jwidth); *width = RIG_PASSBAND_NORMAL; return -RIG_EINVAL; } return RIG_OK; } static int rig2jrc_mode(RIG *rig, rmode_t mode, pbwidth_t width, char *jmode, char *jwidth) { switch (mode) { case RIG_MODE_RTTY: *jmode = MD_RTTY; break; case RIG_MODE_CW: *jmode = MD_CW; break; case RIG_MODE_USB: *jmode = MD_USB; break; case RIG_MODE_LSB: *jmode = MD_LSB; break; case RIG_MODE_AM: *jmode = MD_AM; break; case RIG_MODE_FM: *jmode = MD_FM; break; case RIG_MODE_AMS: *jmode = MD_AMS; break; case RIG_MODE_FAX: *jmode = MD_FAX; break; case RIG_MODE_ECSSUSB: *jmode = MD_ECSS_USB; break; case RIG_MODE_ECSSLSB: *jmode = MD_ECSS_LSB; break; case RIG_MODE_WFM: *jmode = MD_WFM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (RIG_PASSBAND_NOCHANGE == width) { *jwidth = '1'; return RIG_OK; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width <= s_Hz(1500)) { *jwidth = '2'; /*narr*/ } else if (width <= s_Hz(4000)) { *jwidth = '1'; /*inter*/ } else if (width <= s_Hz(9000)) { *jwidth = '0'; /*wide*/ } else if (rig->caps->rig_model == RIG_MODEL_NRD535) { *jwidth = '3'; /*aux - nrd535 only*/ } else { *jwidth = '1'; /*inter*/ } return RIG_OK; } int jrc_open(RIG *rig) { int retval; /* * Turning computer control ON, * Turn continuous mode on (for "I" query) */ if (rig->caps->rig_model == RIG_MODEL_NRD535) { retval = jrc_transaction(rig, "H1" EOM, 3, NULL, NULL); } else { retval = jrc_transaction(rig, "H1" EOM "I1"EOM, 6, NULL, NULL); } return retval; } int jrc_close(RIG *rig) { int retval; /* Turning computer control OFF */ retval = jrc_transaction(rig, "H0" EOM, 3, NULL, NULL); return retval; } /* * jrc_set_freq * Assumes rig!=NULL */ int jrc_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char freqbuf[BUFSZ]; if (freq >= (freq_t)pow(10, priv->max_freq_len)) { return -RIG_EINVAL; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%0*"PRIll EOM, priv->max_freq_len, (int64_t)freq); return jrc_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } static int get_current_istate(RIG *rig, char *buf, int *buf_len) { int retval; /* * JRCs use "I" to get information, */ if (rig->caps->rig_model == RIG_MODEL_NRD535) { retval = jrc_transaction(rig, "I1" EOM "I0" EOM, 6, buf, buf_len); } else { retval = jrc_transaction(rig, "I" EOM, 2, buf, buf_len); } return retval; } /* * jrc_get_freq * Assumes rig!=NULL, freq!=NULL */ int jrc_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval; char freqbuf[BUFSZ]; int freq_len; //note: JRCs use "I" to get information retval = get_current_istate(rig, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } //I command returns Iabdffffffffg if (freqbuf[0] != 'I' || freq_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_freq: wrong answer %s, " "len=%d\n", freqbuf, freq_len); return -RIG_ERJCTED; } freqbuf[4 + priv->max_freq_len] = '\0'; /* extract freq */ sscanf(freqbuf + 4, "%"SCNfreq, freq); return RIG_OK; } /* * jrc_set_vfo * Assumes rig!=NULL */ int jrc_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmdbuf[16]; int retval; char vfo_function; switch (vfo) { case RIG_VFO_VFO: vfo_function = 'F'; break; case RIG_VFO_MEM: vfo_function = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "jrc_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "%c" EOM, vfo_function); retval = jrc_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), NULL, NULL); return retval; } /* * jrc_set_mode * Assumes rig!=NULL */ int jrc_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int retval; char amode, awidth; retval = rig2jrc_mode(rig, mode, width, &amode, &awidth); if (retval != RIG_OK) { return retval; } SNPRINTF(mdbuf, sizeof(mdbuf), "D" "%c" EOM, amode); retval = jrc_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (width != RIG_PASSBAND_NOCHANGE) { SNPRINTF(mdbuf, sizeof(mdbuf), "B" "%c" EOM, awidth); retval = jrc_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * jrc_get_mode * Assumes rig!=NULL, mode!=NULL, width!=NULL */ int jrc_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int md_len, retval; char mdbuf[BUFSZ]; char cmode; char cwidth; //note: JRCs use "I" to get information retval = get_current_istate(rig, mdbuf, &md_len); if (retval != RIG_OK) { return retval; } //I command returns Iabdffffffffg if (mdbuf[0] != 'I' || md_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_mode: wrong answer %s, " "len=%d\n", mdbuf, md_len); return -RIG_ERJCTED; } /* extract width and mode */ cwidth = mdbuf[2]; cmode = mdbuf[3]; retval = jrc2rig_mode(rig, cmode, cwidth, mode, width); return retval; } /* * jrc_set_func * Assumes rig!=NULL */ int jrc_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_FAGC: /* FIXME: FAGC levels */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%d" EOM, status ? 1 : 2); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_NB: /* FIXME: NB1 and NB2 */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "N%d" EOM, status ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); /* * FIXME: which BB mode for NR and BC at same time ? */ case RIG_FUNC_NR: SNPRINTF(cmdbuf, sizeof(cmdbuf), "BB%d" EOM, status ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_BC: SNPRINTF(cmdbuf, sizeof(cmdbuf), "BB%d" EOM, status ? 2 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_LOCK: SNPRINTF(cmdbuf, sizeof(cmdbuf), "DD%d" EOM, status ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_MN: SNPRINTF(cmdbuf, sizeof(cmdbuf), "EE%d" EOM, status ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %s\n", rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_func * Assumes rig!=NULL, status!=NULL */ int jrc_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval, func_len; char funcbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_FAGC: /* FIXME: FAGC levels */ //retval = jrc_transaction (rig, "G" EOM, 2, funcbuf, &func_len); retval = get_current_istate(rig, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } //if (func_len != 3 || func_len != 6) { if (funcbuf[0] != 'I' || func_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } //*status = funcbuf[1] != '2'; *status = funcbuf[4 + priv->max_freq_len] != '2'; return RIG_OK; case RIG_FUNC_NB: /* FIXME: NB1 and NB2 */ retval = jrc_transaction(rig, "N" EOM, 2, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[1] != '0'; return RIG_OK; /* * FIXME: which BB mode for NR and BC at same time ? */ case RIG_FUNC_NR: retval = jrc_transaction(rig, "BB" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[2] == '1'; return RIG_OK; case RIG_FUNC_BC: retval = jrc_transaction(rig, "BB" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[2] == '2'; return RIG_OK; case RIG_FUNC_LOCK: retval = jrc_transaction(rig, "DD" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[1] == '1'; return RIG_OK; case RIG_FUNC_MN: retval = jrc_transaction(rig, "EE" EOM, 3, funcbuf, &func_len); if (retval != RIG_OK) { return retval; } if (func_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_func: wrong answer %s, " "len=%d\n", funcbuf, func_len); return -RIG_ERJCTED; } *status = funcbuf[1] == '1'; return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int jrc_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%d" EOM, val.i ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "HH%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "JJ%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "LL%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_NR: SNPRINTF(cmdbuf, sizeof(cmdbuf), "FF%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #if 0 case RIG_LEVEL_TONE: SNPRINTF(cmdbuf, sizeof(cmdbuf), "KK%03d" EOM, (int)(val.f * 255.0)); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #endif case RIG_LEVEL_NOTCHF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "GG%+04d" EOM, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #if 0 case RIG_LEVEL_BWC: if (priv->pbs_len == 3) { val.i /= 10; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "W%0*d" EOM, priv->pbs_len, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); #endif case RIG_LEVEL_AGC: if (val.i < 10) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%d" EOM, val.i == RIG_AGC_SLOW ? 0 : val.i == RIG_AGC_FAST ? 1 : 2); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "G3%03d" EOM, val.i / 20); } return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_CWPITCH: SNPRINTF(cmdbuf, sizeof(cmdbuf), "%s%+05d" EOM, priv->cw_pitch, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_IF: if (priv->pbs_len == 3) { val.i /= 10; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "P%+0*d" EOM, priv->pbs_len + 1, val.i); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_level * Assumes rig!=NULL, val!=NULL */ int jrc_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval, lvl_len, lvl; char lvlbuf[BUFSZ]; char cwbuf[BUFSZ]; int cw_len; switch (level) { case RIG_LEVEL_RAWSTR: /* read A/D converted value */ retval = jrc_transaction(rig, "M" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[4] = '\0'; val->i = atoi(lvlbuf + 1); break; case RIG_LEVEL_STRENGTH: /* read calibrated A/D converted value */ retval = jrc_transaction(rig, "M" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[4] = '\0'; val->i = (int)rig_raw2val(atoi(lvlbuf + 1), &rig->caps->str_cal); break; case RIG_LEVEL_ATT: retval = get_current_istate(rig, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvl_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } val->i = lvlbuf[1] == '1' ? 20 : 0; break; case RIG_LEVEL_AGC: retval = get_current_istate(rig, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'I' || lvl_len != priv->info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[priv->info_len - 1] = '\0'; if (priv->info_len == 14) { switch (lvlbuf[priv->info_len - 2]) { case '0' : val->i = RIG_AGC_SLOW; break; case '1' : val->i = RIG_AGC_FAST; break; case '2' : val->i = RIG_AGC_OFF; break; default : val->i = RIG_AGC_FAST; } } else { val->i = atoi(lvlbuf + priv->info_len - 4); } break; case RIG_LEVEL_RF: retval = jrc_transaction(rig, "HH" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; case RIG_LEVEL_AF: retval = jrc_transaction(rig, "JJ" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; case RIG_LEVEL_SQL: retval = jrc_transaction(rig, "LL" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; case RIG_LEVEL_NR: retval = jrc_transaction(rig, "FF" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; #if 0 case RIG_LEVEL_TONE: retval = jrc_transaction(rig, "KK" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%u", &lvl); val->f = (float)lvl / 255.0; break; #endif case RIG_LEVEL_NOTCHF: retval = jrc_transaction(rig, "GG" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* * 000..255 */ sscanf(lvlbuf + 2, "%d", &lvl); val->f = (float)lvl / 255.0; break; #if 0 case RIG_LEVEL_BWC: retval = jrc_transaction(rig, "W" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'W' || lvl_len != priv->pbs_len + 2) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 1, "%d", &lvl); if (priv->pbs_len == 3) { lvl *= 10; } val->i = lvl; break; #endif case RIG_LEVEL_CWPITCH: SNPRINTF(cwbuf, sizeof(cwbuf), "%s" EOM, priv->cw_pitch); cw_len = strlen(cwbuf); retval = jrc_transaction(rig, cwbuf, strlen(cwbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != cw_len + 5) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + (cw_len - 1), "%05d", &lvl); val->i = lvl; break; case RIG_LEVEL_IF: retval = jrc_transaction(rig, "P" EOM, 2, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] != 'P' || lvl_len != priv->pbs_info_len) { rig_debug(RIG_DEBUG_ERR, "jrc_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 1, "%d", &lvl); if (priv->pbs_len == 3) { lvl *= 10; } val->i = lvl; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_set_parm * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sens though) */ int jrc_set_parm(RIG *rig, setting_t parm, value_t val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char cmdbuf[BUFSZ]; int minutes; /* Optimize: * sort the switch cases with the most frequent first */ switch (parm) { case RIG_PARM_BACKLIGHT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "AA%d" EOM, val.f > 0.5 ? 0 : 1); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_PARM_BEEP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "U%0*d" EOM, priv->beep_len, (priv->beep + val.i) ? 1 : 0); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_PARM_TIME: minutes = val.i / 60; SNPRINTF(cmdbuf, sizeof(cmdbuf), "R1%02d%02d" EOM, minutes / 60, minutes % 60); return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_parm * Assumes rig!=NULL, val!=NULL */ int jrc_get_parm(RIG *rig, setting_t parm, value_t *val) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int retval, lvl_len, i; char lvlbuf[BUFSZ]; char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (parm) { case RIG_PARM_TIME: retval = jrc_transaction(rig, "R0" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } /* "Rhhmmss"CR */ if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "jrc_get_parm: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } /* convert ASCII to numeric 0..9 */ for (i = 1; i < 7; i++) { lvlbuf[i] -= '0'; } val->i = ((10 * lvlbuf[1] + lvlbuf[2]) * 60 + /* hours */ 10 * lvlbuf[3] + lvlbuf[4]) * 60 + /* minutes */ 10 * lvlbuf[5] + lvlbuf[6]; /* secondes */ break; case RIG_PARM_BEEP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "U%d" EOM, priv->beep / 10); retval = jrc_transaction(rig, cmdbuf, strlen(cmdbuf), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != priv->beep_len + 2) { rig_debug(RIG_DEBUG_ERR, "jrc_get_parm: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } val->i = lvlbuf[priv->beep_len] == 0 ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * jrc_get_dcd * Assumes rig!=NULL, dcd!=NULL */ int jrc_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; int dcd_len, retval; retval = jrc_transaction(rig, "Q" EOM, 2, dcdbuf, &dcd_len); if (retval != RIG_OK) { return retval; } if (dcd_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_dcd: wrong answer %s, " "len=%d\n", dcdbuf, dcd_len); return -RIG_ERJCTED; } *dcd = dcdbuf[1] == '0' ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } /* * jrc_set_trn * Assumes rig!=NULL */ int jrc_set_trn(RIG *rig, int trn) { char *trncmd; /* transceive(continuous) mode not available in remote mode * so switch back and forth upon entering/leaving */ trncmd = trn == RIG_TRN_RIG ? "H0"EOM"I1"EOM : "H1"EOM"I1"EOM; return jrc_transaction(rig, trncmd, 6, NULL, NULL); } /* * jrc_set_powerstat * Assumes rig!=NULL */ int jrc_set_powerstat(RIG *rig, powerstat_t status) { char pwrbuf[BUFSZ]; SNPRINTF(pwrbuf, sizeof(pwrbuf), "T%d" EOM, status == RIG_POWER_ON ? 1 : 0); return jrc_transaction(rig, pwrbuf, strlen(pwrbuf), NULL, NULL); } /* * jrc_get_powerstat * Assumes rig!=NULL */ int jrc_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[BUFSZ]; int pwr_len, retval; if (rig->caps->rig_model == RIG_MODEL_NRD535) { retval = jrc_transaction(rig, "T" EOM, 2, pwrbuf, &pwr_len); if (retval != RIG_OK) { return retval; } if (pwr_len != 3) { rig_debug(RIG_DEBUG_ERR, "jrc_get_powerstat: wrong answer %s, " "len=%d\n", pwrbuf, pwr_len); return -RIG_ERJCTED; } *status = pwrbuf[1] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; return RIG_OK; } else { retval = jrc_transaction(rig, "I" EOM, 2, pwrbuf, &pwr_len); *status = retval != RIG_OK ? RIG_POWER_OFF : RIG_POWER_ON; return retval; } } /* * jrc_reset * Assumes rig!=NULL */ int jrc_reset(RIG *rig, reset_t reset) { char rstbuf[BUFSZ]; char rst; switch (reset) { case RIG_RESET_MCALL: rst = '1'; break; /* mem clear */ case RIG_RESET_VFO: rst = '2'; break; /* user setup default */ case RIG_RESET_MASTER: rst = '3'; break; /* 1 + 2 */ default: rig_debug(RIG_DEBUG_ERR, "jrc_reset: unsupported reset %d\n", reset); return -RIG_EINVAL; } SNPRINTF(rstbuf, sizeof(rstbuf), "Z%c" EOM, rst); return jrc_transaction(rig, rstbuf, strlen(rstbuf), NULL, NULL); } /* * jrc_set_mem * Assumes rig!=NULL */ int jrc_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; char membuf[BUFSZ]; int mem_len; if (ch < 0 || ch > rig->caps->chan_list[0].endc) { return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "C%03d" EOM, ch); /* don't care about the Automatic response from receiver */ return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), membuf, &mem_len); } /* * jrc_get_mem * Assumes rig!=NULL */ int jrc_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; int mem_len, retval; char membuf[BUFSZ]; int chan; retval = jrc_transaction(rig, "L" EOM, 2, membuf, &mem_len); if (retval != RIG_OK) { return retval; } /* need to handle vacant memories LmmmV, len = 6 */ if ((mem_len != priv->mem_len) && (mem_len != 6)) { rig_debug(RIG_DEBUG_ERR, "jrc_get_mem: wrong answer %s, " "len=%d\n", membuf, mem_len); return -RIG_ERJCTED; } membuf[4] = '\0'; /*extract current channel*/ sscanf(membuf + 1, "%d", &chan); *ch = chan; return RIG_OK; } /* * jrc_set_chan * Assumes rig!=NULL */ int jrc_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char cmdbuf[BUFSZ]; int retval; rmode_t mode; pbwidth_t width; channel_t current; /* read first to get current values */ current.channel_num = chan->channel_num; if ((retval = jrc_get_chan(rig, vfo, ¤t, 1)) != RIG_OK) { return retval; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "K%03d000", chan->channel_num); if (chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i == 20) { cmdbuf[4] = '1'; } mode = chan->mode; width = chan->width; if (RIG_MODE_NONE == mode) { mode = current.mode; } if (RIG_PASSBAND_NOCHANGE == width) { width = current.width; } retval = rig2jrc_mode(rig, mode, width, &cmdbuf[6], &cmdbuf[5]); if (retval != RIG_OK) { return retval; } SNPRINTF(cmdbuf + 7, sizeof(cmdbuf) - 7, "%0*"PRIll, priv->max_freq_len, (int64_t)chan->freq); if (priv->mem_len == 17) { switch (chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i) { case RIG_AGC_SLOW : cmdbuf[priv->mem_len - 2] = '0'; break; case RIG_AGC_FAST : cmdbuf[priv->mem_len - 2] = '1'; break; case RIG_AGC_OFF : cmdbuf[priv->mem_len - 2] = '2'; break; default : cmdbuf[priv->mem_len - 2] = '1'; } } else { SNPRINTF(cmdbuf + priv->mem_len - 4, sizeof(cmdbuf) - (priv->mem_len - 4), "%03d", chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i); } return jrc_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * jrc_get_chan * Assumes rig!=NULL */ int jrc_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; char membuf[BUFSZ], cmdbuf[BUFSZ]; int mem_len, retval; chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, ""); SNPRINTF(cmdbuf, sizeof(cmdbuf), "L%03d%03d" EOM, chan->channel_num, chan->channel_num); retval = jrc_transaction(rig, cmdbuf, strlen(cmdbuf), membuf, &mem_len); if (retval != RIG_OK) { return retval; } /* need to handle vacant memories LmmmV, len = 6 */ if ((mem_len != priv->mem_len) && (mem_len != 6)) { rig_debug(RIG_DEBUG_ERR, "jrc_get_mem: wrong answer %s, " "len=%d\n", membuf, mem_len); return -RIG_ERJCTED; } if (mem_len != 6) { char freqbuf[BUFSZ]; if (membuf[4] == '1') { chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 20; } jrc2rig_mode(rig, membuf[6], membuf[5], &chan->mode, &chan->width); strncpy(freqbuf, membuf + 7, priv->max_freq_len); freqbuf[priv->max_freq_len] = 0x00; chan->freq = strtol(freqbuf, NULL, 10); if (priv->mem_len == 17) { switch (membuf[priv->mem_len - 2]) { case '0' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_SLOW; break; case '1' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; break; case '2' : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; break; default : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; } } else { strncpy(freqbuf, membuf + priv->mem_len - 4, 3); chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = strtol(freqbuf, NULL, 10); } } return RIG_OK; } /* * jrc_vfo_op * Assumes rig!=NULL */ int jrc_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const char *cmd; switch (op) { case RIG_OP_FROM_VFO: cmd = "E1" EOM; break; case RIG_OP_UP: cmd = "MM25" EOM; break; case RIG_OP_DOWN: cmd = "MM24" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "jrc_vfo_op: unsupported op %#x\n", op); return -RIG_EINVAL; } return jrc_transaction(rig, cmd, strlen(cmd), NULL, NULL); } /* * jrc_scan, scan operation * Assumes rig!=NULL * * Not really a scan operation so speaking. * You just make the rig increment frequency of decrement continuously, * depending on the sign of ch. * However, using DCD sensing, followed by a stop, you get it. */ int jrc_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { const char *scan_cmd = ""; switch (scan) { case RIG_SCAN_STOP: scan_cmd = "Y0" EOM; break; case RIG_SCAN_SLCT: scan_cmd = ch > 0 ? "Y+" EOM : "Y-" EOM; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported scan %#x", scan); return -RIG_EINVAL; } return jrc_transaction(rig, scan_cmd, 3, NULL, NULL); } /* * jrc_decode is called by sa_sigio, when some asynchronous * data has been received from the rig */ int jrc_decode_event(RIG *rig) { const struct jrc_priv_caps *priv = (struct jrc_priv_caps *)rig->caps->priv; freq_t freq; rmode_t mode; pbwidth_t width; int count; char buf[BUFSZ]; rig_debug(RIG_DEBUG_VERBOSE, "%s: jrc_decode called\n", __func__); /* "Iabdfg"CR */ //#define SETUP_STATUS_LEN 17 //count = read_string(RIGPORT(rig), buf, SETUP_STATUS_LEN, "", 0); count = read_string(RIGPORT(rig), (unsigned char *) buf, priv->info_len, "", 0, 0, 1); if (count < 0) { return count; } buf[31] = '\0'; /* stop run away.. */ if (buf[0] != 'I') { rig_debug(RIG_DEBUG_WARN, "jrc: unexpected data: %s\n", buf); return -RIG_EPROTO; } /* * TODO: Attenuator and AGC change notification. */ if (rig->callbacks.freq_event) { //buf[14] = '\0'; /* side-effect: destroy AGC first digit! */ buf[4 + priv->max_freq_len] = '\0'; /* side-effect: destroy AGC first digit! */ sscanf(buf + 4, "%"SCNfreq, &freq); return rig->callbacks.freq_event(rig, RIG_VFO_CURR, freq, rig->callbacks.freq_arg); } if (rig->callbacks.mode_event) { jrc2rig_mode(rig, buf[3], buf[2], &mode, &width); return rig->callbacks.mode_event(rig, RIG_VFO_CURR, mode, width, rig->callbacks.freq_arg); } return RIG_OK; } /* * initrigs_jrc is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(jrc) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&nrd535_caps); rig_register(&nrd545_caps); rig_register(&nrd525_caps); rig_register(&jst145_caps); rig_register(&jst245_caps); return RIG_OK; } hamlib-4.6.2/rigs/jrc/nrd525.c0000644000175000017500000001530414752216205012614 00000000000000/* * Hamlib JRC backend - NRD-525 description * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "iofunc.h" #include "jrc.h" static int nrd525_open(RIG *rig); static int nrd525_close(RIG *rig); static int nrd525_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int nrd525_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int nrd525_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int nrd525_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int nrd525_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int nrd525_set_mem(RIG *rig, vfo_t vfo, int ch); #define NRD525_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_FAX) #define NRD525_FUNC (RIG_FUNC_LOCK) #define NRD525_LEVEL (RIG_LEVEL_ATT|RIG_LEVEL_AGC) #define NRD525_VFO (RIG_VFO_VFO) #define NRD525_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_AGC, \ } /* * NRD-525 rig capabilities. * */ struct rig_caps nrd525_caps = { RIG_MODEL(RIG_MODEL_NRD525), .model_name = "NRD-525", .mfg_name = "JRC", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = NRD525_FUNC, .has_get_level = RIG_LEVEL_NONE, .has_set_level = NRD525_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .vfo_ops = RIG_OP_FROM_VFO, .scan_ops = RIG_SCAN_NONE, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM, NRD525_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(10), MHz(30), NRD525_MODES, -1, -1, NRD525_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), NRD525_MODES, -1, -1, NRD525_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {NRD525_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2)}, {RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(2)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(1)}, {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_FAX, kHz(6)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(2)}, RIG_FLT_END, }, .rig_open = nrd525_open, .rig_close = nrd525_close, .set_freq = nrd525_set_freq, .set_mode = nrd525_set_mode, .set_func = nrd525_set_func, .set_level = nrd525_set_level, .set_mem = nrd525_set_mem, .vfo_op = nrd525_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ static int nrd525_open(RIG *rig) { return write_block(RIGPORT(rig), (unsigned char *) "H1", 2); } static int nrd525_close(RIG *rig) { return write_block(RIGPORT(rig), (unsigned char *) "H0", 2); } static int nrd525_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[12]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%08u", (unsigned)(freq / 10)); return write_block(RIGPORT(rig), (unsigned char *) freqbuf, strlen(freqbuf)); } static int nrd525_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char *modestr; switch (mode) { case RIG_MODE_RTTY: modestr = "D0"; break; case RIG_MODE_CW: modestr = "D1"; break; case RIG_MODE_USB: modestr = "D2"; break; case RIG_MODE_LSB: modestr = "D3"; break; case RIG_MODE_AM: modestr = "D4"; break; case RIG_MODE_FM: modestr = "D5"; break; case RIG_MODE_FAX: modestr = "D6"; break; default: return -RIG_EINVAL; } retval = write_block(RIGPORT(rig), (unsigned char *) modestr, strlen(modestr)); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } // TODO: width return retval; } static int nrd525_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { return -RIG_ENIMPL; } static int nrd525_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { switch (level) { case RIG_LEVEL_ATT: return write_block(RIGPORT(rig), (unsigned char *)(val.i != 0 ? "A1" : "A0"), 2); case RIG_LEVEL_AGC: return write_block(RIGPORT(rig), (unsigned char *)(val.i == RIG_AGC_SLOW ? "G0" : (val.i == RIG_AGC_FAST ? "G1" : "G2")), 2); default: return -RIG_EINVAL; } } static int nrd525_set_mem(RIG *rig, vfo_t vfo, int ch) { char membuf[12]; SNPRINTF(membuf, sizeof(membuf), "C%03d", ch); return write_block(RIGPORT(rig), (unsigned char *) membuf, strlen(membuf)); } static int nrd525_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { switch (op) { case RIG_OP_FROM_VFO: return write_block(RIGPORT(rig), (unsigned char *) "E1", 2); default: return -RIG_EINVAL; } } hamlib-4.6.2/rigs/lowe/0000755000175000017500000000000014752216243011700 500000000000000hamlib-4.6.2/rigs/lowe/lowe.c0000644000175000017500000001705714752216205012742 00000000000000/* * Hamlib Lowe backend - main file * Copyright (c) 2003-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "lowe.h" #define BUFSZ 64 #define CR "\x0d" #define EOM CR #define MD_USB "USB" #define MD_LSB "LSB" #define MD_FAX "FAX" #define MD_CW "CW" #define MD_FM "FM" #define MD_AM "AM" #define MD_AMS "AMS" /* * lowe_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int lowe_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, CR, 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * lowe_set_freq * Assumes rig!=NULL */ int lowe_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16], ackbuf[16]; int ack_len, retval; /* */ SNPRINTF(freqbuf, sizeof(freqbuf), "FRQ%f" EOM, (float)freq / 1000); retval = lowe_transaction(rig, freqbuf, strlen(freqbuf), ackbuf, &ack_len); return retval; } /* * lowe_get_freq * Assumes rig!=NULL */ int lowe_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[16]; int freq_len, retval; double f_freq; retval = lowe_transaction(rig, "FRQ?" EOM, 5, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } freqbuf[freq_len < 16 ? freq_len : 15] = '\0'; sscanf(freqbuf + 1, "%lf", &f_freq); *freq = f_freq * 1000; return retval; } /* * lowe_set_mode * Assumes rig!=NULL */ int lowe_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[16], ackbuf[16]; char *mode_sel; int ack_len, retval; switch (mode) { case RIG_MODE_CW: mode_sel = MD_CW; break; case RIG_MODE_USB: mode_sel = MD_USB; break; case RIG_MODE_LSB: mode_sel = MD_LSB; break; case RIG_MODE_FM: mode_sel = MD_FM; break; case RIG_MODE_AM: mode_sel = MD_AM; break; case RIG_MODE_FAX: mode_sel = MD_FAX; break; case RIG_MODE_AMS: mode_sel = MD_AMS; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), "MOD%s" EOM, mode_sel); retval = lowe_transaction(rig, mdbuf, strlen(mdbuf), ackbuf, &ack_len); return retval; } /* * lowe_get_mode * Assumes rig!=NULL */ int lowe_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char mdbuf[16]; int mdbuf_len, retval; retval = lowe_transaction(rig, "MOD?" EOM, 5, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (!strcmp(mdbuf + 1, MD_CW)) { *mode = RIG_MODE_CW; } else if (!strcmp(mdbuf + 1, MD_USB)) { *mode = RIG_MODE_USB; } else if (!strcmp(mdbuf + 1, MD_LSB)) { *mode = RIG_MODE_LSB; } else if (!strcmp(mdbuf + 1, MD_FM)) { *mode = RIG_MODE_FM; } else if (!strcmp(mdbuf + 1, MD_FAX)) { *mode = RIG_MODE_FAX; } else if (!strcmp(mdbuf + 1, MD_AMS)) { *mode = RIG_MODE_AMS; } else if (!strcmp(mdbuf + 1, MD_AM)) { *mode = RIG_MODE_AM; } else { rig_debug(RIG_DEBUG_WARN, "%s: unknown mode '%s'\n", __func__, mdbuf); return -RIG_EPROTO; } *width = RIG_PASSBAND_NORMAL; return retval; } /* * lowe_get_level * Assumes rig!=NULL */ int lowe_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[16]; int lvl_len, retval; if (level != RIG_LEVEL_STRENGTH) { return -RIG_EINVAL; } retval = lowe_transaction(rig, "RSS?" EOM, 5, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } lvlbuf[lvl_len < 16 ? lvl_len : 15] = '\0'; sscanf(lvlbuf + 1, "%d", &val->i); val->i += 60; /* dBm */ return retval; } /* * lowe_reset * Assumes rig!=NULL */ int lowe_reset(RIG *rig, reset_t reset) { static char ackbuf[BUFSZ]; int retval, ack_len; retval = lowe_transaction(rig, "RES" EOM, 4, ackbuf, &ack_len); return retval; } /* * lowe_get_info * Assumes rig!=NULL */ const char *lowe_get_info(RIG *rig) { static char idbuf[BUFSZ]; int retval, id_len; /* hack: no idea what INF is for */ retval = lowe_transaction(rig, "INF?" EOM, 5, idbuf, &id_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: INF didn't work\n", __func__); // non-fatal } /* this is the real one */ retval = lowe_transaction(rig, "TYP?" EOM, 5, idbuf, &id_len); if (retval != RIG_OK) { return NULL; } idbuf[id_len] = '\0'; return idbuf; } /* * probe_lowe(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(lowe) { static char idbuf[BUFSZ]; int retval, id_len; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->parm.serial.rate = hf235_caps.serial_rate_max; port->write_delay = port->post_write_delay = 0; port->timeout = 50; port->retry = 1; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "TYP?" EOM, 4); id_len = read_string(port, (unsigned char *) idbuf, BUFSZ, CR, 2, 0, 1); close(port->fd); if (retval != RIG_OK || id_len <= 0 || id_len >= BUFSZ) { return RIG_MODEL_NONE; } idbuf[id_len] = '\0'; if (!strcmp(idbuf, "HF-235")) { if (cfunc) { (*cfunc)(port, RIG_MODEL_HF235, data); } return RIG_MODEL_HF235; } /* * not found... */ if (memcmp(idbuf, "ID" EOM, 3)) /* catch loopback serial */ rig_debug(RIG_DEBUG_VERBOSE, "probe_lowe: found unknown device " "with ID '%s', please report to Hamlib " "developers.\n", idbuf); return RIG_MODEL_NONE; } /* * initrigs_lowe is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(lowe) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&hf235_caps); return RIG_OK; } hamlib-4.6.2/rigs/lowe/Makefile.am0000644000175000017500000000021014752216205013643 00000000000000LOWESRC = hf235.c lowe.c lowe.h noinst_LTLIBRARIES = libhamlib-lowe.la libhamlib_lowe_la_SOURCES = $(LOWESRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/lowe/Makefile.in0000644000175000017500000005227614752216216013701 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/lowe ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_lowe_la_LIBADD = am__objects_1 = hf235.lo lowe.lo am_libhamlib_lowe_la_OBJECTS = $(am__objects_1) libhamlib_lowe_la_OBJECTS = $(am_libhamlib_lowe_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/hf235.Plo ./$(DEPDIR)/lowe.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_lowe_la_SOURCES) DIST_SOURCES = $(libhamlib_lowe_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ LOWESRC = hf235.c lowe.c lowe.h noinst_LTLIBRARIES = libhamlib-lowe.la libhamlib_lowe_la_SOURCES = $(LOWESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/lowe/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/lowe/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-lowe.la: $(libhamlib_lowe_la_OBJECTS) $(libhamlib_lowe_la_DEPENDENCIES) $(EXTRA_libhamlib_lowe_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_lowe_la_OBJECTS) $(libhamlib_lowe_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hf235.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lowe.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/hf235.Plo -rm -f ./$(DEPDIR)/lowe.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/hf235.Plo -rm -f ./$(DEPDIR)/lowe.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/lowe/Android.mk0000644000175000017500000000037614752216205013535 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := hf235.c lowe.c LOCAL_MODULE := lowe LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/lowe/lowe.h0000644000175000017500000000260314752216205012736 00000000000000/* * Hamlib Lowe backend - main header * Copyright (c) 2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _LOWE_H #define _LOWE_H 1 #include #define BACKEND_VER "20200112" int lowe_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int lowe_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int lowe_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int lowe_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int lowe_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int lowe_reset(RIG *rig, reset_t reset); const char *lowe_get_info(RIG *rig); extern struct rig_caps hf235_caps; #endif /* _LOWE_H */ hamlib-4.6.2/rigs/lowe/hf235.c0000644000175000017500000000677614752216205012631 00000000000000/* * Hamlib Lowe backend - HF-235 description * Copyright (c) 2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "lowe.h" #define HF235_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_FM) #define HF235_FUNC (RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define HF235_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define HF235_PARM_ALL (RIG_PARM_NONE) #define HF235_VFO (RIG_VFO_A) #define HF235_VFO_OPS (RIG_OP_NONE) /* * HF-235 rig capabilities. * */ struct rig_caps hf235_caps = { RIG_MODEL(RIG_MODEL_HF235), .model_name = "HF-235", .mfg_name = "Lowe", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, /* and only basic support */ .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = HF235_FUNC, .has_set_func = HF235_FUNC, .has_get_level = HF235_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(HF235_LEVEL_ALL), .has_get_parm = HF235_PARM_ALL, .has_set_parm = RIG_PARM_SET(HF235_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = HF235_VFO_OPS, .chan_list = { RIG_CHAN_END, /* FIXME */ }, .rx_range_list1 = { {kHz(30), MHz(30), HF235_MODES, -1, -1, HF235_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), HF235_MODES, -1, -1, HF235_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {HF235_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = NULL, .set_freq = lowe_set_freq, .get_freq = lowe_get_freq, .set_mode = lowe_set_mode, .get_mode = lowe_get_mode, //.set_func = lowe_set_func, .get_level = lowe_get_level, .reset = lowe_reset, .get_info = lowe_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/drake/0000755000175000017500000000000014752216242012017 500000000000000hamlib-4.6.2/rigs/drake/Makefile.am0000644000175000017500000000022214752216205013766 00000000000000DRAKESRC = r8a.c r8b.c drake.c drake.h noinst_LTLIBRARIES = libhamlib-drake.la libhamlib_drake_la_SOURCES = $(DRAKESRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/drake/Makefile.in0000644000175000017500000005260114752216216014011 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/drake ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_drake_la_LIBADD = am__objects_1 = r8a.lo r8b.lo drake.lo am_libhamlib_drake_la_OBJECTS = $(am__objects_1) libhamlib_drake_la_OBJECTS = $(am_libhamlib_drake_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/drake.Plo ./$(DEPDIR)/r8a.Plo \ ./$(DEPDIR)/r8b.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_drake_la_SOURCES) DIST_SOURCES = $(libhamlib_drake_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DRAKESRC = r8a.c r8b.c drake.c drake.h noinst_LTLIBRARIES = libhamlib-drake.la libhamlib_drake_la_SOURCES = $(DRAKESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/drake/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/drake/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-drake.la: $(libhamlib_drake_la_OBJECTS) $(libhamlib_drake_la_DEPENDENCIES) $(EXTRA_libhamlib_drake_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_drake_la_OBJECTS) $(libhamlib_drake_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drake.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r8a.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r8b.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/drake.Plo -rm -f ./$(DEPDIR)/r8a.Plo -rm -f ./$(DEPDIR)/r8b.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/drake.Plo -rm -f ./$(DEPDIR)/r8a.Plo -rm -f ./$(DEPDIR)/r8b.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/drake/Android.mk0000644000175000017500000000040414752216205013645 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := r8a.c r8b.c drake.c LOCAL_MODULE := drake LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/drake/drake.c0000644000175000017500000007021114752216205013171 00000000000000/* * Hamlib Drake backend - main file * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "cal.h" #include "register.h" #include "drake.h" /* * Protocol information available at http://www.rldrake.com/swl/R8B.pdf */ #define BUFSZ 64 #define CR "\x0d" #define LF "\x0a" #define EOM CR #define MD_USB '1' #define MD_LSB '2' #define MD_RTTY '3' #define MD_CW '4' #define MD_FM '5' #define MD_AM '6' /* * drake_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int drake_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, TODO: flush input? */ if (!data || !data_len) { return 0; } retval = read_string(rp, (unsigned char *) data, BUFSZ, LF, 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } int drake_init(RIG *rig) { struct drake_priv_data *priv; STATE(rig)->priv = calloc(1, sizeof(struct drake_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->curr_ch = 0; return RIG_OK; } int drake_cleanup(RIG *rig) { struct drake_priv_data *priv = STATE(rig)->priv; free(priv); return RIG_OK; } /* * drake_set_freq * Assumes rig!=NULL */ int drake_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char freqbuf[16], ackbuf[16]; int ack_len, retval; /* * 10Hz resolution * TODO: round nearest? */ SNPRINTF((char *) freqbuf, sizeof(freqbuf), "F%07u" EOM, (unsigned int)freq / 10); retval = drake_transaction(rig, (char *) freqbuf, strlen((char *)freqbuf), (char *) ackbuf, &ack_len); return retval; } /* * drake_get_freq * Assumes rig!=NULL, freq!=NULL */ int drake_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int freq_len, retval; char freqbuf[BUFSZ]; double f; char fmult; retval = drake_transaction(rig, "RF" EOM, 3, freqbuf, &freq_len); if (retval != RIG_OK) { return retval; } /* RA command returns *fffff.ff*mHz */ if (freq_len != 15) { rig_debug(RIG_DEBUG_ERR, "drake_get_freq: wrong answer %s, " "len=%d\n", freqbuf, freq_len); return -RIG_ERJCTED; } fmult = freqbuf[10]; freqbuf[9] = '\0'; /* extract freq */ sscanf(freqbuf + 1, "%lf", &f); f *= 1000.0; if (fmult == 'M' || fmult == 'm') { f *= 1000.0; } *freq = (freq_t)f; return RIG_OK; } /* * drake_set_vfo * Assumes rig!=NULL */ int drake_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmdbuf[16], ackbuf[16]; int ack_len, retval; char vfo_function; switch (vfo) { case RIG_VFO_A : vfo_function = 'A'; break; case RIG_VFO_B : vfo_function = 'B'; break; case RIG_VFO_VFO: vfo_function = 'F'; break; case RIG_VFO_MEM: vfo_function = 'C'; break; default: rig_debug(RIG_DEBUG_ERR, "drake_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } if ((vfo_function == 'A') || (vfo_function == 'B')) { SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "V%c" EOM, vfo_function); } if ((vfo_function == 'F') || (vfo_function == 'C')) { SNPRINTF((char *) cmdbuf, sizeof(cmdbuf), "%c" EOM, vfo_function); } retval = drake_transaction(rig, (char *) cmdbuf, strlen((char *)cmdbuf), (char *) ackbuf, &ack_len); return retval; } /* * drake_get_vfo * Assumes rig!=NULL */ int drake_get_vfo(RIG *rig, vfo_t *vfo) { int mdbuf_len, retval; char mdbuf[BUFSZ]; retval = drake_transaction(rig, "RA" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len < 35) { rig_debug(RIG_DEBUG_ERR, "drake_get_vfo: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } if (mdbuf[0] == '*') { *vfo = RIG_VFO_MEM; } else { char cvfo = (mdbuf[9] & 0x38); switch (cvfo) { case '0' : *vfo = RIG_VFO_B; break; case '8' : *vfo = RIG_VFO_A; break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_vfo: unsupported vfo %c\n", cvfo); *vfo = RIG_VFO_VFO; return -RIG_EINVAL; } } return RIG_OK; } /* * drake_set_mode * Assumes rig!=NULL */ int drake_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char mdbuf[16], ackbuf[16]; unsigned char mode_sel; int ack_len, retval; switch (mode) { case RIG_MODE_CW: mode_sel = MD_CW; break; case RIG_MODE_ECSSUSB: case RIG_MODE_USB: mode_sel = MD_USB; break; case RIG_MODE_ECSSLSB: case RIG_MODE_LSB: mode_sel = MD_LSB; break; case RIG_MODE_FM: mode_sel = MD_FM; break; case RIG_MODE_AMS: case RIG_MODE_AM: mode_sel = MD_AM; break; case RIG_MODE_RTTY: mode_sel = MD_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "drake_set_mode: " "unsupported mode %s\n", rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) mdbuf, sizeof(mdbuf), "M%c" EOM, mode_sel); retval = drake_transaction(rig, (char *) mdbuf, strlen((char *)mdbuf), (char *) ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (width != RIG_PASSBAND_NOCHANGE) { if (mode != RIG_MODE_FM) { unsigned int width_sel; if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width <= 500) { width_sel = '0'; } else if (width <= 1800) { width_sel = '1'; } else if (width <= 2300) { width_sel = '2'; } else if (width <= 4000) { width_sel = '4'; } else { width_sel = '6'; } SNPRINTF((char *) mdbuf, sizeof(mdbuf), "W%c" EOM, width_sel); retval = drake_transaction(rig, (char *) mdbuf, strlen((char *)mdbuf), (char *) ackbuf, &ack_len); } } if ((mode == RIG_MODE_AMS) || (mode == RIG_MODE_ECSSUSB) || (mode == RIG_MODE_ECSSLSB) || (mode == RIG_MODE_AM) || (mode == RIG_MODE_USB) || (mode == RIG_MODE_LSB)) { SNPRINTF((char *) mdbuf, sizeof(mdbuf), "S%c" EOM, ((mode == RIG_MODE_AMS) || (mode == RIG_MODE_ECSSUSB) || (mode == RIG_MODE_ECSSLSB)) ? 'O' : 'F'); retval = drake_transaction(rig, (char *) mdbuf, strlen((char *)mdbuf), (char *) ackbuf, &ack_len); } return retval; } /* * drake_get_mode * Assumes rig!=NULL */ int drake_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int mdbuf_len, retval; char mdbuf[BUFSZ]; char cmode; char cwidth; char csynch; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_mode: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } cmode = mdbuf[3]; cwidth = mdbuf[4]; csynch = mdbuf[5]; switch (cwidth & 0x37) { case '0': *width = s_Hz(500); break; case '1': *width = s_Hz(1800); break; case '2': *width = s_Hz(2300); break; case '3': *width = s_Hz(4000); break; case '4': *width = s_Hz(6000); break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_mode: unsupported width %c\n", cwidth); *width = RIG_PASSBAND_NORMAL; return -RIG_EINVAL; } if ((cwidth >= '0') && (cwidth <= '4')) { switch (cmode & 0x33) { case '0': *mode = RIG_MODE_LSB; break; case '1': *mode = RIG_MODE_RTTY; break; case '2': *mode = RIG_MODE_FM; *width = s_Hz(12000); break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_mode: unsupported mode %c\n", cmode); *mode = RIG_MODE_NONE; return -RIG_EINVAL; } } else { switch (cmode & 0x33) { case '0': *mode = RIG_MODE_USB; break; case '1': *mode = RIG_MODE_CW; break; case '2': *mode = RIG_MODE_AM; break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_mode: unsupported mode %c\n", cmode); *mode = RIG_MODE_NONE; return -RIG_EINVAL; } } if ((csynch & 0x34) == '4') { if (*mode == RIG_MODE_AM) { *mode = RIG_MODE_AMS; } else if (*mode == RIG_MODE_USB) { *mode = RIG_MODE_ECSSUSB; } else if (*mode == RIG_MODE_LSB) { *mode = RIG_MODE_ECSSLSB; } } return RIG_OK; } /* * drake_set_ant * Assumes rig!=NULL */ int drake_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { unsigned char buf[16], ackbuf[16]; int ack_len, retval; SNPRINTF((char *) buf, sizeof(buf), "A%c" EOM, ant == RIG_ANT_1 ? '1' : (ant == RIG_ANT_2 ? '2' : 'C')); retval = drake_transaction(rig, (char *) buf, strlen((char *)buf), (char *) ackbuf, &ack_len); return retval; } /* * drake_get_ant * Assumes rig!=NULL */ int drake_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { int mdbuf_len, retval; char mdbuf[BUFSZ]; char cant; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_ant: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } cant = mdbuf[3]; switch (cant & 0x3c) { case '0': *ant_curr = RIG_ANT_1; break; case '4': *ant_curr = RIG_ANT_3; break; case '8': *ant_curr = RIG_ANT_2; break; default : rig_debug(RIG_DEBUG_ERR, "drake_get_ant: unsupported antenna %c\n", cant); return -RIG_EINVAL; } return RIG_OK; } /* * drake_set_mem * Assumes rig!=NULL */ int drake_set_mem(RIG *rig, vfo_t vfo, int ch) { int ack_len, retval; char buf[16], ackbuf[16]; struct drake_priv_data *priv = STATE(rig)->priv; priv->curr_ch = ch; SNPRINTF(buf, sizeof(buf), "C%03d" EOM, ch); ack_len = 0; // fix compile-time warning "possibly uninitialized" retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); if (ack_len != 2) { rig_debug(RIG_DEBUG_ERR, "drake_set_mem: could not set channel %03d.\n", ch); retval = -RIG_ERJCTED; } return retval; } /* * drake_get_mem * Assumes rig!=NULL */ int drake_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct drake_priv_data *priv = STATE(rig)->priv; int mdbuf_len, retval; char mdbuf[BUFSZ]; int chan; retval = drake_transaction(rig, "RC" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 6) { rig_debug(RIG_DEBUG_ERR, "drake_get_mem: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } mdbuf[4] = '\0'; /* extract channel no */ sscanf(mdbuf + 1, "%03d", &chan); *ch = chan; priv->curr_ch = chan; return RIG_OK; } /* * drake_set_chan * Assumes rig!=NULL */ int drake_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan) { const struct drake_priv_data *priv = STATE(rig)->priv; vfo_t old_vfo; int old_chan; char mdbuf[16], ackbuf[16]; int ack_len, retval; value_t dummy; dummy.i = 0; drake_get_vfo(rig, &old_vfo); old_chan = 0; /* set to vfo if needed */ if (old_vfo == RIG_VFO_MEM) { old_chan = priv->curr_ch; retval = drake_set_vfo(rig, RIG_VFO_VFO); if (retval != RIG_OK) { return retval; } } /* set all memory features */ drake_set_ant(rig, RIG_VFO_CURR, chan->ant, dummy); drake_set_freq(rig, RIG_VFO_CURR, chan->freq); drake_set_mode(rig, RIG_VFO_CURR, chan->mode, chan->width); drake_set_func(rig, RIG_VFO_CURR, RIG_FUNC_NB, (chan->funcs & RIG_FUNC_NB) == RIG_FUNC_NB); drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_AGC, chan->levels[rig_setting2idx(RIG_LEVEL_AGC)]); drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_PREAMP, chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)]); drake_set_level(rig, RIG_VFO_CURR, RIG_LEVEL_ATT, chan->levels[rig_setting2idx(RIG_LEVEL_ATT)]); drake_set_func(rig, RIG_VFO_CURR, RIG_FUNC_MN, (chan->funcs & RIG_FUNC_MN) == RIG_FUNC_MN); SNPRINTF(mdbuf, sizeof(mdbuf), "PR" EOM "%03d" EOM, chan->channel_num); retval = drake_transaction(rig, mdbuf, strlen(mdbuf), ackbuf, &ack_len); if (old_vfo == RIG_VFO_MEM) { drake_set_mem(rig, RIG_VFO_CURR, old_chan); } return retval; } /* * drake_get_chan * Assumes rig!=NULL */ int drake_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct drake_priv_data *priv = STATE(rig)->priv; vfo_t old_vfo; int old_chan; char mdbuf[BUFSZ], freqstr[BUFSZ]; int mdbuf_len, retval; chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 0; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, " "); drake_get_vfo(rig, &old_vfo); old_chan = 0; if (old_vfo == RIG_VFO_MEM) { old_chan = priv->curr_ch; } //go to new channel retval = drake_set_mem(rig, RIG_VFO_CURR, chan->channel_num); if (retval != RIG_OK) { return RIG_OK; } //now decipher it retval = drake_transaction(rig, "RA" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len < 35) { rig_debug(RIG_DEBUG_ERR, "drake_get_channel: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } if ((mdbuf[5] >= '4') && (mdbuf[5] <= '?')) { chan->funcs |= RIG_FUNC_NB; } switch (mdbuf[5] & 0x33) { case '0': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; break; case '2': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; break; case '3': chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_SLOW; break; default : chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_FAST; } if ((mdbuf[6] & 0x3c) == '8') { chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 10; } if ((mdbuf[6] & 0x3c) == '4') { chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 10; } if ((mdbuf[6] & 0x32) == '2') { chan->funcs |= RIG_FUNC_MN; } switch (mdbuf[7] & 0x3c) { case '0': chan->ant = RIG_ANT_1; break; case '4': chan->ant = RIG_ANT_3; break; case '8': chan->ant = RIG_ANT_2; break; default : chan->ant = RIG_ANT_NONE; } switch (mdbuf[8] & 0x37) { case '0': chan->width = s_Hz(500); break; case '1': chan->width = s_Hz(1800); break; case '2': chan->width = s_Hz(2300); break; case '3': chan->width = s_Hz(4000); break; case '4': chan->width = s_Hz(6000); break; default : chan->width = RIG_PASSBAND_NORMAL; } if ((mdbuf[8] >= '0') && (mdbuf[8] <= '4')) { switch (mdbuf[7] & 0x33) { case '0': chan->mode = RIG_MODE_LSB; break; case '1': chan->mode = RIG_MODE_RTTY; break; case '2': chan->mode = RIG_MODE_FM; chan->width = s_Hz(12000); break; default : chan->mode = RIG_MODE_NONE; } } else { switch (mdbuf[7] & 0x33) { case '0': chan->mode = RIG_MODE_USB; break; case '1': chan->mode = RIG_MODE_CW; break; case '2': chan->mode = RIG_MODE_AM; break; default : chan->mode = RIG_MODE_NONE; } } if ((mdbuf[9] & 0x34) == '4') { if (chan->mode == RIG_MODE_AM) { chan->mode = RIG_MODE_AMS; } else if (chan->mode == RIG_MODE_USB) { chan->mode = RIG_MODE_ECSSUSB; } else if (chan->mode == RIG_MODE_LSB) { chan->mode = RIG_MODE_ECSSLSB; } } strncpy(freqstr, mdbuf + 11, 9); freqstr[9] = 0x00; if ((mdbuf[21] == 'k') || (mdbuf[21] == 'K')) { chan->freq = strtod(freqstr, NULL) * 1000.0; } if ((mdbuf[21] == 'm') || (mdbuf[21] == 'M')) { chan->freq = strtod(freqstr, NULL) * 1000000.0; } strncpy(chan->channel_desc, mdbuf + 25, 7); chan->channel_desc[7] = '\0'; // in case strncpy did not terminate the string //now put the radio back the way it was //we apparently can't do a read-only channel read if (old_vfo != RIG_VFO_MEM) { retval = drake_set_vfo(rig, RIG_VFO_VFO); if (retval != RIG_OK) { return retval; } } else { retval = drake_set_mem(rig, RIG_VFO_CURR, old_chan); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * drake_vfo_op * Assumes rig!=NULL */ int drake_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct drake_priv_data *priv = STATE(rig)->priv; char buf[16], ackbuf[16]; int len, ack_len, retval; switch (op) { case RIG_OP_UP: SNPRINTF(buf, sizeof(buf), "U"); break; case RIG_OP_DOWN: SNPRINTF(buf, sizeof(buf), "D"); break; case RIG_OP_CPY: SNPRINTF(buf, sizeof(buf), "A E B" EOM); break; case RIG_OP_TO_VFO: /* len = SNPRINTF(buf,"C%03d" EOM, priv->curr_ch); */ SNPRINTF(buf, sizeof(buf), "F" EOM); break; case RIG_OP_MCL: SNPRINTF(buf, sizeof(buf), "EC%03d" EOM, priv->curr_ch); break; case RIG_OP_FROM_VFO: SNPRINTF(buf, sizeof(buf), "PR" EOM "%03d" EOM, priv->curr_ch); break; default: return -RIG_EINVAL; } len = strlen(buf); retval = drake_transaction(rig, buf, len, buf[len - 1] == 0x0d ? ackbuf : NULL, &ack_len); return retval; } /* * drake_set_func * Assumes rig!=NULL */ int drake_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[16], ackbuf[16]; int ack_len, retval; switch (func) { case RIG_FUNC_MN: SNPRINTF(buf, sizeof(buf), "N%c" EOM, status ? 'O' : 'F'); break; case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "L%c" EOM, status ? 'O' : 'F'); break; case RIG_FUNC_NB: /* TODO: NB narrow */ SNPRINTF(buf, sizeof(buf), "B%c" EOM, status ? 'W' : 'F'); break; default: return -RIG_EINVAL; } retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } /* * drake_get_func * Assumes rig!=NULL */ int drake_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int mdbuf_len, retval; char mdbuf[BUFSZ]; char mc; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdbuf_len); if (retval != RIG_OK) { return retval; } if (mdbuf_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_func: wrong answer %s, " "len=%d\n", mdbuf, mdbuf_len); return -RIG_ERJCTED; } switch (func) { case RIG_FUNC_MN: mc = mdbuf[2]; *status = ((mc & 0x32) == '2'); break; case RIG_FUNC_NB: /* TODO: NB narrow */ mc = mdbuf[1]; *status = ((mc >= '4') && (mc <= '?')); break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get func %s\n", rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * drake_set_level * Assumes rig!=NULL */ int drake_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[16], ackbuf[16]; int ack_len, retval; switch (level) { case RIG_LEVEL_PREAMP: SNPRINTF(buf, sizeof(buf), "G%c" EOM, val.i ? '+' : '0'); break; case RIG_LEVEL_ATT: SNPRINTF(buf, sizeof(buf), "G%c" EOM, val.i ? '-' : '0'); break; case RIG_LEVEL_AGC: SNPRINTF(buf, sizeof(buf), "A%c" EOM, val.i == RIG_AGC_OFF ? 'O' : (val.i == RIG_AGC_FAST ? 'F' : 'S')); break; default: return -RIG_EINVAL; } retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } /* * drake_get_level * Assumes rig!=NULL */ int drake_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int lvl_len, retval, ss; char lvlbuf[BUFSZ]; char mc; if ((level != RIG_LEVEL_RAWSTR) && (level != RIG_LEVEL_STRENGTH)) { retval = drake_transaction(rig, "RM" EOM, 3, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "drake_get_level: wrong answer %s, " "len=%d\n", lvlbuf, lvl_len); return -RIG_ERJCTED; } } switch (level) { case RIG_LEVEL_RAWSTR: retval = drake_transaction(rig, "RSS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "drake_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[3] = '\0'; val->i = strtol(lvlbuf + 1, (char **)NULL, 16); break; case RIG_LEVEL_STRENGTH: retval = drake_transaction(rig, "RSS" EOM, 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "drake_get_level: wrong answer" "len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[3] = '\0'; ss = strtol(lvlbuf + 1, (char **)NULL, 16); val->i = (int)rig_raw2val(ss, &rig->caps->str_cal); break; case RIG_LEVEL_PREAMP: mc = lvlbuf[2]; if ((mc & 0x3c) == '8') { val->i = 10; } else { val->i = 0; } break; case RIG_LEVEL_ATT: mc = lvlbuf[2]; if ((mc & 0x3c) == '4') { val->i = 10; } else { val->i = 0; } break; case RIG_LEVEL_AGC: mc = lvlbuf[1]; switch (mc & 0x33) { case '0': val->i = RIG_AGC_OFF; break; case '2': val->i = RIG_AGC_FAST; break; case '3': val->i = RIG_AGC_SLOW; break; default : val->i = RIG_AGC_FAST; } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int drake_set_powerstat(RIG *rig, powerstat_t status) { char buf[16], ackbuf[16]; int ack_len, retval; SNPRINTF(buf, sizeof(buf), "P%c" EOM, status == RIG_POWER_OFF ? 'F' : 'O'); retval = drake_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } int drake_get_powerstat(RIG *rig, powerstat_t *status) { int mdlen, retval; char mdbuf[BUFSZ]; retval = drake_transaction(rig, "RM" EOM, 3, mdbuf, &mdlen); if (retval != RIG_OK) { return retval; } *status = (mdlen == 8); return RIG_OK; } /* * drake_set_freq * Assumes rig!=NULL */ const char *drake_get_info(RIG *rig) { static char idbuf[BUFSZ]; int retval, id_len; retval = drake_transaction(rig, "ID" EOM, 3, idbuf, &id_len); if (retval != RIG_OK) { return NULL; } idbuf[id_len] = '\0'; return idbuf; } /* * initrigs_drake is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(drake) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&r8a_caps); rig_register(&r8b_caps); return RIG_OK; } /* * probe_drake(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(drake) { static char idbuf[BUFSZ]; int retval, id_len; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->parm.serial.rate = r8b_caps.serial_rate_max; port->write_delay = port->post_write_delay = 0; port->timeout = 50; port->retry = 1; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } retval = write_block(port, (unsigned char *) "ID" EOM, 3); id_len = read_string(port, (unsigned char *) idbuf, BUFSZ, LF, 1, 0, 1); close(port->fd); if (retval != RIG_OK || id_len <= 0 || id_len >= BUFSZ) { return RIG_MODEL_NONE; } idbuf[id_len] = '\0'; if (!strcmp(idbuf, "R8B")) { if (cfunc) { (*cfunc)(port, RIG_MODEL_DKR8B, data); } return RIG_MODEL_DKR8B; } if (!strcmp(idbuf, "R8A")) /* TBC */ { if (cfunc) { (*cfunc)(port, RIG_MODEL_DKR8A, data); } return RIG_MODEL_DKR8A; } /* * not found... */ if (memcmp(idbuf, "ID" EOM, 3)) /* catch loopback serial */ rig_debug(RIG_DEBUG_VERBOSE, "probe_drake: found unknown device " "with ID '%s', please report to Hamlib " "developers.\n", idbuf); return RIG_MODEL_NONE; } hamlib-4.6.2/rigs/drake/r8a.c0000644000175000017500000001243114752216205012575 00000000000000/* * Hamlib Drake backend - R-8A description * Copyright (c) 2001-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "drake.h" #define R8A_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_FM) #define R8A_FUNC (RIG_FUNC_MN|RIG_FUNC_LOCK|RIG_FUNC_NB) #define R8A_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define R8A_PARM_ALL (RIG_PARM_TIME) #define R8A_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_VFO|RIG_VFO_MEM) #define R8A_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_MCL|RIG_OP_CPY) #define R8A_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define R8A_STR_CAL { 16, { \ { 0, -60 }, \ { 1, -48 }, \ { 11, -42 }, \ { 27, -36 }, \ { 39, -30 }, \ { 51, -24 }, \ { 64, -18 }, \ { 80, -12 }, \ { 97, -6 }, \ { 116, 0 }, \ { 138, 10 }, \ { 163, 20 }, \ { 195, 30 }, \ { 217, 40 }, \ { 228, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define DRAKE_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = R8A_FUNC, \ .levels = RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ } /* * R-8A rig capabilities. * * specs: http://www.dxing.com/rx/r8.htm * */ struct rig_caps r8a_caps = { RIG_MODEL(RIG_MODEL_DKR8A), .model_name = "R-8A", .mfg_name = "Drake", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = R8A_FUNC, .has_set_func = R8A_FUNC, .has_get_level = R8A_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(R8A_LEVEL_ALL), .has_get_parm = R8A_PARM_ALL, .has_set_parm = RIG_PARM_SET(R8A_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, /* TODO: actually has RIG_TRN_RIG */ .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = R8A_VFO_OPS, .chan_list = { { 0, 439, RIG_MTYPE_MEM, DRAKE_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(100), MHz(30), R8A_MODES, -1, -1, R8A_VFO, R8A_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), R8A_MODES, -1, -1, R8A_VFO, R8A_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {R8A_MODES, 10}, {R8A_MODES, 100}, {R8A_MODES, kHz(1)}, {R8A_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(4)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(1.8)}, RIG_FLT_END, }, .str_cal = R8A_STR_CAL, .priv = NULL, .rig_init = drake_init, .rig_cleanup = drake_cleanup, .set_freq = drake_set_freq, .get_freq = drake_get_freq, .set_vfo = drake_set_vfo, .get_vfo = drake_get_vfo, .set_mode = drake_set_mode, .get_mode = drake_get_mode, .set_func = drake_set_func, .get_func = drake_get_func, .set_level = drake_set_level, .get_level = drake_get_level, .set_ant = drake_set_ant, .get_ant = drake_get_ant, .set_mem = drake_set_mem, .get_mem = drake_get_mem, .set_channel = drake_set_chan, .get_channel = drake_get_chan, .vfo_op = drake_vfo_op, .set_powerstat = drake_set_powerstat, .get_powerstat = drake_get_powerstat, .get_info = drake_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/drake/r8b.c0000644000175000017500000001242314752216205012577 00000000000000/* * Hamlib Drake backend - R-8B description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "drake.h" #define R8B_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_ECSS|RIG_MODE_FM) #define R8B_FUNC (RIG_FUNC_MN|RIG_FUNC_LOCK|RIG_FUNC_NB) #define R8B_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define R8B_PARM_ALL (RIG_PARM_TIME) #define R8B_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_VFO|RIG_VFO_MEM) #define R8B_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_MCL|RIG_OP_CPY) #define R8B_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define R8B_STR_CAL { 16, { \ { 0, -60 }, \ { 1, -48 }, \ { 11, -42 }, \ { 27, -36 }, \ { 39, -30 }, \ { 51, -24 }, \ { 64, -18 }, \ { 80, -12 }, \ { 97, -6 }, \ { 116, 0 }, \ { 138, 10 }, \ { 163, 20 }, \ { 195, 30 }, \ { 217, 40 }, \ { 228, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define DRAKE_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = 1, \ .levels = RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ } /* * R-8B rig capabilities. * * manual: http://www.rldrake.com/swl/R8B.pdf * */ struct rig_caps r8b_caps = { RIG_MODEL(RIG_MODEL_DKR8B), .model_name = "R-8B", .mfg_name = "Drake", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 1, .timeout = 200, .retry = 3, .has_get_func = R8B_FUNC, .has_set_func = R8B_FUNC, .has_get_level = R8B_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(R8B_LEVEL_ALL), .has_get_parm = R8B_PARM_ALL, .has_set_parm = RIG_PARM_SET(R8B_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, /* TODO: actually has RIG_TRN_RIG */ .bank_qty = 0, .chan_desc_sz = 7, .vfo_ops = R8B_VFO_OPS, .chan_list = { { 0, 999, RIG_MTYPE_MEM, DRAKE_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(10), MHz(30), R8B_MODES, -1, -1, R8B_VFO, R8B_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), R8B_MODES, -1, -1, R8B_VFO, R8B_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {R8B_MODES, 10}, {R8B_MODES, 100}, {R8B_MODES, kHz(1)}, {R8B_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_ECSS, kHz(4)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(1.8)}, RIG_FLT_END, }, .str_cal = R8B_STR_CAL, .priv = NULL, .rig_init = drake_init, .rig_cleanup = drake_cleanup, .set_freq = drake_set_freq, .get_freq = drake_get_freq, .set_vfo = drake_set_vfo, .get_vfo = drake_get_vfo, .set_mode = drake_set_mode, .get_mode = drake_get_mode, .set_func = drake_set_func, .get_func = drake_get_func, .set_level = drake_set_level, .get_level = drake_get_level, .set_ant = drake_set_ant, .get_ant = drake_get_ant, .set_mem = drake_set_mem, .get_mem = drake_get_mem, .set_channel = drake_set_chan, .get_channel = drake_get_chan, .vfo_op = drake_vfo_op, .set_powerstat = drake_set_powerstat, .get_powerstat = drake_get_powerstat, .get_info = drake_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/drake/drake.h0000644000175000017500000000453014752216205013177 00000000000000/* * Hamlib Drake backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _DRAKE_H #define _DRAKE_H 1 #include #define BACKEND_VER "20200319" struct drake_priv_data { int curr_ch; }; int drake_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int drake_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int drake_set_vfo(RIG *rig, vfo_t vfo); int drake_get_vfo(RIG *rig, vfo_t *vfo); int drake_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int drake_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int drake_init(RIG *rig); int drake_cleanup(RIG *rig); int drake_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int drake_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int drake_set_mem(RIG *rig, vfo_t vfo, int ch); int drake_get_mem(RIG *rig, vfo_t vfo, int *ch); int drake_set_chan(RIG *rig, vfo_t vfo, const channel_t *chan); int drake_get_chan(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int drake_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int drake_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int drake_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int drake_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int drake_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int drake_set_powerstat (RIG * rig, powerstat_t status); int drake_get_powerstat (RIG * rig, powerstat_t *status); const char *drake_get_info(RIG *rig); extern struct rig_caps r8a_caps; extern struct rig_caps r8b_caps; #endif /* _DRAKE_H */ hamlib-4.6.2/rigs/gomspace/0000755000175000017500000000000014752216244012531 500000000000000hamlib-4.6.2/rigs/gomspace/Makefile.am0000644000175000017500000000022214752216205014476 00000000000000GOMSPACESRC = gs100.c gs100.h noinst_LTLIBRARIES = libhamlib-gomspace.la libhamlib_gomspace_la_SOURCES = $(GOMSPACESRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/gomspace/Makefile.in0000644000175000017500000005212314752216216014520 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/gomspace ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_gomspace_la_LIBADD = am__objects_1 = gs100.lo am_libhamlib_gomspace_la_OBJECTS = $(am__objects_1) libhamlib_gomspace_la_OBJECTS = $(am_libhamlib_gomspace_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/gs100.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_gomspace_la_SOURCES) DIST_SOURCES = $(libhamlib_gomspace_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ GOMSPACESRC = gs100.c gs100.h noinst_LTLIBRARIES = libhamlib-gomspace.la libhamlib_gomspace_la_SOURCES = $(GOMSPACESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/gomspace/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/gomspace/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-gomspace.la: $(libhamlib_gomspace_la_OBJECTS) $(libhamlib_gomspace_la_DEPENDENCIES) $(EXTRA_libhamlib_gomspace_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_gomspace_la_OBJECTS) $(libhamlib_gomspace_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs100.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/gs100.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/gs100.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/gomspace/gs100.h0000644000175000017500000000371214752216205013454 00000000000000/* * GomSpace backend and the GS100 radio control module * * Created in 2022 by Richard Linhart OK1CTR OK1CTR@gmail.com * and used during VZLUSAT-2 satellite mission. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _GS100_H #define _GS100_H 1 /* Includes ------------------------------------------------------------------*/ #include "hamlib/rig.h" #include "token.h" /* Definitions ---------------------------------------------------------------*/ /* backend conf */ #define TOK_CFG_MAGICCONF TOKEN_BACKEND(1) #define TOK_CFG_STATIC_DATA TOKEN_BACKEND(2) /* ext_level's and ext_parm's tokens */ #define TOK_EL_MAGICLEVEL TOKEN_BACKEND(1) #define TOK_EL_MAGICFUNC TOKEN_BACKEND(2) #define TOK_EL_MAGICOP TOKEN_BACKEND(3) #define TOK_EP_MAGICPARM TOKEN_BACKEND(4) #define TOK_EL_MAGICCOMBO TOKEN_BACKEND(5) #define TOK_EL_MAGICEXTFUNC TOKEN_BACKEND(6) /* Public variables ----------------------------------------------------------*/ /* RIG capabilities descriptions */ extern struct rig_caps gs100_caps; extern struct rig_caps netrigctl_caps; extern struct rig_caps flrig_caps; extern struct rig_caps trxmanager_caps; /*----------------------------------------------------------------------------*/ #endif /* _GS100_H */ hamlib-4.6.2/rigs/gomspace/Android.mk0000644000175000017500000000037314752216205014362 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := gs100.c LOCAL_MODULE := gomspace LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/gomspace/gs100.c0000644000175000017500000003647614752216205013464 00000000000000/* * GomSpace backend and the GS100 radio control module * * Created in 2022 by Richard Linhart OK1CTR OK1CTR@gmail.com * and used during VZLUSAT-2 satellite mission. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Includes ------------------------------------------------------------------*/ #include #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "gs100.h" /* Private Defines -----------------------------------------------------------*/ // If defined, commands are software simulated only #undef _LOCAL_SIMULATION_ // If true, configuration table switching is minimized #define PARAM_MEM_MINIMAL 1 // Buffer size for serial transfers #define BUFSZ 256 // Last character on each line received from RIG #define GOM_STOPSET "\n" // Exact character sequence on the RIG's command prompt #define GOM_PROMPT "\x1B[1;32mnanocom-ax\x1B[1;30m # \x1B[0m\x1B[0m" // Maximum number of lines parsed from GS100 response #define GOM_MAXLINES 20 // RIG's parametric table number for receive #define GOM_CONFIG_TAB_RX 1 // RIG's parametric table number for transmit #define GOM_CONFIG_TAB_TX 5 /* Private Typedefs ----------------------------------------------------------*/ /** * GS100 rig private data structure */ struct gs100_priv_data { freq_t freq_rx; ///< currently just for backup and TRX emulation freq_t freq_tx; ///< currently just for backup and TRX emulation int param_mem; ///< last value of configuration table selection }; /* Imported Functions --------------------------------------------------------*/ struct ext_list *alloc_init_ext(const struct confparams *cfp); struct ext_list *find_ext(struct ext_list *elp, hamlib_token_t token); /* Private function prototypes -----------------------------------------------*/ /** * Set variable in the GS100 configuration table */ static int gomx_set(RIG *rig, int table, char *varname, char *varvalue); /** * Get variable from the GS100 configuration table */ static int gomx_get(RIG *rig, int table, char *varname, const char *varvalue, int varvalue_len); /** * Sends a message to the GS100 and parses response lines */ static int gomx_transaction(RIG *rig, char *message, char *response); /* Functions -----------------------------------------------------------------*/ /* GS100 transceiver control init */ static int gs100_init(RIG *rig) { __attribute__((unused)) struct gs100_priv_data *priv; ENTERFUNC; priv = (struct gs100_priv_data *)calloc(1, sizeof(struct gs100_priv_data)); if (!priv) { RETURNFUNC(-RIG_ENOMEM); } STATE(rig)->priv = (void *)priv; #ifdef _LOCAL_SIMULATION_ RIGPORT(rig)->type.rig = RIG_PORT_NONE; // just simulation priv->freq_rx = rig->caps->rx_range_list1->startf; priv->freq_tx = rig->caps->tx_range_list1->startf; #endif priv->param_mem = -1; // means undefined last selection RETURNFUNC(RIG_OK); } /* GS100 transceiver control deinit */ static int gs100_cleanup(RIG *rig) { ENTERFUNC; if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* GS100 transceiver open */ static int gs100_open(RIG *rig) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_GS100) { rig_debug(RIG_DEBUG_VERBOSE, "%s: OPENING'\n", __func__); } RETURNFUNC(RIG_OK); } /* GS100 transceiver close */ static int gs100_close(RIG *rig) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_GS100) { rig_debug(RIG_DEBUG_VERBOSE, "%s: CLOSING'\n", __func__); } RETURNFUNC(RIG_OK); } /* GS100 transceiver set configuration */ static int gs100_set_conf(RIG *rig, hamlib_token_t token, const char *val) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; ENTERFUNC; priv = (struct gs100_priv_data *)STATE(rig)->priv; switch (token) { case 0: break; case 1: break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* GS100 transceiver get configuration */ static int gs100_get_conf(RIG *rig, hamlib_token_t token, char *val) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; ENTERFUNC; priv = (struct gs100_priv_data *)STATE(rig)->priv; switch (token) { case 0: break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* GS100 transceiver set receiver frequency */ static int gs100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char fstr[20], value[20]; int retval; ENTERFUNC; // reporting sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: fstr = '%s'\n", __func__, fstr); #ifdef _LOCAL_SIMULATION_ priv->freq_rx = freq; #endif // range check - GS100 don't do it! if (freq < rig->caps->rx_range_list1->startf || freq > rig->caps->rx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } // perform set command sprintf(value, "%1.0lf", freq); retval = gomx_set(rig, GOM_CONFIG_TAB_RX, "freq", value); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* GS100 transceiver get receiver frequency */ static int gs100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char resp[20]; int retval; freq_t f; ENTERFUNC; // perform the get command retval = gomx_get(rig, GOM_CONFIG_TAB_RX, "freq", resp, sizeof(resp)); if (retval != RIG_OK) { RETURNFUNC(retval); } #ifdef _LOCAL_SIMULATION_ *freq = priv->freq_rx; #else retval = sscanf(resp, "%lf", &f); #endif // relevance check if (retval != 1) { RETURNFUNC(-RIG_EPROTO); } if (f < rig->caps->rx_range_list1->startf || f > rig->caps->rx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } *freq = f; RETURNFUNC(RIG_OK); } /* GS100 transceiver set transmitter frequency */ static int gs100_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char fstr[20], value[20]; int retval; ENTERFUNC; // reporting sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: fstr = '%s'\n", __func__, fstr); #ifdef _LOCAL_SIMULATION_ priv->freq_tx = freq; #endif // range check - GS100 don't do it! if (freq < rig->caps->tx_range_list1->startf || freq > rig->caps->tx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } // perform set command sprintf(value, "%1.0lf", freq); retval = gomx_set(rig, GOM_CONFIG_TAB_TX, "freq", value); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* GS100 transceiver get transmitter frequency */ static int gs100_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { #ifdef _LOCAL_SIMULATION_ __attribute__((unused)) const struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; #endif char resp[20]; int retval; freq_t f; ENTERFUNC; // perform the get command retval = gomx_get(rig, GOM_CONFIG_TAB_TX, "freq", resp, sizeof(resp)); if (retval != RIG_OK) { RETURNFUNC(retval); } #ifdef _LOCAL_SIMULATION_ *freq = priv->freq_tx; #else retval = sscanf(resp, "%lf", &f); #endif // relevance check if (retval != 1) { RETURNFUNC(-RIG_EPROTO); } if (f < rig->caps->tx_range_list1->startf || f > rig->caps->tx_range_list1->endf) { RETURNFUNC(-RIG_EDOM); } *freq = f; RETURNFUNC(RIG_OK); } /* GS100 transceiver get info */ static const char *gs100_get_info(RIG *rig) { return ("Gomspace Ground Station Transceiver GS100"); } /* The HAMLIB RIG Capabilities Structure Definition --------------------------*/ #define GS100_FUNC (0) #define GS100_LEVEL (0) #define GS100_PARM (0) #define GS100_VFO_OPS RIG_OP_TUNE #define GS100_VFOS (RIG_VFO_A) #define GS100_MODES (RIG_MODE_PKTFM) struct rig_caps GS100_caps = { RIG_MODEL(RIG_MODEL_GS100), .model_name = "GS100", .mfg_name = "GOMSPACE", .version = "20211117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 115200, .serial_rate_max = 500000, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 1, .post_write_delay = 1, .timeout = 250, .retry = 0, .has_get_func = GS100_FUNC, .has_set_func = GS100_FUNC, .has_get_level = GS100_LEVEL, .has_set_level = GS100_LEVEL, .has_get_parm = GS100_PARM, .has_set_parm = GS100_PARM, .vfo_ops = GS100_VFO_OPS, .rx_range_list1 = { { .startf = MHz(430), .endf = MHz(440), .modes = GS100_MODES, .low_power = 0, .high_power = 0, GS100_VFOS, .label = "GS100#1" }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = MHz(430), .endf = MHz(440), .modes = GS100_MODES, .low_power = 0, .high_power = 0, GS100_VFOS, .label = "GS100#1" }, RIG_FRNG_END, }, .tuning_steps = { {GS100_MODES, Hz(10)}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, .rig_init = gs100_init, .rig_cleanup = gs100_cleanup, .rig_open = gs100_open, .rig_close = gs100_close, .set_conf = gs100_set_conf, .get_conf = gs100_get_conf, .set_freq = gs100_set_freq, .get_freq = gs100_get_freq, .set_split_freq = gs100_set_tx_freq, .get_split_freq = gs100_get_tx_freq, .get_info = gs100_get_info, }; /* Private functions ---------------------------------------------------------*/ /* Set variable in the GS100 configuration table */ static int gomx_set(RIG *rig, int table, char *varname, char *varvalue) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; int retval; char msg[BUFSZ], resp[BUFSZ]; assert(rig != NULL); assert(varname != NULL); assert(varvalue != NULL); rig_debug(RIG_DEBUG_TRACE, "%s: table=%d, '%s' = '%s'\n", __func__, table, varname, varvalue); if (!PARAM_MEM_MINIMAL || table != priv->param_mem) { // select the configuration table priv->param_mem = table; sprintf(msg, "param mem %d\n", table); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } } // set the variable sprintf(msg, "param set %s %s\n", varname, varvalue); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } // check response if (strlen(resp) > 0) { return (-RIG_EPROTO); } return (RIG_OK); } /* Get variable from the GS100 configuration table */ static int gomx_get(RIG *rig, int table, char *varname, const char *varvalue, int varvalue_len) { __attribute__((unused)) struct gs100_priv_data *priv = (struct gs100_priv_data *)STATE(rig)->priv; int retval; char msg[BUFSZ], resp[BUFSZ], *c; char fmt[32]; assert(rig != NULL); assert(varname != NULL); assert(varvalue != NULL); rig_debug(RIG_DEBUG_TRACE, "%s: table=%d, '%s'\n", __func__, table, varname); if (!PARAM_MEM_MINIMAL || table != priv->param_mem) { // select the configuration table priv->param_mem = table; sprintf(msg, "param mem %d\n", table); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } } // get the variable sprintf(msg, "param get %19s\n", varname); retval = gomx_transaction(rig, msg, resp); if (retval != RIG_OK) { return (retval); } // check response and extract the value if ((c = strchr(resp, '=')) == NULL) { return (-RIG_EPROTO); } snprintf(fmt, sizeof(fmt), "%%%ds", varvalue_len); if (sscanf(c + 1, fmt, varvalue_len) != 1) { return (-RIG_EPROTO); } return (RIG_OK); } /* Sends a message to the GS100 and parses response lines */ static int gomx_transaction(RIG *rig, char *message, char *response) { hamlib_port_t *rp; int retval, n = 0; char buf[BUFSZ]; assert(rig != NULL); assert(message != NULL); assert(response != NULL); rig_debug(RIG_DEBUG_TRACE, "%s: msg='%s'\n", __func__, message == NULL ? "NULL" : message); rp = RIGPORT(rig); // send message to the transceiver rig_flush(rp); retval = write_block(rp, (uint8_t *)message, strlen(message)); if (retval != RIG_OK) { return (retval); } while (1) { // read the response line retval = read_string(rp, (unsigned char *)buf, BUFSZ, (const char *)GOM_STOPSET, 0, strlen(GOM_STOPSET), 0); if (retval < 0) { return (retval); } if (retval == 0) { return (-RIG_ETIMEOUT); } n++; // prompt is always the last line if (strcmp(buf, GOM_PROMPT) == 0) { break; } // before last line would be the response if (n > 1) { strcpy(response, buf); } else { *response = '\0'; } // don't return command echo if (n > GOM_MAXLINES) { return (-RIG_EPROTO); } } // report the response rig_debug(RIG_DEBUG_VERBOSE, "%s: returning response='%s'\n", __func__, response == NULL ? "NULL" : response); return (RIG_OK); } /* System Integration Functions ----------------------------------------------*/ /* Init RIG backend function */ DECLARE_INITRIG_BACKEND(gomspace) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&GS100_caps); return (RIG_OK); } /* Probe RIG backend function */ DECLARE_PROBERIG_BACKEND(gomspace) { return (RIG_MODEL_GS100); } /*----------------------------------------------------------------------------*/ hamlib-4.6.2/rigs/icom/0000755000175000017500000000000014752216243011661 500000000000000hamlib-4.6.2/rigs/icom/icom_defs.h0000644000175000017500000005601614752216205013710 00000000000000/* * Hamlib CI-V backend - defines for the ICOM "CI-V" interface. * Copyright (c) 2000-2016 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICOM_DEFS_H #define _ICOM_DEFS_H 1 /* * CI-V frame codes */ #define PR 0xfe /* Preamble code */ #define CTRLID 0xe0 /* Controllers's default address */ #define BCASTID 0x00 /* Broadcast address */ #define FI 0xfd /* End of message code */ #define ACK 0xfb /* OK code */ #define NAK 0xfa /* NG code */ #define COL 0xfc /* CI-V bus collision detected */ #define PAD 0xff /* Transmit padding */ #define ACKFRMLEN 6 /* reply frame length */ #define S_NONE -1 /* * Arguments length in bytes */ #define CHAN_NB_LEN 2 #define BANK_NB_LEN 2 #define OFFS_LEN 3 /* * Cn controller commands * Most radios have 2 or 3 receive passbands available. Where only 2 are available they are selected by 01 for wide and 02 for narrow Actual bandwidth is determined by the filters installed. With the newer DSP rigs there are 3 presets 01 = wide 02 = middle and 03 = narrow. Actually, you can set change any of these presets to any thing you want. * Notes: * The following only applies to IC-706. * 1. When wide or normal op available: add "00" for wide, "01" normal * Normal or narrow op: add "00" for normal, "01" for narrow * Wide, normal or narrow op: add "00" for wide, "01" normal, "02" narrow * 2. Memory channel number 1A=0100/1b=0101, 2A=0102/2b=0103, * 3A=0104/3b=0105, C1=0106, C2=0107 */ #define C_SND_FREQ 0x00 /* Send frequency data transceive mode does not ack*/ #define C_SND_MODE 0x01 /* Send mode data, Sc for transceive mode does not ack */ #define C_RD_BAND 0x02 /* Read band edge frequencies */ #define C_RD_FREQ 0x03 /* Read display frequency */ #define C_RD_MODE 0x04 /* Read display mode */ #define C_SET_FREQ 0x05 /* Set frequency data(1) */ #define C_SET_MODE 0x06 /* Set mode data, Sc */ #define C_SET_VFO 0x07 /* Set VFO */ #define C_SET_MEM 0x08 /* Set channel, Sc(2) */ #define C_WR_MEM 0x09 /* Write memory */ #define C_MEM2VFO 0x0a /* Memory to VFO */ #define C_CLR_MEM 0x0b /* Memory clear */ #define C_RD_OFFS 0x0c /* Read duplex offset frequency; default changes with HF/6M/2M */ #define C_SET_OFFS 0x0d /* Set duplex offset frequency */ #define C_CTL_SCAN 0x0e /* Control scan, Sc */ #define C_CTL_SPLT 0x0f /* Control split, and duplex mode Sc */ #define C_SET_TS 0x10 /* Set tuning step, Sc */ #define C_CTL_ATT 0x11 /* Set/get attenuator, Sc */ #define C_CTL_ANT 0x12 /* Set/get antenna, Sc */ #define C_CTL_ANN 0x13 /* Control announce (speech synth.), Sc */ #define C_CTL_LVL 0x14 /* Set AF/RF/squelch, Sc */ #define C_RD_SQSM 0x15 /* Read squelch condition/S-meter level, Sc */ #define C_CTL_FUNC 0x16 /* Function settings (AGC,NB,etc.), Sc */ #define C_SND_CW 0x17 /* Send CW message */ #define C_SET_PWR 0x18 /* Set Power ON/OFF, Sc */ #define C_RD_TRXID 0x19 /* Read transceiver ID code */ #define C_CTL_MEM 0x1a /* Misc memory/bank/rig control functions, Sc */ #define C_SET_TONE 0x1b /* Set tone frequency */ #define C_CTL_PTT 0x1c /* Control Transmit On/Off, Sc */ #define C_CTL_EDGE 0x1e /* Band edges */ #define C_CTL_DVT 0x1f /* Digital modes calsigns & messages */ #define C_CTL_DIG 0x20 /* Digital modes settings & status */ #define C_CTL_RIT 0x21 /* RIT/XIT control */ #define C_CTL_DSD 0x22 /* D-STAR Data */ #define C_SEND_SEL_FREQ 0x25 /* Send/Recv sel/unsel VFO frequency */ #define C_SEND_SEL_MODE 0x26 /* Send/Recv sel/unsel VFO mode & filter */ #define C_CTL_SCP 0x27 /* Scope control & data */ #define C_SND_VOICE 0x28 /* Transmit Voice Memory Contents */ #define C_CTL_MTEXT 0x70 /* Microtelecom Extension */ #define C_CTL_MISC 0x7f /* Miscellaneous control, Sc */ /* * Sc controller sub commands */ /* * Set mode data (C_SET_MODE) sub commands */ #define S_LSB 0x00 /* Set to LSB */ #define S_USB 0x01 /* Set to USB */ #define S_AM 0x02 /* Set to AM */ #define S_AMN 0x02 /* Set to AM-N */ #define S_CW 0x03 /* Set to CW */ #define S_RTTY 0x04 /* Set to RTTY */ #define S_FM 0x05 /* Set to FM */ #define S_FMN 0x05 /* Set to FM-N */ #define S_WFM 0x06 /* Set to Wide FM */ #define S_CWR 0x07 /* Set to CW Reverse */ #define S_RTTYR 0x08 /* Set to RTTY Reverse */ #define S_AMS 0x11 /* Set to AMS */ #define S_PSK 0x12 /* 7800 PSK USB */ #define S_PSKR 0x13 /* 7800 PSK LSB */ #define S_SAML 0x14 /* Set to AMS-L */ #define S_SAMU 0x15 /* Set to AMS-U */ #define S_P25 0x16 /* Set to P25 */ #define S_DSTAR 0x17 /* Set to D-STAR */ #define S_DPMR 0x18 /* Set to dPMR */ #define S_NXDNVN 0x19 /* Set to NXDN_VN */ #define S_NXDN_N 0x20 /* Set to NXDN-N */ #define S_DCR 0x21 /* Set to DCR */ #define S_DD 0x22 /* Set to DD 1200Mhz only? */ #define S_R7000_SSB 0x05 /* Set to SSB on R-7000 */ /* filter width coding for older ICOM rigs with 2 filter width */ /* there is no special 'wide' for that rigs */ #define PD_MEDIUM_2 0x01 /* Medium */ #define PD_NARROW_2 0x02 /* Narrow */ /* filter width coding for newer ICOM rigs with 3 filter width */ #define PD_WIDE_3 0x01 /* Wide */ #define PD_MEDIUM_3 0x02 /* Medium */ #define PD_NARROW_3 0x03 /* Narrow */ /* * Set VFO (C_SET_VFO) sub commands */ #define S_VFOA 0x00 /* Set to VFO A */ #define S_VFOB 0x01 /* Set to VFO B */ #define S_BTOA 0xa0 /* VFO A=B */ #define S_XCHNG 0xb0 /* Switch VFO A and B */ #define S_SUBTOMAIN 0xb1 /* MAIN = SUB */ #define S_DUAL_OFF 0xc0 /* Dual watch off */ #define S_DUAL_ON 0xc1 /* Dual watch on */ #define S_DUAL 0xc2 /* Dual watch (0 = off, 1 = on) */ #define S_MAIN 0xd0 /* Select MAIN band */ #define S_SUB 0xd1 /* Select SUB band */ #define S_BAND_SEL 0xd2 /* Read/Set Main/Sub band selection */ #define S_FRONTWIN 0xe0 /* Select front window */ /* * Set MEM (C_SET_MEM) sub commands */ #define S_BANK 0xa0 /* Select memory bank (aka 'memory group' with IC-R8600) */ /* * Scan control (C_CTL_SCAN) subcommands */ #define S_SCAN_STOP 0x00 /* Stop scan/window scan */ #define S_SCAN_START 0x01 /* Programmed/Memory scan */ #define S_SCAN_PROG 0x02 /* Programmed scan */ #define S_SCAN_DELTA 0x03 /* Delta-f scan */ #define S_SCAN_WRITE 0x04 /* auto memory-write scan */ #define S_SCAN_FPROG 0x12 /* Fine programmed scan */ #define S_SCAN_FDELTA 0x13 /* Fine delta-f scan */ #define S_SCAN_MEM2 0x22 /* Memory scan */ #define S_SCAN_SLCTN 0x23 /* Selected number memory scan */ #define S_SCAN_SLCTM 0x24 /* Selected mode memory scan */ #define S_SCAN_PRIO 0x42 /* Priority / window scan */ #define S_SCAN_FDFOF 0xA0 /* Fix dF OFF */ #define S_SCAN_FDF5I 0xA1 /* Fix range +/-5kHz */ #define S_SCAN_FDF1X 0xA2 /* Fix range +/-10kHz */ #define S_SCAN_FDF2X 0xA3 /* Fix range +/-20kHz */ #define S_SCAN_FDF5X 0xA4 /* Fix range +/-50kHz */ #define S_SCAN_FDF1C 0xA5 /* Fix range +/-100kHz */ #define S_SCAN_FDF5C 0xA6 /* Fix range +/-500kHz */ #define S_SCAN_FDF1M 0xA7 /* Fix range +/-1MHz */ #define S_SCAN_FDFON 0xAA /* Fix dF ON */ #define S_SCAN_NSLCT 0xB0 /* Set as non select channel */ #define S_SCAN_SLCT 0xB1 /* Set as select channel */ #define S_SCAN_SL_NUM 0xB2 /* select programmed mem scan 7800 only */ #define S_SCAN_RSMOFF 0xD0 /* Set scan resume OFF */ #define S_SCAN_RSMONP 0xD1 /* Set scan resume ON + pause time */ #define S_SCAN_RSMON 0xD3 /* Set scan resume ON */ /* * Split control (S_CTL_SPLT) subcommands */ #define S_SPLT_OFF 0x00 /* Split OFF */ #define S_SPLT_ON 0x01 /* Split ON */ #define S_DUP_OFF 0x10 /* Simplex mode */ #define S_DUP_M 0x11 /* Duplex - mode */ #define S_DUP_P 0x12 /* Duplex + mode */ #define S_DUP_DD_RPS 0x13 /* DD Repeater Simplex mode (RPS) */ /* * Set Attenuator (C_CTL_ATT) subcommands */ #define S_ATT_RD -1 /* Without subcommand, reads out setting */ #define S_ATT_OFF 0x00 /* Off */ #define S_ATT_6dB 0x06 /* 6 dB, IC-756Pro */ #define S_ATT_10dB 0x10 /* 10 dB */ #define S_ATT_12dB 0x12 /* 12 dB, IC-756Pro */ #define S_ATT_18dB 0x18 /* 18 dB, IC-756Pro */ #define S_ATT_20dB 0x20 /* 20 dB */ #define S_ATT_30dB 0x30 /* 30 dB, or Att on for IC-R75 */ /* * Set Preamp (S_FUNC_PAMP) data */ #define D_PAMP_OFF 0x00 #define D_PAMP1 0x01 #define D_PAMP2 0x02 /* * Set AGC (S_FUNC_AGC) data */ #define D_AGC_FAST 0x00 #define D_AGC_MID 0x01 #define D_AGC_SLOW 0x02 #define D_AGC_SUPERFAST 0x03 /* IC746 pro */ /* * Set antenna (C_SET_ANT) subcommands */ #define S_ANT_RD -1 /* Without subcommand, reads out setting */ #define S_ANT1 0x00 /* Antenna 1 */ #define S_ANT2 0x01 /* Antenna 2 */ /* * Announce control (C_CTL_ANN) subcommands */ #define S_ANN_ALL 0x00 /* Announce all */ #define S_ANN_FREQ 0x01 /* Announce freq */ #define S_ANN_MODE 0x02 /* Announce operating mode */ /* * Function settings (C_CTL_LVL) subcommands */ #define S_LVL_AF 0x01 /* AF level setting */ #define S_LVL_RF 0x02 /* RF level setting */ #define S_LVL_SQL 0x03 /* SQL level setting */ #define S_LVL_IF 0x04 /* IF shift setting */ #define S_LVL_APF 0x05 /* APF level setting */ #define S_LVL_NR 0x06 /* NR level setting */ #define S_LVL_PBTIN 0x07 /* Twin PBT setting (inside) */ #define S_LVL_PBTOUT 0x08 /* Twin PBT setting (outside) */ #define S_LVL_CWPITCH 0x09 /* CW pitch setting */ #define S_LVL_RFPOWER 0x0a /* RF power setting */ #define S_LVL_MICGAIN 0x0b /* MIC gain setting */ #define S_LVL_KEYSPD 0x0c /* Key Speed setting */ #define S_LVL_NOTCHF 0x0d /* Notch freq. setting */ #define S_LVL_COMP 0x0e /* Compressor level setting */ #define S_LVL_BKINDL 0x0f /* BKin delay setting */ #define S_LVL_BALANCE 0x10 /* Balance setting (Dual watch) */ #define S_LVL_AGC 0x11 /* AGC (7800) */ #define S_LVL_NB 0x12 /* NB setting */ #define S_LVL_DIGI 0x13 /* DIGI-SEL (7800) */ #define S_LVL_DRIVE 0x14 /* DRIVE gain setting */ #define S_LVL_MON 0x15 /* Monitor gain setting */ #define S_LVL_VOXGAIN 0x16 /* VOX gain setting */ #define S_LVL_ANTIVOX 0x17 /* Anti VOX gain setting */ #define S_LVL_CONTRAST 0x18 /* CONTRAST level setting */ #define S_LVL_BRIGHT 0x19 /* BRIGHT level setting */ #define S_LVL_BASS 0x1B /* Bass level setting */ #define S_LVL_TREBLE 0x1C /* Treble level setting */ #define S_LVL_SCNSPD 0x1D /* Scan speed */ #define S_LVL_SCNDEL 0x1E /* Scan delay */ #define S_LVL_PRIINT 0x1F /* PRIO interval */ #define S_LVL_RESTIM 0x20 /* Resume time */ /* * Read squelch condition/S-meter level/other meter levels (C_RD_SQSM) subcommands */ #define S_SQL 0x01 /* Read squelch condition */ #define S_SML 0x02 /* Read S-meter level */ #define S_SMF 0x03 /* Read S-meter level in AAAABBCC format */ #define S_CML 0x04 /* Read centre -meter level */ #define S_CSQL 0x05 /* Read combined squelch conditions */ #define S_SAMS 0x06 /* Read S-AM Sync indicator */ #define S_OVF 0x07 /* Read OVF indicator status */ #define S_RFML 0x11 /* Read RF-meter level */ #define S_SWR 0x12 /* Read SWR-meter level */ #define S_ALC 0x13 /* Read ALC-meter level */ #define S_CMP 0x14 /* Read COMP-meter level */ #define S_VD 0x15 /* Read Vd-meter level */ #define S_ID 0x16 /* Read Id-meter level */ /* * Function settings (C_CTL_FUNC) subcommands Set and Read */ #define S_FUNC_PAMP 0x02 /* Preamp setting */ #define S_FUNC_AGCOFF 0x10 /* IC-R8500 only */ #define S_FUNC_AGCON 0x11 /* IC-R8500 only */ #define S_FUNC_AGC 0x12 /* AGC setting presets: the dsp models allow these to be modified */ #define S_FUNC_NBOFF 0x20 /* IC-R8500 only */ #define S_FUNC_NBON 0x21 /* IC-R8500 only */ #define S_FUNC_NB 0x22 /* NB setting */ #define S_FUNC_APFOFF 0x30 /* IC-R8500 only */ #define S_FUNC_APFON 0x31 /* IC-R8500 only */ #define S_FUNC_APF 0x32 /* APF setting */ #define S_FUNC_NR 0x40 /* NR setting */ #define S_FUNC_ANF 0x41 /* ANF setting */ #define S_FUNC_TONE 0x42 /* TONE setting */ #define S_FUNC_TSQL 0x43 /* TSQL setting */ #define S_FUNC_COMP 0x44 /* COMP setting */ #define S_FUNC_MON 0x45 /* Monitor setting */ #define S_FUNC_VOX 0x46 /* VOX setting */ #define S_FUNC_BKIN 0x47 /* BK-IN setting */ #define S_FUNC_MN 0x48 /* Manual notch setting */ #define S_FUNC_RF 0x49 /* RTTY Filter setting */ #define S_FUNC_AFC 0x4A /* Auto Frequency Control (AFC) setting */ #define S_FUNC_CSQL 0x4B /* DTCS tone code squelch setting*/ #define S_FUNC_VSC 0x4C /* voice squelch control useful for scanning*/ #define S_FUNC_MANAGC 0x4D /* manual AGC */ #define S_FUNC_DIGISEL 0x4E /* DIGI-SEL */ #define S_FUNC_TW_PK 0x4F /* RTTY Twin Peak filter 0= off 1 = on */ #define S_FUNC_DIAL_LK 0x50 /* Dial lock */ #define S_FUNC_P25SQL 0x52 /* P25 DSQL */ #define S_FUNC_ANTRX 0x53 /* ANT-RX */ #define S_FUNC_IF1F 0x55 /* 1st IF filter */ #define S_FUNC_DSPF 0x56 /* DSP filter */ #define S_FUNC_MANN 0x57 /* Manual notch width */ #define S_FUNC_SSBT 0x58 /* SSB Tx bandwidth */ #define S_FUNC_SUBB 0x59 /* Sub band */ #define S_FUNC_SATM 0x5A /* Satellite mode */ #define S_FUNC_DSSQL 0x5B /* D-STAR DSQL */ #define S_FUNC_DPSQL 0x5F /* dPMR DSQL */ #define S_FUNC_NXSQL 0x60 /* NXDN DSQL */ #define S_FUNC_DCSQL 0x61 /* DCR DSQL */ #define S_FUNC_DPSCM 0x62 /* dPMR scrambler */ #define S_FUNC_NXENC 0x63 /* NXDN encryption */ #define S_FUNC_DCENC 0x64 /* DCR encryption */ #define S_FUNC_IPP 0x65 /* IP+ setting */ #define S_FUNC_TX_INHIBIT 0x66 /* TX inhibit setting */ #define S_FUNC_DPP 0x67 /* DPP setting */ /* * Set Power On/Off (C_SET_PWR) subcommands */ #define S_PWR_OFF 0x00 #define S_PWR_ON 0x01 #define S_PWR_STDBY 0x02 /* * Transmit control (C_CTL_PTT) subcommands */ #define S_PTT 0x00 #define S_ANT_TUN 0x01 /* Auto tuner 0=OFF, 1 = ON, 2=Start Tuning */ #define S_RD_TX_FREQ 0x03 /* Read transmit frequency */ /* * Band Edge control (C_CTL_EDGE) subcommands */ #define S_EDGE_RD_N 0x00 // Fixed band edge count #define S_EDGE_RD 0x01 // Fixed band edges #define S_EDGE_RD_NU 0x02 // User band edge count #define S_EDGE_RD_U 0x03 // User band edges /* * RIT/XIT control (C_CTL_RIT) subcommands */ #define S_RIT_FREQ 0x00 #define S_RIT 0x01 /* RIT 0 = OFF, 1 = ON */ #define S_XIT 0x02 /* XIT (delta TX) 0 = OFF, 1 = ON */ /* * Misc contents (C_CTL_MEM) subcommands applies to newer rigs. * * Beware the IC-7200 which is non-standard. */ #define S_MEM_CNTNT 0x00 /* Memory content 2 bigendian */ #define S_MEM_BAND_REG 0x01 /* band stacking register */ #define S_MEM_FILT_WDTH 0x03 /* current passband filter width */ #define S_MEM_PARM 0x05 /* rig parameters; extended parm # + param value: should be coded */ /* in the rig files because they are different for each rig */ #define S_MEM_DATA_MODE 0x06 /* data mode */ #define S_MEM_TX_PB 0x07 /* SSB tx passband */ #define S_MEM_FLTR_SHAPE 0x08 /* DSP filter shape 0=sharp 1=soft */ /* Icr75c */ #define S_MEM_CNTNT_SLCT 0x01 #define S_MEM_FLT_SLCT 0x01 #define S_MEM_MODE_SLCT 0x02 /* For IC-910H rig. */ #define S_MEM_RDWR_MEM 0x00 /* Read/write memory channel */ #define S_MEM_SATMEM 0x01 /* Satellite memory */ #define S_MEM_VOXGAIN 0x02 /* VOX gain level (0=0%, 255=100%) */ #define S_MEM_VOXDELAY 0x03 /* VOX delay (0=0.0 sec, 20=2.0 sec) */ #define S_MEM1_VOXDELAY 0x05 /* VOX delay (0=0.0 sec, 20=2.0 sec) */ #define S_MEM_ANTIVOX 0x04 /* anti VOX setting */ #define S_MEM_RIT 0x06 /* RIT (0=off, 1=on, 2=sub dial) */ #define S_MEM_SATMODE910 0x07 /* Satellite mode (on/off) */ #define S_MEM_BANDSCOPE 0x08 /* Simple bandscope (on/off) */ /* For IC9700 and IC9100 and likely future Icoms */ #define S_MEM_DUALMODE 0x59 /* Dualwatch mode (on/off) */ #define S_MEM_SATMODE 0x5a /* Satellite mode (on/off) */ /* IC-R8600 and others */ #define S_MEM_SKIP_SLCT_OFF 0x00 #define S_MEM_SKIP_SLCT_ON 0x10 #define S_MEM_PSKIP_SLCT_ON 0x20 #define S_MEM_DUP_OFF 0x00 #define S_MEM_DUP_MINUS 0x01 #define S_MEM_DUP_PLUS 0x02 #define S_MEM_TSTEP_OFF 0x00 #define S_MEM_TSTEP_ON 0x01 #define S_FUNC_IPPLUS 0x07 /* IP+ subcommand 0x1a 0x07 */ /* IC-R6 */ #define S_MEM_AFLT 0x00 /* AF LPF Off/On */ /* IC-R30 */ #define S_MEM_ANL 0x00 /* ANL Off/On */ #define S_MEM_EAR 0x01 /* Earphone mode Off/On */ #define S_MEM_REC 0x09 /* Recorder Off/On */ /* IC-F8101 */ #define S_MEM_PTT 0x37 /* PTT 0,1,2 for front/rear PTT */ /* * Tone control (C_SET_TONE) subcommands */ #define S_TONE_RPTR 0x00 /* Tone frequency setting for repeater receive */ #define S_TONE_SQL 0x01 /* Tone frequency setting for squelch */ #define S_TONE_DTCS 0x02 /* DTCS code and polarity for squelch */ #define S_TONE_P25NAC 0x03 /* P25 NAC */ #define S_TONE_DSCSQL 0x07 /* D-STAR CSQL */ #define S_TONE_DPCOM 0x08 /* dPMR COM ID */ #define S_TONE_DPCC 0x09 /* dPMR CC */ #define S_TONE_NXRAN 0x0A /* NXDN RAN */ #define S_TONE_DCUC 0x0B /* DCR UC */ #define S_TONE_DPSCK 0x0C /* dPMR scrambler key */ #define S_TONE_NXENK 0x0D /* NXDN encryption key */ #define S_TONE_DCENK 0x0E /* DCR encryption key */ /* * Transceiver ID (C_RD_TRXID) subcommands */ #define S_RD_TRXID 0x00 /* * Digital modes settings & status subcommands */ #define S_DIG_DSCALS 0x00 /* D-STAR Call sign */ #define S_DIG_DSMESS 0x01 /* D-STAR Message */ #define S_DIG_DSRSTS 0x02 /* D-STAR Rx status */ #define S_DIG_DSGPSD 0x03 /* D-STAR GPS data */ #define S_DIG_DSGPSM 0x04 /* D-STAR GPS message */ #define S_DIG_DSCSQL 0x05 /* D-STAR CSQL */ #define S_DIG_P25ID 0x06 /* P25 ID */ #define S_DIG_P25STS 0x07 /* P25 Rx status */ #define S_DIG_DPRXID 0x08 /* dPMR Rx ID */ #define S_DIG_DPRSTS 0x09 /* dPMR Rx status */ #define S_DIG_NXRXID 0x0A /* NXDN Rx ID */ #define S_DIG_NXRSTS 0x0B /* NXDN Rx status */ #define S_DIG_DCRXID 0x0C /* DCR Rx ID */ #define S_DVT_DSMYCS 0x00 /* D-STAR My CS */ #define S_DVT_DSTXCS 0x01 /* D-STAR Tx CS */ #define S_DVT_DSTXMS 0x02 /* D-STAR Tx Mess */ #define S_DSD_DSTXDT 0x00 /* D-STAR Tx Data */ /* * S_CTL_SCP Scope control & data subcommands */ #define S_SCP_DAT 0x00 /* Read data */ #define S_SCP_STS 0x10 /* On/Off status */ #define S_SCP_DOP 0x11 /* Data O/P Control */ #define S_SCP_MSS 0x12 /* Main/Sub setting */ #define S_SCP_SDS 0x13 /* Single/Dual scope setting */ #define S_SCP_MOD 0x14 /* Center/Fixed mode */ #define S_SCP_SPN 0x15 /* Span setting */ #define S_SCP_EDG 0x16 /* Edge setting */ #define S_SCP_HLD 0x17 /* Hold On/Off */ #define S_SCP_ATT 0x18 /* Attenuator */ #define S_SCP_REF 0x19 /* Reference level */ #define S_SCP_SWP 0x1a /* Sweep speed */ #define S_SCP_STX 0x1b /* Scope during Tx */ #define S_SCP_CFQ 0x1c /* Center frequency type */ #define S_SCP_VBW 0x1d /* Video Band Width (VBW) setting */ #define S_SCP_FEF 0x1e /* Fixed edge freqs */ #define S_SCP_RBW 0x1f /* Resolution Band Width (RBW) setting */ #define S_SCP_MKP 0x20 /* Marker position setting */ /* * C_CTL_MISC OptoScan extension */ #define S_OPTO_LOCAL 0x01 #define S_OPTO_REMOTE 0x02 #define S_OPTO_TAPE_ON 0x03 #define S_OPTO_TAPE_OFF 0x04 #define S_OPTO_RDSTAT 0x05 #define S_OPTO_RDCTCSS 0x06 #define S_OPTO_RDDCS 0x07 #define S_OPTO_RDDTMF 0x08 #define S_OPTO_RDID 0x09 #define S_OPTO_SPKRON 0x0a #define S_OPTO_SPKROFF 0x0b #define S_OPTO_5KSCON 0x0c #define S_OPTO_5KSCOFF 0x0d #define S_OPTO_NXT 0x0e #define S_OPTO_SCON 0x0f #define S_OPTO_SCOFF 0x10 /* * OmniVIPlus (Omni VI) extensions */ #define C_OMNI6_XMT 0x16 /* * S_MEM_MODE_SLCT Misc CI-V Mode settings */ #define S_PRM_BEEP 0x02 #define S_PRM_CWPITCH 0x10 #define S_PRM_LANG 0x15 #define S_PRM_BACKLT 0x21 #define S_PRM_SLEEP 0x32 #define S_PRM_SLPTM 0x33 #define S_PRM_TIME 0x27 /* * Tokens for Extra Level and Parameters common to multiple rigs. Use token # > 99. Defined here so they * will be available in ICOM name space. They have different internal commands primarily in dsp rigs. These * tokens are used ext_lvl and ext_parm functions in the individual rig files. * Extra parameters which are rig specific should be coded in the individual rig files and token #s < 100. */ #define TOKEN_BACKEND(t) (t) #define TOK_RTTY_FLTR TOKEN_BACKEND(100) #define TOK_SSBBASS TOKEN_BACKEND(101) #define TOK_SQLCTRL TOKEN_BACKEND(102) #define TOK_DRIVE_GAIN TOKEN_BACKEND(103) #define TOK_DIGI_SEL_FUNC TOKEN_BACKEND(104) #define TOK_DIGI_SEL_LEVEL TOKEN_BACKEND(105) #define TOK_DSTAR_CALL_SIGN TOKEN_BACKEND(120) #define TOK_DSTAR_MESSAGE TOKEN_BACKEND(121) #define TOK_DSTAR_STATUS TOKEN_BACKEND(122) #define TOK_DSTAR_GPS_DATA TOKEN_BACKEND(123) #define TOK_DSTAR_GPS_MESS TOKEN_BACKEND(124) #define TOK_DSTAR_DSQL TOKEN_BACKEND(125) #define TOK_DSTAR_MY_CS TOKEN_BACKEND(126) #define TOK_DSTAR_TX_CS TOKEN_BACKEND(127) #define TOK_DSTAR_TX_MESS TOKEN_BACKEND(128) #define TOK_DSTAR_TX_DATA TOKEN_BACKEND(129) #define TOK_DSTAR_CODE TOKEN_BACKEND(130) #define TOK_SCOPE_MSS TOKEN_BACKEND(140) #define TOK_SCOPE_SDS TOKEN_BACKEND(141) #define TOK_SCOPE_EDG TOKEN_BACKEND(142) #define TOK_SCOPE_STX TOKEN_BACKEND(143) #define TOK_SCOPE_CFQ TOKEN_BACKEND(144) #define TOK_SCOPE_VBW TOKEN_BACKEND(145) #define TOK_SCOPE_FEF TOKEN_BACKEND(146) #define TOK_SCOPE_RBW TOKEN_BACKEND(147) #define TOK_SCOPE_MKP TOKEN_BACKEND(148) #define TOK_IPP_FUNC TOKEN_BACKEND(149) #define TOK_TX_INHIBIT_FUNC TOKEN_BACKEND(150) #define TOK_DPP_FUNC TOKEN_BACKEND(151) #define TOK_ICPW2_FUNC TOKEN_BACKEND(152) /* * icom_ext_parm table subcommand modifiers */ #define SC_MOD_RD 0x01 /* Readable */ #define SC_MOD_WR 0x02 /* Writeable */ #define SC_MOD_RW 0x03 /* Read-write */ #define SC_MOD_RW12 0x07 /* Write +0x01, Read +0x02 */ /* * icom_ext_parm table data types */ #define CMD_DAT_WRD 0x00 /* literal single word type */ #define CMD_DAT_INT 0x01 /* bcd int type */ #define CMD_DAT_FLT 0x02 /* bcd float type */ #define CMD_DAT_LVL 0x03 /* bcd level type */ #define CMD_DAT_BOL 0x04 /* bcd boolean type */ #define CMD_DAT_STR 0x05 /* string type */ #define CMD_DAT_BUF 0x06 /* literal byte buffer type */ #define CMD_DAT_TIM 0x07 /* Time type HHMM<>seconds */ /* * Icom spectrum scope definitions */ #define SCOPE_MODE_CENTER 0x00 #define SCOPE_MODE_FIXED 0x01 #define SCOPE_MODE_SCROLL_C 0x02 #define SCOPE_MODE_SCROLL_F 0x03 #define SCOPE_SPEED_FAST 0x00 #define SCOPE_SPEED_MID 0x01 #define SCOPE_SPEED_SLOW 0x02 #define SCOPE_IN_RANGE 0x00 #define SCOPE_OUT_OF_RANGE 0x01 #endif /* _ICOM_DEFS_H */ hamlib-4.6.2/rigs/icom/icr9000.c0000644000175000017500000001317414752216205013037 00000000000000/* * Hamlib CI-V backend - IC-R9000 descriptions * Copyright (c) 2000-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #define ICR9000_MODES (RIG_MODE_AM|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_CW|RIG_MODE_WFM) #define ICR9000_OPS (RIG_OP_FROM_VFO|RIG_OP_MCL) #define ICR9000_FUNCS (RIG_FUNC_VSC) #define ICR9000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define ICR9000_PARMS (RIG_PARM_ANN) #define ICR9000_SCAN_OPS (RIG_SCAN_MEM) /* TBC */ #define ICR9000_ANTS (RIG_ANT_1|RIG_ANT_2) /* selectable by CI-V ? */ #define ICR9000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT, \ } /* TODO: S-Meter measurements */ #define ICR9000_STR_CAL UNKNOWN_IC_STR_CAL static struct icom_priv_caps icr9000_priv_caps = { 0x2a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r9000_ts_sc_list, .antack_len = 2, .ant_count = 2 }; /* * ICR9000A rig capabilities. */ struct rig_caps icr9000_caps = { RIG_MODEL(RIG_MODEL_ICR9000), .model_name = "IC-R9000", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR9000_FUNCS, .has_set_func = ICR9000_FUNCS, .has_get_level = ICR9000_LEVELS, .has_set_level = RIG_LEVEL_SET(ICR9000_LEVELS), .has_get_parm = ICR9000_PARMS, .has_set_parm = RIG_PARM_SET(ICR9000_PARMS), .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 10, 20, 30, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR9000_OPS, .scan_ops = ICR9000_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 999, RIG_MTYPE_MEM, ICR9000_MEM_CAP }, /* TBC */ { 1000, 1009, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* 2 by 2 */ { 1010, 1019, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* 2 by 2 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(1999.8), ICR9000_MODES, -1, -1, RIG_VFO_A, ICR9000_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(1999.8), ICR9000_MODES, -1, -1, RIG_VFO_A, ICR9000_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR9000_MODES, 10}, /* resolution */ {ICR9000_MODES, 100}, {ICR9000_MODES, kHz(1)}, {ICR9000_MODES, kHz(5)}, {ICR9000_MODES, kHz(9)}, {ICR9000_MODES, kHz(10)}, {ICR9000_MODES, 12500}, {ICR9000_MODES, kHz(20)}, {ICR9000_MODES, kHz(25)}, {ICR9000_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR9000_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr9000_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, #ifdef XXREMOVEDXX .set_parm = icom_set_parm, .get_parm = icom_get_parm, #endif .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr75.c0000644000175000017500000004334714752216205012707 00000000000000/* * Hamlib CI-V backend - description of IC-R75 * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "misc.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" /* * IC-R75 * * TODO: * $1A command: * - set_parm, set_trn, IF filter setting, etc. */ #define ICR75_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_AMS) #define ICR75_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_NR) #define ICR75_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define ICR75_PARM_ALL (RIG_PARM_ANN|RIG_PARM_APO|RIG_PARM_BACKLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME) #define ICR75_VFO_ALL (RIG_VFO_VFO|RIG_VFO_MEM) #define ICR75_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR75_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO) #define ICR75_ANTS (RIG_ANT_1|RIG_ANT_2) #define ICR75_STR_CAL { 17, { \ { 0, -60 }, \ { 37, -54 }, \ { 52, -48 }, \ { 61, -42 }, \ { 72, -36 }, \ { 86, -30 }, \ { 95, -24 }, \ { 109, -18 }, \ { 124, -12 }, \ { 128, -6 }, \ { 146, 0 }, \ { 166, 10 }, \ { 186, 20 }, \ { 199, 30 }, \ { 225, 40 }, \ { 233, 50 }, \ { 255, 60 }, \ } } /* * channel caps. */ #define ICR75_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ .flags = 1, \ } static int icr75_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int icr75_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int icr75_set_parm(RIG *rig, setting_t parm, value_t val); static int icr75_get_parm(RIG *rig, setting_t parm, value_t *val); static struct icom_priv_caps icr75_priv_caps = { 0x5a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r75_ts_sc_list, .antack_len = 2, .ant_count = 2 }; struct rig_caps icr75_caps = { RIG_MODEL(RIG_MODEL_ICR75), .model_name = "IC-R75", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .has_get_func = ICR75_FUNC_ALL, .has_set_func = ICR75_FUNC_ALL, .has_get_level = ICR75_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR75_LEVEL_ALL), .has_get_parm = ICR75_PARM_ALL, .has_set_parm = RIG_PARM_SET(ICR75_PARM_ALL), .level_gran = { #define NO_LVL_PBT_IN #define NO_LVL_PBT_OUT #define NO_LVL_CWPITCH #include "level_gran_icom.h" [LVL_PBT_IN] = { .min = { .f = -1280 }, .max = { .f = +1280 }, .step = { .f = 15 } }, [LVL_PBT_OUT] = { .min = { .f = -1280 }, .max = { .f = +1280 }, .step = { .f = 15 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 10 } }, #undef NO_LVL_PBT_IN #undef NO_LVL_PBT_OUT #undef NO_LVL_CWPITCH }, .parm_gran = { [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, [PARM_TIME] = { .min = { .i = 0 }, .max = { .i = 86399} }, [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC */ .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR75_VFO_OPS, .scan_ops = ICR75_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 1, 99, RIG_MTYPE_MEM, ICR75_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, ICR75_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), ICR75_MODES, -1, -1, ICR75_VFO_ALL, ICR75_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), ICR75_MODES, -1, -1, ICR75_VFO_ALL, ICR75_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR75_MODES, Hz(10)}, {ICR75_MODES, Hz(100)}, {ICR75_MODES, kHz(1)}, {ICR75_MODES, kHz(5)}, {ICR75_MODES, kHz(6.25)}, {ICR75_MODES, kHz(9)}, {ICR75_MODES, kHz(10)}, {ICR75_MODES, kHz(12.5)}, {ICR75_MODES, kHz(20)}, {ICR75_MODES, kHz(25)}, {ICR75_MODES, kHz(100)}, {ICR75_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1.9)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(15)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = ICR75_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr75_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icr75_set_parm, .get_parm = icr75_get_parm, .get_dcd = icom_get_dcd, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .set_channel = icr75_set_channel, .get_channel = icr75_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * icr75_set_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL * TODO: still a WIP --SF */ int icr75_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char chanbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int chan_len, freq_len, ack_len, retval; unsigned char icmode; signed char icmode_ext; int err; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; to_bcd_be(chanbuf, chan->channel_num, 4); chanbuf[2] = S_MEM_CNTNT_SLCT; freq_len = priv->civ_731_mode ? 4 : 5; /* * to_bcd requires nibble len */ to_bcd(chanbuf + 3, chan->freq, freq_len * 2); chan_len = 2 + freq_len + 1; err = rig2icom_mode(rig, vfo, chan->mode, chan->width, &icmode, &icmode_ext); if (err != RIG_OK) { return err; } chanbuf[chan_len++] = icmode; chanbuf[chan_len++] = icmode_ext; to_bcd_be(chanbuf + chan_len++, chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i, 2); to_bcd_be(chanbuf + chan_len++, chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i, 2); to_bcd_be(chanbuf + chan_len++, chan->ant, 2); memset(chanbuf + chan_len, 0, 8); SNPRINTF((char *)(chanbuf + chan_len), 9, "%.8s", chan->channel_desc); chan_len += 8; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * icr75_get_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL * TODO: still a WIP --SF */ int icr75_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char chanbuf[24]; int chan_len, freq_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; to_bcd_be(chanbuf, chan->channel_num, 4); chan_len = 2; freq_len = priv->civ_731_mode ? 4 : 5; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_RF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_SQL)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_NR)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_IN)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_OUT)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_CWPITCH)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, " "); /* * freqbuf should contain Cn,Data area */ if ((chan_len != freq_len + 18) && (chan_len != 5)) { rig_debug(RIG_DEBUG_ERR, "icr75_get_channel: wrong frame len=%d\n", chan_len); return -RIG_ERJCTED; } /* do this only if not a blank channel */ if (chan_len != 5) { /* * from_bcd requires nibble len */ chan->flags = RIG_CHFLAG_NONE; chan->freq = from_bcd(chanbuf + 5, freq_len * 2); chan_len = 4 + freq_len + 1; icom2rig_mode(rig, chanbuf[chan_len], chanbuf[chan_len + 1], &chan->mode, &chan->width); chan_len += 2; if (from_bcd_be(chanbuf + chan_len++, 2) != 0) { chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 20; } if (from_bcd_be(chanbuf + chan_len++, 2) != 0) { chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 20; } chan->ant = from_bcd_be(chanbuf + chan_len++, 2); strncpy(chan->channel_desc, (char *)(chanbuf + chan_len), 8); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int icr75_set_parm(RIG *rig, setting_t parm, value_t val) { unsigned char prmbuf[MAXFRAMELEN]; int min, hr, sec; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_ANN: { int ann_mode = -1; int ann_lang = -1; switch (val.i) { case RIG_ANN_OFF: ann_mode = S_ANN_ALL; break; case RIG_ANN_FREQ: ann_mode = S_ANN_FREQ; break; case RIG_ANN_RXMODE: ann_mode = S_ANN_MODE; break; case RIG_ANN_ENG: case RIG_ANN_JAP: ann_lang = (val.i == RIG_ANN_ENG) ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } if (ann_mode >= 0) { return icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0); } else if (ann_lang >= 0) { prmbuf[0] = S_PRM_LANG; prmbuf[1] = ann_lang; return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 2, prmbuf, 0, 0); } rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } case RIG_PARM_APO: prmbuf[0] = S_PRM_SLPTM; hr = (int)((float) val.i / 60.0f); min = val.i - (hr * 60); to_bcd_be(prmbuf + 1, (long long) hr, 2); to_bcd_be(prmbuf + 2, (long long) min, 2); return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 3, prmbuf, 0, 0); case RIG_PARM_BACKLIGHT: prmbuf[0] = S_PRM_BACKLT; to_bcd_be(prmbuf + 1, (long long)(val.f * 255.0f), 2 * 2); return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 3, prmbuf, 0, 0); case RIG_PARM_BEEP: prmbuf[0] = S_PRM_BEEP; prmbuf[1] = val.i ? 1 : 0; return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 2, prmbuf, 0, 0); case RIG_PARM_TIME: hr = (int)((float) val.i / 3600.0); min = (int)((float)(val.i - (hr * 3600)) / 60.0); sec = (val.i - (hr * 3600) - (min * 60)); prmbuf[0] = S_PRM_TIME; to_bcd_be(prmbuf + 1, (long long) hr, 2); to_bcd_be(prmbuf + 2, (long long) min, 2); to_bcd_be(prmbuf + 3, (long long) sec, 2); return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 4, prmbuf, 0, 0); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm %s\n", rig_strparm(parm)); return -RIG_EINVAL; } } int icr75_get_parm(RIG *rig, setting_t parm, value_t *val) { unsigned char prmbuf[MAXFRAMELEN], resbuf[MAXFRAMELEN]; int prm_len, res_len; int prm_cn, prm_sc; int icom_val = 0; int cmdhead; int retval; int min, hr, sec; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_APO: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_SLPTM; break; case RIG_PARM_BACKLIGHT: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_BACKLT; break; case RIG_PARM_BEEP: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_BEEP; break; case RIG_PARM_TIME: prm_cn = C_CTL_MEM; prm_sc = S_MEM_MODE_SLCT; prm_len = 1; prmbuf[0] = S_PRM_TIME; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_parm %s", rig_strparm(parm)); return -RIG_EINVAL; } retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, resbuf, &res_len); if (retval != RIG_OK) { return retval; } cmdhead = 3; res_len -= cmdhead; if (resbuf[0] != ACK && resbuf[0] != prm_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } switch (parm) { case RIG_PARM_APO: hr = from_bcd_be(resbuf + cmdhead, 2); min = from_bcd_be(resbuf + cmdhead + 1, 2); icom_val = (hr * 60) + min; val->i = icom_val; break; case RIG_PARM_TIME: hr = from_bcd_be(resbuf + cmdhead, 2); min = from_bcd_be(resbuf + cmdhead + 1, 2); sec = from_bcd_be(resbuf + cmdhead + 2, 2); icom_val = (hr * 3600) + (min * 60) + sec; val->i = icom_val; break; case RIG_PARM_BACKLIGHT: icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); val->f = (float) icom_val / 255.0; break; case RIG_PARM_BEEP: icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); val->i = icom_val; break; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } hamlib-4.6.2/rigs/icom/delta2.c0000644000175000017500000001210414752216205013114 00000000000000/* * Hamlib CI-V backend - description of the TenTenc DeltaII * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Delta II (aka TT 536) cloned after Omni VI. * Needs RS-232 Serial Level Converter Model 305 or equivalent. * * For changing CI-V address of the rig, see: * http://www.tentecwiki.org/doku.php?id=536addr */ /* Known problems: * * To Do: get the datasheet, and testing on real hardware!! */ #include #include "icom.h" #define DELTAII_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define DELTAII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DELTAII_ALL_RX_MODES (DELTAII_OTHER_TX_MODES|RIG_MODE_AM) #define DELTAII_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define DELTAII_STR_CAL { 0, { } } static const struct icom_priv_caps delta2_priv_caps = { 0x01, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list /* TODO: ts_sc_list */ }; struct rig_caps delta2_caps = { RIG_MODEL(RIG_MODEL_DELTAII), .model_name = "Delta II", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = DELTAII_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .str_cal = DELTAII_STR_CAL, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* TODO: 32 simplex, 16 duplex */ { 0, 47, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* These limits measured on Omni VI SN 1A10473 */ .rx_range_list2 = { {kHz(100), kHz(29999), DELTAII_ALL_RX_MODES, -1, -1, DELTAII_VFO_ALL}, RIG_FRNG_END, }, /* Note: There is no AM mode. */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(3500), MHz(4) - 1, DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(7), kHz(7300), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(10100), kHz(10150), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(14), kHz(14350), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(18068), kHz(18168), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(21), kHz(21450), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {kHz(24890), kHz(24990), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, {MHz(28), kHz(29700), DELTAII_OTHER_TX_MODES, 5000, 100000, DELTAII_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {DELTAII_ALL_RX_MODES, Hz(10)}, // This radio has 10 Hz steps. RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& delta2_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // icom.c has no get_vfo .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic970.c0000644000175000017500000001151714752216205012603 00000000000000/* * Hamlib CI-V backend - description of IC-970 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #define IC970_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC970_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC970_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC970_STR_CAL { 0, { } } /* * FIXME: this appears to be the IC-970A/E * what about the IC-970H ? please give it a fix. --SF */ static const struct icom_priv_caps ic970_priv_caps = { 0x2e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic970_caps = { RIG_MODEL(RIG_MODEL_IC970), .model_name = "IC-970", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC970_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, { 102, 102, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), IC970_MODES, -1, -1, IC970_VFO_ALL}, {MHz(430), MHz(440), IC970_MODES, -1, -1, IC970_VFO_ALL}, /* 1200MHz band module is optional */ // {MHz(1240),MHz(1300),IC970_MODES,-1,-1,IC970_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, {MHz(430), MHz(440), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, // {MHz(1240),MHz(1300),IC970_MODES,W(1),W(10),IC970_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(150), IC970_MODES, -1, -1, IC970_VFO_ALL}, {MHz(430), MHz(450), IC970_MODES, -1, -1, IC970_VFO_ALL}, /* 1200MHz band module is optional */ // {MHz(1240),MHz(1300),IC970_MODES,-1,-1,IC970_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(150), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, {MHz(430), MHz(450), IC970_MODES, W(3.5), W(25), IC970_VFO_ALL}, // {MHz(1240),MHz(1300),IC970_MODES,W(1),W(10),IC970_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC970_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, // {RIG_MODE_FM, Hz(500)}, /* optional CW NARROW FILTER */ {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic970_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/os535.c0000644000175000017500000001231314752216205012621 00000000000000/* * Hamlib CI-V backend - description of the OptoScan535 * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * This backend is currently being maintained by Michael Smith, KE4RJQ. * Email: james (dot) m (dot) smith (at) earthlink (dot) net */ #include #include #include "idx_builtin.h" #include "icom.h" #include "tones.h" #include "optoscan.h" extern struct confparams opto_ext_parms[]; #define OS535_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define OS535_VFO_ALL (RIG_VFO_A) #define OS535_LEVELS (RIG_LEVEL_RAWSTR|RIG_LEVEL_AF) #define OS535_SCAN_OPS (RIG_SCAN_PLT) #define OS535_STR_CAL { 2, { \ { 20, 60 }, \ { 137, -60 }, \ } } /* TBC */ /* * The OptoScan is not actually a rig. This is an add-in circuit board * for the Realistic PRO-2035 and PRO-2045 Scanning VHF-UHF Receivers. * http://www.optoelectronics.com/tech/pdf/os535/os535_ci5_spec_v10.pdf * * TODO: srch_dcs, srch_ctcss, rcv_dtmf, and make icom_probe opto aware */ static struct icom_priv_caps os535_priv_caps = { 0x80, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ NULL, .settle_time = 12, }; struct rig_caps os535_caps = { RIG_MODEL(RIG_MODEL_OS535), .model_name = "OptoScan535", .mfg_name = "Optoelectronics", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_SERIAL_CAR, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = OS535_LEVELS, .has_set_level = RIG_LEVEL_AF, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = full_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = RIG_OP_NONE, .scan_ops = OS535_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { { MHz(25), MHz(520), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(760), MHz(1300), OS535_MODES, -1, -1, OS535_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* this is a scanner */ .rx_range_list2 = { { MHz(25), MHz(520), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(760), MHz(823.995), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(849), MHz(868.995), OS535_MODES, -1, -1, OS535_VFO_ALL}, { MHz(894), MHz(1300), OS535_MODES, -1, -1, OS535_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* this is a scanner */ .tuning_steps = { {OS535_MODES, kHz(5)}, {OS535_MODES, kHz(12.5)}, {OS535_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .str_cal = OS535_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& os535_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = optoscan_open, .rig_close = optoscan_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .get_info = optoscan_get_info, .get_ctcss_tone = optoscan_get_ctcss_tone, .get_dcs_code = optoscan_get_dcs_code, .recv_dtmf = optoscan_recv_dtmf, .extparms = opto_ext_parms, .set_ext_parm = optoscan_set_ext_parm, .get_ext_parm = optoscan_get_ext_parm, .set_level = optoscan_set_level, .get_level = optoscan_get_level, .scan = optoscan_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic728.c0000644000175000017500000002020714752216205012600 00000000000000/* * Hamlib CI-V backend - description of IC-728 * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC728_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * IC-728 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic728/specs.htm * */ #define IC728_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC728_AM_TX_MODES (RIG_MODE_AM) #define IC728_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC728_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC728_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC728_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic728_priv_caps = { 0x38, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic728_caps = { RIG_MODEL(RIG_MODEL_IC728), .model_name = "IC-728", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC728_VFO_OPS, .scan_ops = IC728_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(1, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(2, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC728_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic728_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static const struct icom_priv_caps ic729_priv_caps = { 0x3a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic729_caps = { RIG_MODEL(RIG_MODEL_IC729), .model_name = "IC-729", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC728_VFO_OPS, .scan_ops = IC728_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(1, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC728_ALL_RX_MODES, -1, -1, IC728_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC728_OTHER_TX_MODES, W(10), W(100), IC728_VFO_ALL, IC728_ANTS), FRQ_RNG_HF(2, IC728_AM_TX_MODES, W(10), W(40), IC728_VFO_ALL, IC728_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC728_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic729_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic78.c0000644000175000017500000001260014752216205012514 00000000000000/* * Hamlib CI-V backend - description of IC-78 * Copyright (c) 2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "icom.h" #include "bandplan.h" #include "idx_builtin.h" #define IC78_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC78_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC78_AM_TX_MODES (RIG_MODE_AM) #define IC78_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP) #define IC78_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR|RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_SQL) #define IC78_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define IC78_VFO_OPS (RIG_OP_NONE) #define IC78_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) #define IC78_ANTS (RIG_ANT_1) /* * IC78_STR_CAL is what the S-meter displays * * FIXME: real measures! */ #define IC78_STR_CAL { 2, \ { \ { 0, -60 }, \ { 255, 60 } \ } } /* * ic78 rigs capabilities. */ static const struct icom_priv_caps ic78_priv_caps = { 0x62, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list }; struct rig_caps ic78_caps = { RIG_MODEL(RIG_MODEL_IC78), .model_name = "IC-78", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC78_FUNC_ALL, .has_set_func = IC78_FUNC_ALL, .has_get_level = IC78_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC78_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC78_VFO_OPS, .scan_ops = IC78_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 100, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30) - 1, IC78_ALL_RX_MODES, -1, -1, IC78_VFO_ALL, IC78_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC78_OTHER_TX_MODES, W(2), W(100), IC78_VFO_ALL, IC78_ANTS), FRQ_RNG_HF(1, IC78_AM_TX_MODES, W(2), W(40), IC78_VFO_ALL, IC78_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30) - 1, IC78_ALL_RX_MODES, -1, -1, IC78_VFO_ALL, IC78_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC78_OTHER_TX_MODES, W(2), W(100), IC78_VFO_ALL, IC78_ANTS), FRQ_RNG_HF(2, IC78_AM_TX_MODES, W(2), W(40), IC78_VFO_ALL, IC78_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC78_ALL_RX_MODES, 10}, {IC78_ALL_RX_MODES, 100}, {IC78_ALL_RX_MODES, kHz(1)}, {IC78_ALL_RX_MODES, kHz(5)}, {IC78_ALL_RX_MODES, kHz(9)}, {IC78_ALL_RX_MODES, kHz(10)}, {IC78_ALL_RX_MODES, 12500}, {IC78_ALL_RX_MODES, kHz(20)}, {IC78_ALL_RX_MODES, kHz(25)}, {IC78_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .str_cal = IC78_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic78_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .scan = icom_scan, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic910.c0000644000175000017500000002605514752216205012600 00000000000000/* * Hamlib CI-V backend - description of IC-910 (VHF/UHF All-Mode Transceiver) * Contributed by Francois Retief * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "idx_builtin.h" #include "tones.h" /* * It seems some IC910 out there have weird firmware. Uncomment the following * if your modes are wrong, and please report to hamlib-developer maillist * with firmware number. That'd be interesting to have a word from Icom * on this subject, and if firmware updates are possible. */ #ifdef HAVE_WEIRD_IC910_MODES static int ic910_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { /* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */ if (mode == RIG_MODE_FM) { mode = RIG_MODE_RTTY; } return icom_set_mode(rig, vfo, mode, width); } static int ic910_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { /* FIX: The IC-910 has "Set FM" = 4, which is RTTY in for other radios */ int retval = icom_get_mode(rig, vfo, mode, width); if (*mode == RIG_MODE_RTTY) { *mode = RIG_MODE_FM; } return retval; } #endif /* HAVE_WEIRD_IC910_MODES */ /* * This function does the special bandwidth coding for IC-910 * (1 - normal, 2 - narrow) */ static int ic910_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (*pd == PD_NARROW_3) { *pd = PD_NARROW_2; } return err; } #define IC910_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC910_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC910_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) #define IC910_SCAN_OPS (RIG_SCAN_MEM) #define IC910_VFO_OPS (RIG_OP_FROM_VFO| \ RIG_OP_TO_VFO| \ RIG_OP_CPY| \ RIG_OP_MCL| \ RIG_OP_XCHG) #define IC910_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC| \ RIG_FUNC_SATMODE| \ RIG_FUNC_SCOPE) #define IC910_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_IF| \ RIG_LEVEL_NR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_KEYSPD| \ RIG_LEVEL_COMP| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY| \ RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP) #define IC910_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ static const struct icom_priv_caps ic910_priv_caps = { 0x60, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flicker */ ic910_ts_sc_list, .r2i_mode = ic910_r2i_mode }; int ic910_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { case RIG_FUNC_SCOPE: return icom_set_raw(rig, C_CTL_MEM, S_MEM_BANDSCOPE, 0, NULL, 1, status ? 1 : 0); case RIG_FUNC_SATMODE: return icom_set_raw(rig, C_CTL_MEM, S_MEM_SATMODE910, 0, NULL, 1, status ? 1 : 0); default: return icom_set_func(rig, vfo, func, status); } } int ic910_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { switch (func) { case RIG_FUNC_SCOPE: return icom_get_raw(rig, C_CTL_MEM, S_MEM_BANDSCOPE, 0, NULL, status); case RIG_FUNC_SATMODE: return icom_get_raw(rig, C_CTL_MEM, S_MEM_SATMODE910, 0, NULL, status); default: return icom_get_func(rig, vfo, func, status); } } int ic910_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_set_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, 1, val); default: return icom_set_level(rig, vfo, level, val); } } int ic910_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_get_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, val); default: return icom_get_level(rig, vfo, level, val); } } extern int ic9700_set_vfo(RIG *rig, vfo_t vfo); struct rig_caps ic910_caps = { RIG_MODEL(RIG_MODEL_IC910), .model_name = "IC-910", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC910_FUNC_ALL, .has_set_func = IC910_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = IC910_LEVEL_ALL | (RIG_LEVEL_RAWSTR), .has_set_level = IC910_LEVEL_ALL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 20, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */ .max_xit = Hz(0), .max_ifshift = Hz(0), /* 1.2kHz manual knob */ // .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = IC910_VFO_OPS, .scan_ops = IC910_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 105, RIG_MTYPE_EDGE }, { 106, 106, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { /* USA */ {MHz(144), MHz(148), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(430), MHz(450), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(148), IC910_MODES, W(5), W(100), IC910_VFO_ALL}, {MHz(430), MHz(450), IC910_MODES, W(5), W(75), IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { /* Europe */ {MHz(144), MHz(146), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(430), MHz(440), IC910_MODES, 0, 0, IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(146), IC910_MODES, W(5), W(100), IC910_VFO_ALL}, {MHz(430), MHz(440), IC910_MODES, W(5), W(75), IC910_VFO_ALL}, {MHz(1240), MHz(1300), IC910_MODES, 0, 0, IC910_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(0.1)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_FM, kHz(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* builtin */ {RIG_MODE_CW, Hz(600)}, /* with optional FL-132/Fl133 CW filters */ {RIG_MODE_FM, kHz(15)}, /* builtin */ {RIG_MODE_FM, kHz(6)}, /* builtin */ RIG_FLT_END, }, .str_cal = IC910_STR_CAL, .priv = &ic910_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icom_set_freq, #ifdef HAVE_WEIRD_IC910_MODES .get_mode = ic910_get_mode, .set_mode = ic910_set_mode, #else .get_mode = icom_get_mode, .set_mode = icom_set_mode, #endif .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .set_vfo = ic9700_set_vfo, // .get_vfo = icom_get_vfo, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = ic910_get_func, .set_func = ic910_set_func, .get_level = ic910_get_level, .set_level = ic910_set_level, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/Makefile.am0000644000175000017500000000146714752216205013643 00000000000000ICOMSRC = icom.c icom.h icom_defs.h frame.c frame.h ic706.c icr8500.c ic735.c ic775.c ic756.c \ ic275.c ic475.c ic1275.c ic820h.c ic821h.c \ icr7000.c ic910.c ic9100.c ic970.c ic725.c ic737.c ic718.c \ os535.c os456.c omni.c delta2.c ic92d.c \ ic736.c ic738.c ic7410.c ic746.c ic703.c ic726.c ic271.c \ ic765.c ic781.c ic471.c icr9000.c icr9500.c \ icr10.c icr20.c icr30.c icr6.c icr71.c icr72.c icr75.c icrx7.c icr8600.c \ id1.c id31.c id51.c id4100.c id5100.c perseus.c ic2730.c \ ic707.c ic728.c ic751.c ic761.c \ ic78.c ic7800.c ic785x.c \ ic7000.c ic7100.c ic7200.c ic7300.c ic7600.c ic7610.c ic7700.c ic7760.c icf8101.c \ ic7300.h optoscan.c optoscan.h xiegu.c level_gran_icom.h noinst_LTLIBRARIES = libhamlib-icom.la libhamlib_icom_la_SOURCES = $(ICOMSRC) EXTRA_DIST = README.icom TODO.icom Android.mk hamlib-4.6.2/rigs/icom/icr8500.c0000644000175000017500000001530514752216205013041 00000000000000/* * Hamlib CI-V backend - IC-R8500 description * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #define ICR8500_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_WFM) #define ICR8500_1MHZ_TS_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ICR8500_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_APF) #define ICR8500_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_APF|RIG_LEVEL_SQL|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR) #define ICR8500_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR8500_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|RIG_SCAN_PRIO) /* FIXME: real measure */ #define ICR8500_STR_CAL { 16, { \ { 0, -54 }, /* S0 */ \ { 10, -48 }, \ { 32, -42 }, \ { 46, -36 }, \ { 62, -30 }, \ { 82, -24 }, \ { 98, -18 }, \ { 112, -12 }, \ { 124, -6 }, \ { 134, 0 }, /* S9 */ \ { 156, 10 }, \ { 177, 20 }, \ { 192, 30 }, \ { 211, 40 }, \ { 228, 50 }, \ { 238, 60 }, \ } } int icr8500_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static struct icom_priv_caps icr8500_priv_caps = { 0x4a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list }; /* * IC-R8500 rig capabilities. */ struct rig_caps icr8500_caps = { RIG_MODEL(RIG_MODEL_ICR8500), .model_name = "ICR-8500", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = ICR8500_FUNC_ALL, .has_get_level = ICR8500_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR8500_LEVEL_ALL | RIG_LEVEL_AF), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, /* FIXME: CTCSS/DCS list */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = kHz(1.2), .targetable_vfo = 0, .vfo_ops = ICR8500_OPS, .scan_ops = ICR8500_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 12, .chan_desc_sz = 0, .str_cal = ICR8500_STR_CAL, .chan_list = { /* FIXME: memory channel list */ { 1, 999, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(824) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(849) + 10, MHz(869) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(894) + 10, GHz(2) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(824) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(849) + 10, MHz(869) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, {MHz(894) + 10, GHz(2) - 10, ICR8500_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR8500_MODES, 10}, {ICR8500_MODES, 50}, {ICR8500_MODES, 100}, {ICR8500_MODES, kHz(1)}, {ICR8500_MODES, 2500}, {ICR8500_MODES, kHz(5)}, {ICR8500_MODES, kHz(9)}, {ICR8500_MODES, kHz(10)}, {ICR8500_MODES, 12500}, {ICR8500_MODES, kHz(20)}, {ICR8500_MODES, kHz(25)}, {ICR8500_MODES, kHz(100)}, {ICR8500_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* FIXME: To be confirmed! --SF */ {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, /* narrow */ {RIG_MODE_AM, kHz(15)}, /* wide */ {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, /* narrow */ {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr8500_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icr8500_set_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int icr8500_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { case RIG_FUNC_NB: return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_NBON : S_FUNC_NBOFF, 0, NULL, 0, 0); case RIG_FUNC_FAGC: return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_AGCON : S_FUNC_AGCOFF, 0, NULL, 0, 0); case RIG_FUNC_APF: return icom_set_raw(rig, C_CTL_FUNC, status ? S_FUNC_APFON : S_FUNC_APFOFF, 0, NULL, 0, 0); default: return icom_set_func(rig, vfo, func, status); } } hamlib-4.6.2/rigs/icom/optoscan.c0000644000175000017500000005160414752216205013577 00000000000000/* * Hamlib CI-V backend - OptoScan extensions * Copyright (c) 2000-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "optoscan.h" const struct confparams opto_ext_parms[] = { { TOK_TAPECNTL, "tapecntl", "Toggle Tape Switch", "Toggles built in tape switch", 0, RIG_CONF_CHECKBUTTON, {} }, { TOK_5KHZWIN, "5khzwin", "Toggle 5kHz Search Window", "Toggles 5kHz search window", 0, RIG_CONF_CHECKBUTTON, {} }, { TOK_SPEAKER, "speaker", "Toggle speaker audio", "Toggles speaker audio", 0, RIG_CONF_CHECKBUTTON, {} }, { TOK_AUDIO, "audio", "Audio present", "Audio present", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_DTMFPEND, "dtmfpend", "DTMF Digit Pending", "DTMF Digit Pending", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_DTMFOVRR, "dtmfovrr", "DTMF Buffer Overflow", "DTMF Buffer Overflow", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_CTCSSACT, "ctcssact", "CTCSS Tone Active", "CTCSS Tone Active", NULL, RIG_CONF_CHECKBUTTON, {} }, { TOK_DCSACT, "dcsact", "DCS Code Active", "DCS Code Active", NULL, RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; static int optoscan_get_status_block(RIG *rig, struct optostat *status_block); static int optoscan_send_freq(RIG *rig, vfo_t vfo, const pltstate_t *state); static int optoscan_RTS_toggle(RIG *rig); static int optoscan_start_timer(RIG *rig, pltstate_t *state); static int optoscan_wait_timer(RIG *rig, pltstate_t *state); /* * optoscan_open * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_open(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; pltstate_t *pltstate; unsigned char ackbuf[16]; int ack_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; pltstate = calloc(1, sizeof(pltstate_t)); if (!pltstate) { return -RIG_ENOMEM; } memset(pltstate, 0, sizeof(pltstate_t)); priv->pltstate = pltstate; /* select REMOTE control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_REMOTE, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { free(pltstate); return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_open: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); free(pltstate); return -RIG_ERJCTED; } return RIG_OK; } /* * optoscan_close * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_close(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char ackbuf[16]; int ack_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; /* select LOCAL control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_LOCAL, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_close: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } free(priv->pltstate); return RIG_OK; } /* * optoscan_get_info * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ const char *optoscan_get_info(RIG *rig) { unsigned char ackbuf[16]; int ack_len, retval; static char info[64]; /* select LOCAL control */ retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDID, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return NULL; } if (ack_len != 7) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_info: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return NULL; } SNPRINTF(info, sizeof(info), "OptoScan%c%c%c, software version %d.%d, " "interface version %d.%d\n", ackbuf[2], ackbuf[3], ackbuf[4], ackbuf[5] >> 4, ackbuf[5] & 0xf, ackbuf[6] >> 4, ackbuf[6] & 0xf); return info; } /* * optoscan_get_ctcss_tone * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDCTCSS, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { return retval; } if (tone_len != 4) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_ctcss_tone: ack NG (%#.2x), " "len=%d\n", tonebuf[0], tone_len); return -RIG_ERJCTED; } tone_len -= 2; *tone = from_bcd_be(tonebuf + 2, tone_len * 2); rig_debug(RIG_DEBUG_ERR, "optoscan_get_ctcss_tone: *tone=%u\n", *tone); return RIG_OK; } /* * optoscan_get_dcs_code * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDDCS, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { return retval; } if (tone_len != 4) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_dcs_code: ack NG (%#.2x), " "len=%d\n", tonebuf[0], tone_len); return -RIG_ERJCTED; } tone_len -= 2; *code = from_bcd_be(tonebuf + 2, tone_len * 2); rig_debug(RIG_DEBUG_ERR, "optoscan_get_dcs_code: *code=%u\n", *code); return RIG_OK; } int optoscan_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { unsigned char dtmfbuf[MAXFRAMELEN], digit; int len, digitpos; const unsigned char xlate[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#' }; digitpos = 0; do { int retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDDTMF, NULL, 0, dtmfbuf, &len); if (retval != RIG_OK) { return retval; } if (len != 3) { rig_debug(RIG_DEBUG_ERR, "optoscan_recv_dtmf: ack NG (%#.2x), len=%d\n", dtmfbuf[0], len); return -RIG_ERJCTED; } digit = dtmfbuf[2]; if (digit < 16) { digits[digitpos] = xlate[digit]; digitpos++; } } while ((digit != 0x99) && (digitpos < *length)); *length = digitpos; digits[digitpos] = 0; if (*length > 0) { rig_debug(RIG_DEBUG_ERR, "%s: %d digits - %s\n", __func__, *length, digits); } else { rig_debug(RIG_DEBUG_ERR, "%s: no digits to read.\n", __func__); } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len; int retval, subcode; memset(epbuf, 0, MAXFRAMELEN); memset(ackbuf, 0, MAXFRAMELEN); switch (token) { case TOK_TAPECNTL: if (val.i == 0) { subcode = S_OPTO_TAPE_OFF; } else { subcode = S_OPTO_TAPE_ON; } break; case TOK_5KHZWIN: if (val.i == 0) { subcode = S_OPTO_5KSCOFF; } else { subcode = S_OPTO_5KSCON; } break; case TOK_SPEAKER: if (val.i == 0) { subcode = S_OPTO_SPKROFF; } else { subcode = S_OPTO_SPKRON; } break; default: return -RIG_EINVAL; } retval = icom_transaction(rig, C_CTL_MISC, subcode, epbuf, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int optoscan_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { struct optostat status_block; int retval; retval = optoscan_get_status_block(rig, &status_block); if (retval != RIG_OK) { return retval; } switch (token) { case TOK_TAPECNTL: val->i = status_block.tape_enabled; break; case TOK_5KHZWIN: val->i = status_block.fivekhz_enabled; break; case TOK_SPEAKER: val->i = status_block.speaker_enabled; break; case TOK_AUDIO: val->i = status_block.audio_present; break; case TOK_DTMFPEND: val->i = status_block.DTMF_pending; break; case TOK_DTMFOVRR: val->i = status_block.DTMF_overrun; break; case TOK_CTCSSACT: val->i = status_block.CTCSS_active; break; case TOK_DCSACT: val->i = status_block.DCS_active; break; default: return -RIG_ENIMPL; } return RIG_OK; } /* * optoscan_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int optoscan_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { unsigned char lvlbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int retval; memset(lvlbuf, 0, MAXFRAMELEN); /* * So far, levels of float type are in [0.0..1.0] range */ if (RIG_LEVEL_IS_FLOAT(level)) { icom_val = val.f * 255; } else { icom_val = val.i; } switch (level) { case RIG_LEVEL_AF: lvl_cn = C_CTL_MISC; if (icom_val == 0) { lvl_sc = S_OPTO_SPKROFF; } else { lvl_sc = S_OPTO_SPKRON; } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s", rig_strlevel(level)); return -RIG_EINVAL; } retval = icom_transaction(rig, lvl_cn, lvl_sc, lvlbuf, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "optoscan_set_level: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * optoscan_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL */ int optoscan_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct optostat status_block; int lvl_len = 0; int icom_val; int retval; if (level != RIG_LEVEL_AF) { int lvl_cn, lvl_sc; /* Command Number, Subcommand */ unsigned char lvlbuf[MAXFRAMELEN]; int cmdhead; switch (level) { case RIG_LEVEL_RAWSTR: lvl_cn = C_RD_SQSM; lvl_sc = S_SML; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s", rig_strlevel(level)); return -RIG_EINVAL; } retval = icom_transaction(rig, lvl_cn, lvl_sc, NULL, 0, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (lvl_sc == -1) ? 1 : 2; lvl_len -= cmdhead; if (lvlbuf[0] != ACK && lvlbuf[0] != lvl_cn) { rig_debug(RIG_DEBUG_ERR, "optoscan_get_level: ack NG (%#.2x), " "len=%d\n", lvlbuf[0], lvl_len); return -RIG_ERJCTED; } /* * The result is a 3 digit BCD, but in *big endian* order: 0000..0255 * (from_bcd is little endian) */ icom_val = from_bcd_be(lvlbuf + cmdhead, lvl_len * 2); } else /* level == RIG_LEVEL_AF */ { retval = optoscan_get_status_block(rig, &status_block); if (retval != RIG_OK) { return retval; } icom_val = 0; if (status_block.speaker_enabled == 1) { icom_val = 255; } } switch (level) { case RIG_LEVEL_RAWSTR: val->i = icom_val; break; default: if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float)icom_val / 255; } else { val->i = icom_val; } } rig_debug(RIG_DEBUG_TRACE, "optoscan_get_level: %d %d %d %f\n", lvl_len, icom_val, val->i, val->f); return RIG_OK; } /* OS456 Pipeline tuning algorithm: * Step 2: Send the next frequency and mode to the receiver using the * TRANSFER NEXT FREQUENCY/MODE command. * * Step 3: Change the state of the RTS interface signal to cause the * next frequency and mode to become the current frequency and * mode, and the receiver to begin settling. * * Step 4: While the receiver is still settling on the current * frequency and mode, send the next frequency and mode to the * receiver using the TRANSFER NEXT FREQUENCY/MODE command. * * Step 5: Wait for the receiver to finish settling. The total * settling time, including sending the next frequency and * mode, is 20 milliseconds (0.02 seconds). * * Step 6: Check the squelch status by reading the DCD interface * signal. If the squelch is open, scanning is stopped. * Otherwise, scanning continues. Optionally, the status of * the CTCSS/DCS/DTMF decoder can be checked, and the * appropriate action taken. * * Step 7: Continuously repeat steps 3 through 6 above. */ int optoscan_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { pltstate_t *state; pltune_cb_t cb; int rc, pin_state; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); if (scan != RIG_SCAN_PLT) { return -RIG_ENAVAIL; } rs = STATE(rig); cb = rig->callbacks.pltune; state = ((struct icom_priv_data *)rs->priv)->pltstate; if (state == NULL) { return -RIG_EINTERNAL; } if (state->freq == 0) /* pltstate_t is not initialized - perform setup */ { /* time for CIV command to be sent. this is subtracted from */ /* rcvr settle time */ state->usleep_time = (1000000 / (rp->parm.serial.rate)) * 13 * 9; rc = cb(rig, vfo, &(state->next_freq), &(state->next_mode), &(state->next_width), rig->callbacks.pltune_arg); if (rc == RIG_SCAN_STOP) { return RIG_OK; /* callback halted loop */ } /* Step 1 is implicit, since hamlib does this when it opens the device */ optoscan_send_freq(rig, vfo, state); /*Step 2*/ } rc = 0; while (rc != RIG_SCAN_STOP) { optoscan_RTS_toggle(rig); /*Step 3*/ state->freq = state->next_freq; state->mode = state->next_mode; optoscan_start_timer(rig, state); rc = cb(rig, vfo, &(state->next_freq), &(state->next_mode), &(state->next_width), rig->callbacks.pltune_arg); if (rc != RIG_SCAN_STOP) { optoscan_send_freq(rig, vfo, state); /*Step 4*/ } optoscan_wait_timer(rig, state); /*Step 5*/ ser_get_car(rp, &pin_state); if (pin_state) /*Step 6*/ { return RIG_OK; /* we've broken squelch - return(). caller can */ /* get current freq & mode out of state str */ } } /* exiting pipeline loop - force state init on next call */ state->freq = 0; return RIG_OK; } /* * Assumes rig!=NULL, status_block !=NULL */ static int optoscan_get_status_block(RIG *rig, struct optostat *status_block) { int retval, ack_len, expected_len; unsigned char ackbuf[MAXFRAMELEN]; memset(status_block, 0, sizeof(struct optostat)); retval = icom_transaction(rig, C_CTL_MISC, S_OPTO_RDSTAT, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } switch (rig->caps->rig_model) { case RIG_MODEL_OS456: expected_len = 4; break; case RIG_MODEL_OS535: expected_len = 5; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown rig model", __func__); return -RIG_ERJCTED; break; } if (ack_len != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } if (ackbuf[2] & 1) { status_block->remote_control = 1; } if (ackbuf[2] & 2) { status_block->DTMF_pending = 1; } if (ackbuf[2] & 4) { status_block->DTMF_overrun = 1; } if (ackbuf[2] & 16) { status_block->squelch_open = 1; } if (ackbuf[2] & 32) { status_block->CTCSS_active = 1; } if (ackbuf[2] & 64) { status_block->DCS_active = 1; } if (ackbuf[3] & 1) { status_block->tape_enabled = 1; } if (ackbuf[3] & 2) { status_block->speaker_enabled = 1; } if (ackbuf[3] & 4) { status_block->fivekhz_enabled = 1; } if (ackbuf[3] & 16) { status_block->audio_present = 1; } rig_debug(RIG_DEBUG_VERBOSE, "remote_control = %d\n", status_block->remote_control); rig_debug(RIG_DEBUG_VERBOSE, "DTMF_pending = %d\n", status_block->DTMF_pending); rig_debug(RIG_DEBUG_VERBOSE, "DTMF_overrun = %d\n", status_block->DTMF_overrun); rig_debug(RIG_DEBUG_VERBOSE, "squelch_open = %d\n", status_block->squelch_open); rig_debug(RIG_DEBUG_VERBOSE, "CTCSS_active = %d\n", status_block->CTCSS_active); rig_debug(RIG_DEBUG_VERBOSE, "DCS_active = %d\n", status_block->DCS_active); rig_debug(RIG_DEBUG_VERBOSE, "tape_enabled = %d\n", status_block->tape_enabled); rig_debug(RIG_DEBUG_VERBOSE, "speaker_enabled = %d\n", status_block->speaker_enabled); rig_debug(RIG_DEBUG_VERBOSE, "fivekhz_enabled = %d\n", status_block->fivekhz_enabled); rig_debug(RIG_DEBUG_VERBOSE, "audio_present = %d\n", status_block->audio_present); return RIG_OK; } static int optoscan_send_freq(RIG *rig, vfo_t vfo, const pltstate_t *state) { unsigned char buff[OPTO_BUFF_SIZE]; char md, pd; freq_t freq; rmode_t mode; freq = state->next_freq; mode = state->next_mode; memset(buff, 0, OPTO_BUFF_SIZE); to_bcd(buff, freq, 5 * 2); /* to_bcd requires nibble len */ rig2icom_mode(rig, vfo, mode, 0, (unsigned char *) &md, (signed char *) &pd); buff[5] = md; /* read echo'd chars only...there will be no ACK from this command * * Note: * It may have waited for pltstate->usleep_time before reading the echo'd * chars, but the read will be blocking anyway. --SF * */ return icom_transaction(rig, C_CTL_MISC, S_OPTO_NXT, buff, 6, NULL, NULL); } static int optoscan_RTS_toggle(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); int state = 0; ser_get_rts(rp, &state); ser_set_rts(rp, !state); return RIG_OK; } static int optoscan_start_timer(RIG *rig, pltstate_t *state) { gettimeofday(&(state->timer_start), NULL); return RIG_OK; } static int optoscan_wait_timer(RIG *rig, pltstate_t *state) { struct icom_priv_caps *priv_caps; int usec_diff; int settle_usec; priv_caps = (struct icom_priv_caps *)rig->caps->priv; settle_usec = priv_caps->settle_time * 1000; /*convert settle time (ms) to */ /* settle time (usec) */ gettimeofday(&(state->timer_current), NULL); usec_diff = (int)labs((state->timer_current.tv_usec) - (state->timer_start.tv_usec)); if (usec_diff < settle_usec) { hl_usleep(settle_usec - usec_diff); /* sleep balance of settle_time */ } return RIG_OK; } hamlib-4.6.2/rigs/icom/id4100.c0000644000175000017500000001470614752216205012654 00000000000000/* * Hamlib CI-V backend - description of ID-4100 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" /* * Specs and protocol details comes from the chapter 10 of ID-4100A_E_ENG_PU_0.pdf * * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP2" for rig control. * * TODO: * - DV mode * - GPS support * - Single/dual watch (RIG_LEVEL_BALANCE) */ #define ID4100_MODES (RIG_MODE_FM|RIG_MODE_DSTAR) #define ID4100_ALL_RX_MODES (RIG_MODE_AM|ID4100_MODES) #define ID4100_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define ID4100_SCAN_OPS RIG_SCAN_NONE #define ID4100_VFO_OPS RIG_OP_NONE #define ID4100_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_VOX) #define ID4100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID4100_PARM_ALL RIG_PARM_NONE /* * FIXME: real measurement */ #define ID4100_STR_CAL UNKNOWN_IC_STR_CAL /* */ static struct icom_priv_caps id4100_priv_caps = { 0x9A, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps id4100_caps = { RIG_MODEL(RIG_MODEL_ID4100), .model_name = "ID-4100", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID4100_FUNC_ALL, .has_set_func = ID4100_FUNC_ALL, .has_get_level = ID4100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID4100_LEVEL_ALL), .has_get_parm = ID4100_PARM_ALL, .has_set_parm = ID4100_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID4100_VFO_OPS, .scan_ops = ID4100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, {MHz(375), MHz(550), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), ID4100_MODES, W(5), W(25), ID4100_VFO_ALL}, {MHz(430), MHz(440), ID4100_MODES, W(5), W(25), ID4100_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, {MHz(375), MHz(550), ID4100_ALL_RX_MODES, -1, -1, ID4100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), ID4100_MODES, W(5), W(50), ID4100_VFO_ALL}, {MHz(430), MHz(450), ID4100_MODES, W(5), W(50), ID4100_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID4100_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id4100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, //.set_powerstat = icom_set_powerstat, // ID-4100 does cannot query power .get_powerstat = icom_get_powerstat, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic707.c0000644000175000017500000001174614752216205012605 00000000000000/* * Hamlib CI-V backend - description of IC-707 * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC707_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * IC-707 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic707/specs.htm * */ #define IC707_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC707_AM_TX_MODES (RIG_MODE_AM) #define IC707_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC707_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC707_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_STOP) #define IC707_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic707_priv_caps = { 0x3e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic707_caps = { RIG_MODEL(RIG_MODEL_IC707), .model_name = "IC-707", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC707_VFO_OPS, .scan_ops = IC707_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 25, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 26, 30, RIG_MTYPE_SPLIT, IC_MIN_MEM_CAP }, /* split ? */ { 31, 32, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC707_ALL_RX_MODES, -1, -1, IC707_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC707_OTHER_TX_MODES, W(5), W(100), IC707_VFO_ALL, IC707_ANTS), FRQ_RNG_HF(1, IC707_AM_TX_MODES, W(5), W(25), IC707_VFO_ALL, IC707_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC707_ALL_RX_MODES, -1, -1, IC707_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC707_OTHER_TX_MODES, W(5), W(100), IC707_VFO_ALL, IC707_ANTS), FRQ_RNG_HF(2, IC707_AM_TX_MODES, W(5), W(25), IC707_VFO_ALL, IC707_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC707_ALL_RX_MODES, 10}, {IC707_ALL_RX_MODES, 1000}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic707_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_ts = icom_set_ts, // .get_ts = icom_get_ts, // apparently does not have this .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icom.c0000644000175000017500000101556214752216205012704 00000000000000/* * Hamlib CI-V backend - main file * Copyright (c) 2000-2016 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ // cppcheck-suppress * #include // cppcheck-suppress * #include /* String function definitions */ // cppcheck-suppress * #include /* UNIX standard function definitions */ // cppcheck-suppress * #include #include #include #include #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" #include "event.h" // we automatically determine availability of the 1A 03 command enum { ENUM_1A_03_UNK, ENUM_1A_03_YES, ENUM_1A_03_NO }; static int set_vfo_curr(RIG *rig, vfo_t vfo, vfo_t curr_vfo); static int icom_set_default_vfo(RIG *rig); static int icom_get_spectrum_vfo(RIG *rig, vfo_t vfo); static int icom_get_spectrum_edge_frequency_range(RIG *rig, vfo_t vfo, int *range_id); static void icom_set_x25x26_ability(RIG *rig, int status); static int icom_get_vfo_number_x25x26(RIG *rig, vfo_t vfo); const int cw_lookup [43][2] = { {0, 6}, {7, 7}, {12, 8}, {19, 9}, {25, 10}, {31, 11}, {37, 12}, {43, 13}, {49, 14}, {55, 15}, {61, 16}, {67, 17}, {73, 18}, {79, 19}, {84, 20}, {91, 21}, {97, 22}, {103, 23}, {108, 24}, {114, 25}, {121, 26}, {128, 27}, {134, 28}, {140, 29}, {144, 30}, {151, 31}, {156, 32}, {164, 33}, {169, 34}, {175, 35}, {182, 36}, {188, 37}, {192, 38}, {199, 39}, {203, 40}, {211, 41}, {215, 42}, {224, 43}, {229, 44}, {234, 45}, {239, 46}, {244, 47}, {250, 48} }; const cal_table_float_t icom_default_swr_cal = { 5, { {0, 1.0f}, {48, 1.5f}, {80, 2.0f}, {120, 3.0f}, {240, 6.0f} } }; const cal_table_float_t icom_default_alc_cal = { 2, { {0, 0.0f}, {120, 1.0f} } }; const cal_table_float_t icom_default_rfpower_meter_cal = { 13, { { 0, 0.0f }, { 21, 5.0f }, { 43, 10.0f }, { 65, 15.0f }, { 83, 20.0f }, { 95, 25.0f }, { 105, 30.0f }, { 114, 35.0f }, { 124, 40.0f }, { 143, 50.0f }, { 183, 75.0f }, { 213, 100.0f }, { 255, 120.0f } } }; const cal_table_float_t icom_default_comp_meter_cal = { 3, { {0, 0.0f}, {130, 15.0f}, {241, 30.0f} } }; const cal_table_float_t icom_default_vd_meter_cal = { 3, { {0, 0.0f}, {13, 10.0f}, {241, 16.0f} } }; const cal_table_float_t icom_default_id_meter_cal = { 4, { {0, 0.0f}, {97, 10.0f}, {146, 15.0f}, {241, 25.0f} } }; const struct ts_sc_list r8500_ts_sc_list[] = { {10, 0x00}, {50, 0x01}, {100, 0x02}, {kHz(1), 0x03}, {2500, 0x04}, {kHz(5), 0x05}, {kHz(9), 0x06}, {kHz(10), 0x07}, {12500, 0x08}, {kHz(20), 0x09}, {kHz(25), 0x10}, {kHz(100), 0x11}, {MHz(1), 0x12}, {0, 0x13}, /* programmable tuning step not supported */ {0, 0}, }; const struct ts_sc_list ic737_ts_sc_list[] = { {10, 0x00}, {kHz(1), 0x01}, {kHz(2), 0x02}, {kHz(3), 0x03}, {kHz(4), 0x04}, {kHz(5), 0x05}, {kHz(6), 0x06}, {kHz(7), 0x07}, {kHz(8), 0x08}, {kHz(9), 0x09}, {kHz(10), 0x10}, {0, 0}, }; const struct ts_sc_list r75_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {6250, 0x04}, {kHz(9), 0x05}, {kHz(10), 0x06}, {12500, 0x07}, {kHz(20), 0x08}, {kHz(25), 0x09}, {kHz(100), 0x10}, {MHz(1), 0x11}, {0, 0}, }; const struct ts_sc_list r7100_ts_sc_list[] = { {100, 0x00}, {kHz(1), 0x01}, {kHz(5), 0x02}, {kHz(10), 0x03}, {12500, 0x04}, {kHz(20), 0x05}, {kHz(25), 0x06}, {kHz(100), 0x07}, {0, 0}, }; const struct ts_sc_list r9000_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {12500, 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {kHz(100), 0x09}, {0, 0}, }; const struct ts_sc_list r9500_ts_sc_list[] = { {1, 0x00}, {10, 0x01}, {100, 0x02}, {kHz(1), 0x03}, {kHz(2.5), 0x04}, {kHz(5), 0x05}, {6250, 0x06}, {kHz(9), 0x07}, {kHz(10), 0x08}, {12500, 0x09}, {kHz(20), 0x10}, {kHz(25), 0x11}, {kHz(100), 0x12}, {MHz(1), 0x13}, {0, 0}, }; const struct ts_sc_list ic718_ts_sc_list[] = { {10, 0x00}, {kHz(1), 0x01}, {kHz(5), 0x01}, {kHz(9), 0x01}, {kHz(10), 0x04}, {kHz(100), 0x05}, {0, 0}, }; const struct ts_sc_list ic756_ts_sc_list[] = { {10, 0x00}, {kHz(1), 0x01}, {kHz(5), 0x02}, {kHz(9), 0x03}, {kHz(10), 0x04}, {0, 0}, }; const struct ts_sc_list ic756pro_ts_sc_list[] = { {10, 0x00}, /* 1 if step turned off */ {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {kHz(12.5), 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {0, 0}, }; const struct ts_sc_list ic706_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {12500, 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {kHz(100), 0x09}, {0, 0}, }; const struct ts_sc_list ic7000_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {12500, 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {kHz(100), 0x09}, {MHz(1), 0x10}, {0, 0}, }; const struct ts_sc_list ic7100_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(6.25), 0x04}, {kHz(9), 0x05}, {kHz(10), 0x06}, {kHz(12.5), 0x07}, {kHz(20), 0x08}, {kHz(25), 0x09}, {kHz(50), 0x0A}, {kHz(100), 0x0B}, {MHz(1), 0x0C}, {0, 0x00}, }; const struct ts_sc_list ic7200_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {0, 0}, }; const struct ts_sc_list ic7300_ts_sc_list[] = { {1, 0x00}, /* Manual says "Send/read the tuning step OFF" */ {100, 0x01}, {kHz(1), 0x02}, {kHz(5), 0x03}, {kHz(9), 0x04}, {kHz(10), 0x05}, {kHz(12.5), 0x06}, {kHz(20), 0x07}, {kHz(25), 0x08}, {0, 0}, }; const struct ts_sc_list ic910_ts_sc_list[] = { {Hz(1), 0x00}, {Hz(10), 0x01}, {Hz(50), 0x02}, {Hz(100), 0x03}, {kHz(1), 0x04}, {kHz(5), 0x05}, {kHz(6.25), 0x06}, {kHz(10), 0x07}, {kHz(12.5), 0x08}, {kHz(20), 0x09}, {kHz(25), 0x10}, {kHz(100), 0x11}, {0, 0}, }; const struct ts_sc_list r8600_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {kHz(1), 0x02}, {kHz(2.5), 0x03}, {3125, 0x04}, {kHz(5), 0x05}, {6250, 0x06}, {8330, 0x07}, {kHz(9), 0x08}, {kHz(10), 0x09}, {kHz(12.5), 0x10}, {kHz(20), 0x11}, {kHz(25), 0x12}, {kHz(100), 0x13}, {0, 0x14}, /* programmable tuning step not supported */ {0, 0}, }; const struct ts_sc_list ic705_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {500, 0x02}, {kHz(1), 0x03}, {kHz(5), 0x04}, {kHz(6.25), 0x05}, {kHz(8.33), 0x06}, {kHz(9), 0x07}, {kHz(10), 0x08}, {kHz(12.5), 0x09}, {kHz(20), 0x10}, {kHz(25), 0x11}, {kHz(50), 0x12}, {kHz(100), 0x13}, {0, 0}, }; const struct ts_sc_list ic9700_ts_sc_list[] = { {10, 0x00}, {100, 0x01}, {500, 0x02}, {kHz(1), 0x03}, {kHz(5), 0x04}, {kHz(6.25), 0x05}, {kHz(10), 0x06}, {kHz(12.5), 0x07}, {kHz(20), 0x08}, {kHz(25), 0x09}, {kHz(50), 0x10}, {kHz(100), 0x11}, {0, 0}, }; /* rtty filter list for some DSP rigs ie PRO */ #define RTTY_FIL_NB 5 const pbwidth_t rtty_fil[] = { Hz(250), Hz(300), Hz(350), Hz(500), kHz(1), 0, }; /* AGC Time value lookups */ const agc_time_t agc_level[] = // default { 0, 0.1, 0.2, 0.3, 0.5, 0.8, 1.2, 1.6, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0 }; const agc_time_t agc_level2[] = // AM Mode for 7300/9700/705 { 0, 0.3, 0.5, 0.8, 1.2, 1.6, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 }; struct icom_addr { rig_model_t model; unsigned char re_civ_addr; }; #define TOK_CIVADDR TOKEN_BACKEND(1) #define TOK_MODE731 TOKEN_BACKEND(2) #define TOK_NOXCHG TOKEN_BACKEND(3) #define TOK_TONE_ENABLE TOKEN_BACKEND(4) #define TOK_FILTER_USBD TOKEN_BACKEND(5) #define TOK_FILTER_USB TOKEN_BACKEND(6) #define TOK_FILTER_CW TOKEN_BACKEND(7) #define TOK_FILTER_FM TOKEN_BACKEND(8) const struct confparams icom_cfg_params[] = { { TOK_CIVADDR, "civaddr", "CI-V address", "Transceiver's CI-V address", "0", RIG_CONF_NUMERIC, {.n = {0, 0xff, 1}} }, { TOK_MODE731, "mode731", "CI-V 731 mode", "CI-V operating frequency " "data length, needed for IC731 and IC735", "0", RIG_CONF_CHECKBUTTON }, { TOK_NOXCHG, "no_xchg", "No VFO XCHG", "Don't Use VFO XCHG to set other VFO mode and Frequency", "0", RIG_CONF_CHECKBUTTON }, { TOK_TONE_ENABLE, "tone_enable", "Turn tone on", "Overcome a bug in IC-705 to enable tone after frequency change", "0", RIG_CONF_CHECKBUTTON }, { TOK_FILTER_USBD, "filter_usbd", "Filter to use USBD", "Filter to use for USBD/LSBD when setting mode", "1", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, { TOK_FILTER_USB, "filter_usb", "Filter to use USB", "Filter to use when for USB/LSB setting mode", "2", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, { TOK_FILTER_CW, "filter_cw", "Filter to use CW", "Filter to use for CW/CWR when setting mode", "3", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, { TOK_FILTER_FM, "filter_fm", "Filter to use FM", "Filter to use for FM/PKTFM when setting mode", "1", RIG_CONF_NUMERIC, {.n = {0, 3, 1}} }, {RIG_CONF_END, NULL,} }; /* * Lookup table for icom_get_ext_func */ const struct confparams icom_ext_funcs[] = { { TOK_DIGI_SEL_FUNC, "digi_sel", "DIGI-SEL enable", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_IPP_FUNC, "IPP", "IP Plus", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_TX_INHIBIT_FUNC, "TX_INHIBIT", "TX Inhibit", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_DPP_FUNC, "DPP", "Digital Pre Distortion-SEL enable", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_ICPW2_FUNC, "ICPW2", "Icom PW2 enable", "", "", RIG_CONF_CHECKBUTTON, {} }, { RIG_CONF_END, NULL, } }; /* * Lookup table for icom_get_ext_level */ const struct confparams icom_ext_levels[] = { { TOK_DIGI_SEL_LEVEL, "digi_sel_level", "DIGI-SEL level", "", "", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } }, { TOK_DRIVE_GAIN, "drive_gain", "Drive gain", "", "", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } }, { TOK_SCOPE_MSS, "SPECTRUM_SELECT", "Spectrum Scope Main/Sub", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Main", "Sub", NULL } } } }, { TOK_SCOPE_SDS, "SPECTRUM_DUAL", "Spectrum Scope Single/Dual", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Single", "Dual", NULL } } } }, { TOK_SCOPE_EDG, "SPECTRUM_EDGE", "Spectrum Scope Edge", "Edge selection for fixed scope mode", "", RIG_CONF_COMBO, { .c = { .combostr = { "1", "2", "3", "4", NULL } } } }, { TOK_SCOPE_STX, "SPECTRUM_TX", "Spectrum Scope TX operation", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_SCOPE_CFQ, "SPECTRUM_CENTER", "Spectrum Scope Center Frequency Type", "", "", RIG_CONF_COMBO, { .c = { .combostr = { "Filter center", "Carrier point center", "Carrier point center (Abs. Freq.)", NULL } } } }, { TOK_SCOPE_VBW, "SPECTRUM_VBW", "Spectrum Scope VBW", "Video Band Width", "", RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Wide", NULL } } } }, { TOK_SCOPE_RBW, "SPECTRUM_RBW", "Spectrum Scope RBW", "Resolution Band Width", "", RIG_CONF_COMBO, { .c = { .combostr = { "Wide", "Mid", "Narrow", NULL } } } }, { RIG_CONF_END, NULL, } }; /* * Lookup table for icom_get_ext_parm */ const struct confparams icom_ext_parms[] = { { TOK_DSTAR_DSQL, "dsdsql", "D-STAR CSQL Status", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_DSTAR_CALL_SIGN, "dscals", "D-STAR Call sign", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_MESSAGE, "dsrmes", "D-STAR Rx Message", "", "", RIG_CONF_STRING, {} }, { TOK_DSTAR_STATUS, "dsstat", "D-STAR Rx Status", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_GPS_DATA, "dsgpsd", "D-STAR GPS Data", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_GPS_MESS, "dsgpsm", "D-STAR GPS Message", "", "", RIG_CONF_STRING, {} }, { TOK_DSTAR_CODE, "dscode", "D-STAR CSQL Code", "", "", RIG_CONF_NUMERIC, {} }, { TOK_DSTAR_TX_DATA, "dstdat", "D-STAR Tx Data", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_MY_CS, "dsmycs", "D-STAR MY Call Sign", "", "", RIG_CONF_STRING, {} }, { TOK_DSTAR_TX_CS, "dstxcs", "D-STAR Tx Call Sign", "", "", RIG_CONF_BINARY, {} }, { TOK_DSTAR_TX_MESS, "dstmes", "D-STAR Tx Message", "", "", RIG_CONF_STRING, {} }, { RIG_CONF_END, NULL, } }; /* * Lookup table for icom_get_ext_* & icom_set_ext_* functions */ const struct cmdparams icom_ext_cmd[] = { { {.t = TOK_DSTAR_DSQL}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCSQL, SC_MOD_RW, 1, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_DSTAR_CALL_SIGN}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCALS, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 38 }, { {.t = TOK_DSTAR_MESSAGE}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSMESS, SC_MOD_RW12, 2, {0}, CMD_DAT_STR, 32 }, { {.t = TOK_DSTAR_STATUS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSRSTS, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 1 }, { {.t = TOK_DSTAR_GPS_DATA}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSGPSD, SC_MOD_RW12, 2, {0}, CMD_DAT_BUF, 52 }, { {.t = TOK_DSTAR_GPS_MESS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSGPSM, SC_MOD_RW12, 2, {0}, CMD_DAT_STR, 52 }, { {.t = TOK_DSTAR_CODE}, CMD_PARAM_TYPE_TOKEN, C_CTL_DIG, S_DIG_DSCSQL, SC_MOD_RW12, 2, {0}, CMD_DAT_FLT, 1 }, { {.t = TOK_DSTAR_TX_DATA}, CMD_PARAM_TYPE_TOKEN, C_CTL_DSD, S_DSD_DSTXDT, SC_MOD_RW, 1, {0}, CMD_DAT_BUF, 30 }, { {.t = TOK_DSTAR_MY_CS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSMYCS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 12 }, { {.t = TOK_DSTAR_TX_CS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSTXCS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 24 }, { {.t = TOK_DSTAR_TX_MESS}, CMD_PARAM_TYPE_TOKEN, C_CTL_DVT, S_DVT_DSTXMS, SC_MOD_RW, 1, {0}, CMD_DAT_STR, 20 }, { {.t = TOK_DRIVE_GAIN}, CMD_PARAM_TYPE_TOKEN, C_CTL_LVL, S_LVL_DRIVE, SC_MOD_RW, 0, {0}, CMD_DAT_FLT, 2 }, { {.t = TOK_DIGI_SEL_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_DIGISEL, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_DIGI_SEL_LEVEL}, CMD_PARAM_TYPE_TOKEN, C_CTL_LVL, S_LVL_DIGI, SC_MOD_RW, 0, {0}, CMD_DAT_FLT, 2 }, { {.t = TOK_IPP_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_IPP, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_TX_INHIBIT_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_TX_INHIBIT, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_DPP_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_FUNC, S_FUNC_DPP, SC_MOD_RW, 0, {0}, CMD_DAT_BOL, 1 }, { {.t = TOK_ICPW2_FUNC}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, 0x05, SC_MOD_RW, 2, {0x03, 0x10}, CMD_DAT_BOL, 1 }, { {0} } }; /* * Please, if the default CI-V address of your rig is listed as UNKNOWN_ADDR, * send the value to for inclusion. Thanks --SF */ static const struct icom_addr icom_addr_list[] = { {RIG_MODEL_IC703, 0x68}, {RIG_MODEL_IC706, 0x48}, {RIG_MODEL_IC706MKII, 0x4e}, {RIG_MODEL_IC706MKIIG, 0x58}, {RIG_MODEL_IC271, 0x20}, {RIG_MODEL_IC275, 0x10}, {RIG_MODEL_IC375, 0x12}, {RIG_MODEL_IC471, 0x22}, {RIG_MODEL_IC475, 0x14}, {RIG_MODEL_IC575, 0x16}, {RIG_MODEL_IC707, 0x3e}, {RIG_MODEL_IC725, 0x28}, {RIG_MODEL_IC726, 0x30}, {RIG_MODEL_IC728, 0x38}, {RIG_MODEL_IC729, 0x3a}, {RIG_MODEL_IC731, 0x02}, /* need confirmation */ {RIG_MODEL_IC735, 0x04}, {RIG_MODEL_IC736, 0x40}, {RIG_MODEL_IC7410, 0x80}, {RIG_MODEL_IC746, 0x56}, {RIG_MODEL_IC746PRO, 0x66}, {RIG_MODEL_IC737, 0x3c}, {RIG_MODEL_IC738, 0x44}, {RIG_MODEL_IC751, 0x1c}, {RIG_MODEL_IC751A, 0x1c}, {RIG_MODEL_IC756, 0x50}, {RIG_MODEL_IC756PRO, 0x5c}, {RIG_MODEL_IC756PROII, 0x64}, {RIG_MODEL_IC756PROIII, 0x6e}, {RIG_MODEL_IC7600, 0x7a}, {RIG_MODEL_IC761, 0x1e}, {RIG_MODEL_IC765, 0x2c}, {RIG_MODEL_IC775, 0x46}, {RIG_MODEL_IC7800, 0x6a}, {RIG_MODEL_IC785x, 0x8e}, {RIG_MODEL_IC781, 0x26}, {RIG_MODEL_IC820, 0x42}, {RIG_MODEL_IC821H, 0x4c}, {RIG_MODEL_IC910, 0x60}, {RIG_MODEL_IC9100, 0x7c}, {RIG_MODEL_IC9700, 0xa2}, {RIG_MODEL_IC970, 0x2e}, {RIG_MODEL_IC1271, 0x24}, {RIG_MODEL_IC1275, 0x18}, {RIG_MODEL_ICR10, 0x52}, {RIG_MODEL_ICR20, 0x6c}, {RIG_MODEL_ICR6, 0x7e}, {RIG_MODEL_ICR71, 0x1a}, {RIG_MODEL_ICR72, 0x32}, {RIG_MODEL_ICR75, 0x5a}, {RIG_MODEL_ICRX7, 0x78}, {RIG_MODEL_IC78, 0x62}, {RIG_MODEL_ICR7000, 0x08}, {RIG_MODEL_ICR7100, 0x34}, {RIG_MODEL_ICR8500, 0x4a}, {RIG_MODEL_ICR9000, 0x2a}, {RIG_MODEL_ICR9500, 0x72}, // {RIG_MODEL_MINISCOUT, 0x94}, // ic7300 took this one {RIG_MODEL_IC718, 0x5e}, {RIG_MODEL_OS535, 0x80}, /* same address as IC-7410 */ {RIG_MODEL_ICID1, 0x01}, {RIG_MODEL_IC7000, 0x70}, {RIG_MODEL_IC7100, 0x88}, {RIG_MODEL_IC7200, 0x76}, {RIG_MODEL_IC7300, 0x94}, {RIG_MODEL_IC7610, 0x98}, {RIG_MODEL_IC7700, 0x74}, {RIG_MODEL_IC7760, 0xB2}, {RIG_MODEL_PERSEUS, 0xE1}, {RIG_MODEL_X108G, 0x70}, {RIG_MODEL_X6100, 0x70}, {RIG_MODEL_ICR8600, 0x96}, {RIG_MODEL_ICR30, 0x9c}, {RIG_MODEL_NONE, 0}, }; /* * This is a generic icom_init function. * You might want to define yours, so you can customize it for your rig * * Basically, it sets up *priv * REM: serial port is already open (RIGPORT(rig)->fd) */ int icom_init(RIG *rig) { struct icom_priv_data *priv; struct icom_priv_caps *priv_caps; struct rig_caps *caps; struct rig_state *rs = STATE(rig); int i; ENTERFUNC; if (!rig->caps) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (!caps->priv) { RETURNFUNC(-RIG_ECONF); } priv_caps = (struct icom_priv_caps *) caps->priv; rs->priv = (struct icom_priv_data *) calloc(1, sizeof(struct icom_priv_data)); if (!rs->priv) { /* whoops! memory shortage! */ RETURNFUNC(-RIG_ENOMEM); } priv = rs->priv; priv->spectrum_scope_count = 0; for (i = 0; caps->spectrum_scopes[i].name != NULL; i++) { priv->spectrum_scope_cache[i].spectrum_data = NULL; if (priv_caps->spectrum_scope_caps.spectrum_line_length < 1) { rig_debug(RIG_DEBUG_ERR, "%s: no spectrum scope line length defined\n", __func__); RETURNFUNC(-RIG_ECONF); } priv->spectrum_scope_cache[i].spectrum_data = calloc(1, priv_caps->spectrum_scope_caps.spectrum_line_length); if (!priv->spectrum_scope_cache[i].spectrum_data) { RETURNFUNC(-RIG_ENOMEM); } priv->spectrum_scope_count++; } /* TODO: CI-V address should be customizable */ /* * init the priv_data from static struct * + override with preferences */ priv->re_civ_addr = priv_caps->re_civ_addr; priv->civ_731_mode = priv_caps->civ_731_mode; priv->no_xchg = priv_caps->no_xchg; priv->serial_USB_echo_off = -1; // unknown at this point priv->x25cmdfails = 1; priv->x26cmdfails = 1; priv->x1cx03cmdfails = 0; // Reset 0x25/0x26 command detection for the rigs that may support it icom_set_x25x26_ability(rig, -1); rig_debug(RIG_DEBUG_TRACE, "%s: done\n", __func__); RETURNFUNC(RIG_OK); } /* * ICOM Generic icom_cleanup routine * the serial port is closed by the frontend */ int icom_cleanup(RIG *rig) { struct icom_priv_data *priv; int i; ENTERFUNC; priv = STATE(rig)->priv; for (i = 0; rig->caps->spectrum_scopes[i].name != NULL; i++) { if (priv->spectrum_scope_cache[i].spectrum_data) { free(priv->spectrum_scope_cache[i].spectrum_data); priv->spectrum_scope_cache[i].spectrum_data = NULL; } } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /** * Returns 1 when USB ECHO is off * Returns 0 when USB ECHO is on * \return Returns < 0 when error occurs (e.g. timeout, nimple, navail) */ int icom_get_usb_echo_off(RIG *rig) { int retval; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; ENTERFUNC; // Check for echo on first by assuming echo is off and checking the answer priv->serial_USB_echo_off = 1; retval = icom_transaction(rig, C_RD_FREQ, -1, NULL, 0, ackbuf, &ack_len); // if rig is not powered on we get no data and TIMEOUT if (ack_len == 0 && retval == -RIG_ETIMEOUT) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: ack_len=%d\n", __func__, ack_len); if (ack_len == 1) // then we got an echo of the cmd { unsigned char buf[16]; priv->serial_USB_echo_off = 0; // we should have a freq response so we'll read it and don't really care // flushing doesn't always work as it depends on timing retval = read_icom_frame(RIGPORT(rig), buf, sizeof(buf)); rig_debug(RIG_DEBUG_VERBOSE, "%s: USB echo on detected, get freq retval=%d\n", __func__, retval); if (retval <= 0) { RETURNFUNC(-RIG_ETIMEOUT); } } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: USB echo off detected\n", __func__); } RETURNFUNC(priv->serial_USB_echo_off); } static int icom_check_ack(int ack_len, unsigned char *ackbuf) { if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK)) { // if we don't get ACK/NAK some serial corruption occurred // so we'll call it a timeout for retry purposes rig_debug(RIG_DEBUG_WARN, "%s: command timed out (%#.2x)\n", __func__, ackbuf[0]); return -RIG_ETIMEOUT; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: command not acknowledged (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } #if 0 // this causes the rig to go into VFO mode when it is in memory mode // we have to give up on determining active VFO for Icom rigs // figure out what VFO is current for rigs with 0x25 command static int icom_current_vfo_x25(RIG *rig, vfo_t *vfo) { int freq_offset = 0; freq_t freq_current, freq_other, freq_current_2; vfo_t vfo_current = RIG_VFO_NONE; vfo_t vfo_check = RIG_VFO_A; struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; if (priv->x25cmdfails > 0 && !priv_caps->x25x26_always) { return -RIG_ENAVAIL; } rig_get_freq(rig, RIG_VFO_CURR, &freq_current); rig_get_freq(rig, RIG_VFO_OTHER, &freq_other); if (freq_current == freq_other) { if (priv->vfo_flag != 0) { // we can't change freqs unless rig is idle and we don't know that // so we only check vfo once when freqs are equal rig_debug(RIG_DEBUG_TRACE, "%s: VFO already determined, returning current_vfo %s\n", __func__, rig_strvfo(rs->current_vfo)); *vfo = rs->current_vfo; return RIG_OK; } priv->vfo_flag = 1; freq_offset = 100; rig_set_freq(rig, RIG_VFO_CURR, freq_current + freq_offset); } if (rs->current_vfo == RIG_VFO_B) { vfo_check = RIG_VFO_B; } rig_set_vfo(rig, vfo_check); rig_get_freq(rig, RIG_VFO_CURR, &freq_current_2); if (freq_current_2 == freq_current + freq_offset) // then we are on the vfo_check { vfo_current = vfo_check; } else // the other VFO is the current one { rig_set_vfo(rig, vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A); vfo_current = vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A; } if (freq_offset) // then we need to change freq_current back to original freq { rig_set_freq(rig, RIG_VFO_CURR, freq_current); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_current=%s\n", __func__, rig_strvfo(vfo_current)); *vfo = vfo_current; return RIG_OK; } #endif static int icom_current_vfo_to_vfo_with_band(RIG *rig, vfo_t *vfo_current) { int retval; vfo_t vfo_band; retval = icom_get_vfo(rig, &vfo_band); if (retval != RIG_OK) { return retval; } if (*vfo_current == RIG_VFO_B) { if (vfo_band == RIG_VFO_SUB) { *vfo_current = RIG_VFO_SUB_B; } else { *vfo_current = RIG_VFO_MAIN_B; } } else { if (vfo_band == RIG_VFO_SUB) { *vfo_current = RIG_VFO_SUB_A; } else { *vfo_current = RIG_VFO_MAIN_A; } } return retval; } // figure out what VFO is current static vfo_t icom_current_vfo(RIG *rig) { int retval; int freq_offset = 0; freq_t freq_current, freq_other, freq_current_2; vfo_t vfo_current = RIG_VFO_NONE; vfo_t vfo_check = RIG_VFO_A; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct icom_priv_data *priv = rs->priv; #if 0 // Icom rigs with both Main/Sub receivers and A/B VFOs cannot use the 0x25 command to read Sub receiver frequency if (rs->targetable_vfo & RIG_TARGETABLE_FREQ && !VFO_HAS_MAIN_SUB_A_B_ONLY) { // these newer rigs get special treatment retval = icom_current_vfo_x25(rig, &vfo_current); if (VFO_HAS_MAIN_SUB_ONLY || (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->satmode)) { vfo_current = (vfo_current == RIG_VFO_A) ? RIG_VFO_MAIN : RIG_VFO_SUB; } if (retval == RIG_OK) { return vfo_current; } } #endif if (cachep->ptt) { // don't do this if transmitting -- XCHG would mess it up return rs->current_vfo; } else if (!rig_has_vfo_op(rig, RIG_OP_XCHG)) { // for now we will just set vfoa and be done with it // will take more logic for rigs without XCHG rig_debug(RIG_DEBUG_TRACE, "%s: defaulting to VFOA as no XCHG or x25 available\n", __func__); rig_set_vfo(rig, RIG_VFO_A); return RIG_VFO_A; } rig_get_freq(rig, RIG_VFO_CURR, &freq_current); if (rig_has_vfo_op(rig, RIG_OP_XCHG)) { rig_debug(RIG_DEBUG_TRACE, "%s: Using XCHG to swap\n", __func__); retval = icom_vfo_op(rig, vfo_current, RIG_OP_XCHG); if (retval != RIG_OK) { return rs->current_vfo; } } rig_get_freq(rig, RIG_VFO_CURR, &freq_other); if (rig_has_vfo_op(rig, RIG_OP_XCHG)) { rig_debug(RIG_DEBUG_TRACE, "%s: Using XCHG to swap back\n", __func__); retval = icom_vfo_op(rig, vfo_current, RIG_OP_XCHG); if (retval != RIG_OK) { return rs->current_vfo; } } if (freq_current == freq_other) { if (priv->vfo_flag != 0) { // we can't change freqs unless rig is idle and we don't know that // so we only check vfo once when freqs are equal rig_debug(RIG_DEBUG_TRACE, "%s: vfo already determined...returning current_vfo", __func__); return rs->current_vfo; } priv->vfo_flag = 1; freq_offset = 100; rig_set_freq(rig, RIG_VFO_CURR, freq_current + freq_offset); } if (rs->current_vfo == RIG_VFO_B) { vfo_check = RIG_VFO_B; } rig_set_vfo(rig, vfo_check); rig_get_freq(rig, RIG_VFO_CURR, &freq_current_2); if (freq_current_2 == freq_current + freq_offset) { vfo_current = vfo_check; } else { rig_set_vfo(rig, vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A); vfo_current = vfo_check == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A; } if (freq_offset) // then we need to change freq_current back to original freq { rig_set_freq(rig, RIG_VFO_CURR, freq_current); } if (VFO_HAS_MAIN_SUB_ONLY || (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->satmode)) { vfo_current = (vfo_current == RIG_VFO_A) ? RIG_VFO_MAIN : RIG_VFO_SUB; } else if (VFO_HAS_MAIN_SUB_A_B_ONLY && RIG_IS_IC9700) { // TODO: VFO op XCHG only exchanges Main/Sub, so Sub receiver VFO A/B selection cannot be determined this way retval = icom_current_vfo_to_vfo_with_band(rig, &vfo_current); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo_current=%s\n", __func__, rig_strvfo(vfo_current)); if (vfo_current == RIG_VFO_NONE && rs->current_vfo != RIG_VFO_NONE) { vfo_current = rs->current_vfo; } return vfo_current; } // Some rigs, such as IC-9700, cannot execute 0x25/0x26 commands in satmode static void icom_satmode_fix(RIG *rig, int satmode) { if (RIG_IS_IC9700) { rig_debug(RIG_DEBUG_VERBOSE, "%s: toggling IC-9700 targetable for satmode=%d\n", __func__, satmode); // Modify the copy of targetable_vfo in rig_state only! if (satmode) { STATE(rig)->targetable_vfo = 0; } else { STATE(rig)->targetable_vfo = rig->caps->targetable_vfo; } } } /* * ICOM rig open routine * Detect echo state of USB serial port */ int icom_rig_open(RIG *rig) { int retval, retval_echo, value; int satmode = 0; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; int retry_flag = 1; short retry_save = rp->retry; ENTERFUNC; rp->retry = 0; priv->no_1a_03_cmd = ENUM_1A_03_UNK; rig_debug(RIG_DEBUG_VERBOSE, "%s: %s v%s\n", __func__, rig->caps->model_name, rig->caps->version); if (rs->auto_power_on && priv->poweron == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s asking for power on *****************************************\n", __func__); rig_set_powerstat(rig, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s asking for power on #2 =======================================\n", __func__); priv->poweron = 1; } retry_open: retval_echo = icom_get_usb_echo_off(rig); rig_debug(RIG_DEBUG_TRACE, "%s: echo status result=%d\n", __func__, retval_echo); if (retval_echo == 0 || retval_echo == 1) { retval = RIG_OK; } else if (retval_echo == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to determine Icom echo status -- is rig on and connected?\n", __func__); RETURNFUNC(retval_echo); } else { retval = retval_echo; } if (retval == RIG_OK) // then we know our echo status { // we need to know about dual watch for later use rs->dual_watch = 0; retval = rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, &value); if (retval == RIG_OK) { rs->dual_watch = value; } rig_debug(RIG_DEBUG_VERBOSE, "%s: dual_watch=%d\n", __func__, rs->dual_watch); rig_debug(RIG_DEBUG_TRACE, "%s: echo status known, getting frequency\n", __func__); rp->retry = 0; // rs->current_vfo = icom_current_vfo(rig); // some rigs like the IC7100 still echo when in standby // so asking for freq now should timeout if such a rig freq_t tfreq; retval = rig_get_freq(rig, RIG_VFO_CURR, &tfreq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig error getting frequency retry=%d, err=%s\n", __func__, retry_flag, rigerror(retval)); } } else { rig_debug(RIG_DEBUG_TRACE, "%s: echo status unknown\n", __func__); } if (retval != RIG_OK && priv->poweron == 0 && rs->auto_power_on) { // maybe we need power on? rig_debug(RIG_DEBUG_VERBOSE, "%s trying power on\n", __func__); retval = abs(rig_set_powerstat(rig, 1)); // this is only a fatal error if powerstat is implemented // if not implemented than we're at an error here if (retval != RIG_OK) { rp->retry = retry_save; rig_debug(RIG_DEBUG_ERR, "%s: rig_set_powerstat failed: %s\n", __func__, rigerror(retval)); if (retval == RIG_ENIMPL || retval == RIG_ENAVAIL) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_powerstat not implemented for rig\n", __func__); RETURNFUNC(-RIG_ECONF); } RETURNFUNC(retval); } // Now that we're powered up let's try again retval_echo = icom_get_usb_echo_off(rig); if (retval_echo != 0 && retval_echo != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to determine USB echo status\n", __func__); rp->retry = retry_save; RETURNFUNC(retval_echo); } } else if (retval != RIG_OK) { // didn't ask for power on so let's retry one more time if (retry_flag) { retry_flag = 0; hl_usleep(500 * 1000); // 500ms pause goto retry_open; } rp->retry = retry_save; } priv->poweron = (retval == RIG_OK) ? 1 : 0; if (priv->poweron) { if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { // Getting satmode state updates RX/TX VFOs internally rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } //rs->current_vfo = icom_current_vfo(rig); } #if 0 // do not do this here -- needs to be done when ranges are requested instead as this is very slow icom_get_freq_range(rig); // try get to get rig range capability dynamically #endif rp->retry = retry_save; RETURNFUNC(RIG_OK); } /* * ICOM rig close routine */ int icom_rig_close(RIG *rig) { // Nothing to do yet struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; ENTERFUNC; if (priv->poweron == 0) { RETURNFUNC(RIG_OK); } // nothing to do if (priv->poweron == 1 && rs->auto_power_off) { // maybe we need power off? rig_debug(RIG_DEBUG_VERBOSE, "%s trying power off\n", __func__); int retval = abs(rig_set_powerstat(rig, 0)); // this is only a fatal error if powerstat is implemented // if not implemented than we're at an error here if (retval != RIG_OK && retval != RIG_ENIMPL && retval != RIG_ENAVAIL) { rig_debug(RIG_DEBUG_WARN, "%s: unexpected retval here: %s\n", __func__, rigerror(retval)); rig_debug(RIG_DEBUG_WARN, "%s: rig_set_powerstat failed: =%s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } } RETURNFUNC(RIG_OK); } /* * Set default when vfo == RIG_VFO_NONE * Clients should be setting VFO as 1st things but some don't * So they will get defaults of Main/VFOA as the selected VFO * and we force that selection */ static int icom_set_default_vfo(RIG *rig) { int retval; struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s: called, curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); // we need to know if dual watch is on if (VFO_HAS_MAIN_SUB_A_B_ONLY) { rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN/VFOA\n", __func__); HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case if (retval != RIG_OK) { RETURNFUNC2(retval); } HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_A); // we'll default to Main in this case if (retval != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = RIG_VFO_MAIN; RETURNFUNC2(RIG_OK); } if (VFO_HAS_MAIN_SUB_ONLY) { rig_debug(RIG_DEBUG_TRACE, "%s: setting default as MAIN\n", __func__); HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_MAIN); // we'll default to Main in this case rs->current_vfo = RIG_VFO_MAIN; } else if (VFO_HAS_A_B) { rig_debug(RIG_DEBUG_TRACE, "%s: setting default as VFOA\n", __func__); HAMLIB_TRACE; retval = RIG_OK; if (rs->current_vfo != RIG_VFO_A) { retval = rig_set_vfo(rig, RIG_VFO_A); // we'll default to VFOA for all others rs->current_vfo = RIG_VFO_A; } } else { // we don't have any VFO selection rig_debug(RIG_DEBUG_TRACE, "%s: Unknown VFO setup so setting default as VFOA\n", __func__); rs->current_vfo = RIG_VFO_A; retval = RIG_OK; } if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo now %s\n", __func__, rig_strvfo(rs->current_vfo)); RETURNFUNC2(RIG_OK); } // return true if band is changing from last set_freq // Assumes rig is currently on the VFO being changed // This handles the case case Main/Sub cannot be on the same band int icom_band_changing(RIG *rig, freq_t test_freq) { freq_t curr_freq, freq1, freq2; int retval; ENTERFUNC2; // We should be sitting on the VFO we want to change so just get it's frequency retval = rig_get_freq(rig, RIG_VFO_CURR, &curr_freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_freq failed??\n", __func__); RETURNFUNC2(0); // I guess we need to say no change in this case } // Make our HF=0, 2M = 1, 70cm = 4, and 23cm=12 freq1 = floor(curr_freq / 1e8); freq2 = floor(test_freq / 1e8); rig_debug(RIG_DEBUG_TRACE, "%s: lastfreq=%.0f, thisfreq=%.0f\n", __func__, freq1, freq2); if (freq1 != freq2) { rig_debug(RIG_DEBUG_TRACE, "%s: Band change detected\n", __func__); RETURNFUNC2(1); } rig_debug(RIG_DEBUG_TRACE, "%s: Band change not detected\n", __func__); RETURNFUNC2(0); } static int icom_set_freq_x25(RIG *rig, vfo_t vfo, freq_t freq, int freq_len, unsigned char *freqbuf) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int retval; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || (priv->x25cmdfails > 0 && !priv_caps->x25x26_always)) { return -RIG_ENAVAIL; } int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); retval = icom_transaction(rig, C_SEND_SEL_FREQ, vfo_number, freqbuf, freq_len, ackbuf, &ack_len); if (priv->x25cmdfails < 0 || priv_caps->x25x26_always) { priv->x25cmdfails = (retval == RIG_OK) ? 0 : 1; } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { return retval; } return retval; } static int icom_get_freq_x25(RIG *rig, vfo_t vfo, int *ack_len, unsigned char *ackbuf, int *freqbuf_offset) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; // Rigs like IC-7600, IC-7700, IC-7800 and IC-7100 have new firmware that implements commands 0x25 and 0x26 // So if this succeeds we'll assume all such rigs are targetable freq & mode if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || (priv->x25cmdfails > 0 && !priv_caps->x25x26_always)) { return -RIG_ENAVAIL; } // Attempt to use the 0x25 command to get selected/unselected or Main/Sub VFO frequency directly // For the rigs that indicate selected/unselected VFO frequency, assume current_vfo is accurate to determine what "selected" means int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); retval = icom_transaction(rig, C_SEND_SEL_FREQ, vfo_number, NULL, 0, ackbuf, ack_len); if (retval == RIG_OK) { *freqbuf_offset = 2; } if (priv->x25cmdfails < 0 || priv_caps->x25x26_always) { priv->x25cmdfails = (retval == RIG_OK) ? 0 : 1; } return retval; } static int icom_get_tx_freq(RIG *rig, int *ack_len, unsigned char *ackbuf, int *freqbuf_offset) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; if (priv->x1cx03cmdfails > 0 && !priv_caps->x1cx03_always) { return -RIG_ENAVAIL; } retval = icom_transaction(rig, C_CTL_PTT, S_RD_TX_FREQ, NULL, 0, ackbuf, ack_len); if (retval == RIG_OK) { *freqbuf_offset = 2; } if (priv->x1cx03cmdfails < 0 || priv_caps->x1cx03_always) { priv->x1cx03cmdfails = (retval == RIG_OK) ? 0 : 1; } return retval; } /* * icom_set_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; unsigned char freqbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int freq_len, ack_len = sizeof(ackbuf), retval; int check_ack = 0; int cmd, subcmd = -1; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; freq_t curr_freq; ENTERFUNC2; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s=%" PRIfreq "\n", __func__, rig_strvfo(vfo), freq); // Icom 0x25 command can only manipulate VFO A/B *or* VFO Main/Sub frequencies. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver frequencies must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || force_vfo_swap) { // Switch to the desired VFO (if needed) if frequency is not targetable HAMLIB_TRACE; rig_debug(RIG_DEBUG_TRACE, "%s: set_vfo_curr=%s\n", __func__, rig_strvfo(rs->current_vfo)); retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } retval = rig_get_freq(rig, vfo, &curr_freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } freq_len = priv->civ_731_mode ? 4 : 5; if (RIG_IS_IC905) { // > 5.85GHz is 6 bytes if (freq > 5.85e9) { freq_len = 6; } } to_bcd(freqbuf, freq, freq_len * 2); if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && !force_vfo_swap) { cmd = C_SEND_SEL_FREQ; subcmd = icom_get_vfo_number_x25x26(rig, vfo); retval = icom_set_freq_x25(rig, vfo, freq, freq_len, freqbuf); } if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || retval == -RIG_ENAVAIL || force_vfo_swap) { cmd = C_SET_FREQ; subcmd = -1; #if 0 if (CACHE(rig)->ptt && (ICOM_IS_ID5100 || ICOM_IS_ID4100 || ICOM_IS_ID31 || ICOM_IS_ID51)) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): ID55100 0x00\n", __func__, __LINE__); // for these rigs 0x00 is setting the freq and 0x03 is just for reading cmd = 0x00; // temporary fix for ID5100 not giving ACK/NAK on 0x00 freq on E8 firmware retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_freq failed: %s\n", __func__, rigerror(retval)); return retval; } return RIG_OK; } else #endif { retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf, &ack_len); } int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } check_ack = 1; } if (retval != RIG_OK) { // We might have a failed command if we're changing bands // For example, IC-9700 setting Sub=VHF when Main=VHF will fail // So we'll try a VFO swap and see if that helps things rig_debug(RIG_DEBUG_VERBOSE, "%s: special check for vfo swap\n", __func__); if (icom_band_changing(rig, freq)) { if (rig_has_vfo_op(rig, RIG_OP_XCHG)) { retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: vfo_op XCHG failed: %s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } // Try the command again retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, ackbuf, &ack_len); // Swap back if we got an error otherwise we fall through for more processing if (retval != RIG_OK) { int retval2; rig_debug(RIG_DEBUG_ERR, "%s: 2nd set freq failed: %s\n", __func__, rigerror(retval)); retval2 = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval2 != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: 2nd vfo_op XCHG failed: %s\n", __func__, rigerror(retval2)); RETURNFUNC2(retval2); } RETURNFUNC2(retval); } check_ack = 1; } } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set freq failed: %s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } } if (check_ack && (retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } if (priv->tone_enable) { // IC-705 as of 2024-02-01 turn off TONE on freq change so we turn it back on if enabled rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TONE, 1); } RETURNFUNC2(RIG_OK); } /* * icom_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL, Main=VFOA, Sub=VFOB * Note: old rig may return less than 4/5 bytes for get_freq */ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; unsigned char freqbuf[MAXFRAMELEN]; int freq_len = sizeof(freqbuf); int freqbuf_offset = 1; int retval = RIG_OK; int civ_731_mode_save = 0; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); if (priv->serial_USB_echo_off == -1) { icom_get_usb_echo_off(rig); } if (vfo == RIG_VFO_MEM && (priv->civ_731_mode || RIG_IS_IC706)) { // Memory channels have always 5-byte frequqncy rig_debug(RIG_DEBUG_TRACE, "%s: VFO=MEM so turning off civ_731\n", __func__); civ_731_mode_save = 1; priv->civ_731_mode = 0; } // Pick the appropriate VFO when VFO_TX is requested if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: VFO_TX requested, vfo=%s\n", __func__, rig_strvfo(vfo)); // Attempt to read the transmit frequency directly to avoid VFO swapping retval = icom_get_tx_freq(rig, &freq_len, freqbuf, &freqbuf_offset); if (retval == RIG_OK) { *freq = from_bcd(&freqbuf[freqbuf_offset], (priv->civ_731_mode ? 4 : 5) * 2); if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return retval; } // Fix VFO if the TX freq command is not available if (CACHE(rig)->split != RIG_SPLIT_OFF) { vfo = rs->tx_vfo; } else { vfo = rs->current_vfo; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: using vfo=%s\n", __func__, rig_strvfo(vfo)); // Icom 0x25 command can only manipulate VFO A/B *or* VFO Main/Sub frequencies. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver frequencies must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && !force_vfo_swap) { retval = icom_get_freq_x25(rig, vfo, &freq_len, freqbuf, &freqbuf_offset); if (freq_len == 3 && freqbuf[2] == 0xff) { // then we are in VFO mode *freq = 0; return RIG_OK; } if (retval == RIG_OK) { // 0x25 cmd is 1 byte longer than 0x03 cmd freq_len--; } } // If the command 0x25 is not supported, swap VFO (if required) and read the frequency if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) || retval == -RIG_ENAVAIL || force_vfo_swap) { freqbuf_offset = 1; HAMLIB_TRACE; retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return retval; } for (int i = 0; i < 2; ++i) { retval = icom_transaction(rig, C_RD_FREQ, -1, NULL, 0, freqbuf, &freq_len); HAMLIB_TRACE; if (freqbuf[4] == C_RD_FREQ) { break; } } int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } if (retval != RIG_OK) { if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return retval; } /* * freqbuf should contain Cn,Data area */ freq_len--; /* * is it a blank mem channel ? */ if (freq_len == 1 && freqbuf[1] == 0xff) { *freq = RIG_FREQ_NONE; if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } return RIG_OK; } if (freq_len == 3 && (ICOM_IS_ID5100 || ICOM_IS_ID4100 || ICOM_IS_ID31 || ICOM_IS_ID51)) { rig_debug(RIG_DEBUG_ERR, "%s: 3-byte ID5100/4100 length - turn off XONXOFF flow control\n", __func__); } else if (freq_len != 4 && freq_len != 5 && freq_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, freq_len); if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } if (freq_len == 1 && vfo == RIG_VFO_MEM) { *freq = 0; rig_debug(RIG_DEBUG_ERR, "%s: Rig is in MEM mode and MEM channel is empty\n", __func__); return -RIG_ETRUNC; } return -RIG_ENAVAIL; } if (freq_len != 3 && freq_len != 6 && freq_len != (priv->civ_731_mode ? 4 : 5)) { rig_debug(RIG_DEBUG_WARN, "%s: freq len (%d) differs from expected\n", __func__, freq_len); } *freq = from_bcd(freqbuf + freqbuf_offset, freq_len * 2); // 3-byte freq for ID5100 is in 10000Hz units so convert to Hz if (freq_len == 3) { *freq *= 10000; } if (vfo == RIG_VFO_MEM && civ_731_mode_save) { priv->civ_731_mode = 1; } rig_debug(RIG_DEBUG_VERBOSE, "%s exit vfo=%s, curr_vfo=%s, freq=%g\n", __func__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo), *freq); RETURNFUNC2(RIG_OK); } int icom_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *ts) { unsigned char tsbuf[MAXFRAMELEN]; int ts_len, retval; retval = icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, NULL, 0, tsbuf, &ts_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } /* * tsbuf nibbles should contain 10,1,1000,100 hz digits and 00=+, 01=- bit */ rig_debug(RIG_DEBUG_VERBOSE, "%s: ts_len=%d\n", __func__, ts_len); if (ts_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len); RETURNFUNC2(-RIG_ERJCTED); } *ts = (shortfreq_t) from_bcd(tsbuf + 2, 4); if (tsbuf[4] != 0) { *ts *= -1; } RETURNFUNC2(RIG_OK); } // The Icom rigs have only one register for both RIT and Delta TX // you can turn one or both on -- but both end up just being in sync. static int icom_set_it_new(RIG *rig, vfo_t vfo, shortfreq_t ts, int set_xit) { unsigned char tsbuf[8]; unsigned char ackbuf[16]; int ack_len; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: ts=%d\n", __func__, (int) ts); to_bcd(tsbuf, abs((int) ts), 4); // set sign bit tsbuf[2] = (ts < 0) ? 1 : 0; retval = icom_transaction(rig, C_CTL_RIT, S_RIT_FREQ, tsbuf, 3, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } int icom_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t ts) { RETURNFUNC2(icom_set_it_new(rig, vfo, ts, 0)); } int icom_set_xit_new(RIG *rig, vfo_t vfo, shortfreq_t ts) { RETURNFUNC2(icom_set_it_new(rig, vfo, ts, 1)); } /* icom_get_dsp_flt returns the dsp filter width in hz or 0 if the command is not implemented or error. This allows the default parameters to be assigned from the get_mode routine if the command is not implemented. Assumes rig != null and the current mode is in mode. Has been tested for IC-746pro, Should work on the all dsp rigs ie pro models. The 746 documentation says it has the get_if_filter, but doesn't give any decoding information ? Please test. DSP filter setting ($1A$03), but not supported by every rig, and some models like IC910/Omni VI Plus have a different meaning for this subcommand */ int filtericom[] = { 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300, 3400, 3500, 3600 }; pbwidth_t icom_get_dsp_flt(RIG *rig, rmode_t mode) { int retval, res_len = 0, rfstatus; unsigned char resbuf[MAXFRAMELEN]; value_t rfwidth; unsigned char fw_sub_cmd = RIG_IS_IC7200 ? 0x02 : S_MEM_FILT_WDTH; struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=%s\n", __func__, rig_strrmode(mode)); memset(resbuf, 0, sizeof(resbuf)); if (rig_has_get_func(rig, RIG_FUNC_RF) && (mode & (RIG_MODE_RTTY | RIG_MODE_RTTYR))) { if (!rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_RF, &rfstatus) && (rfstatus)) { retval = rig_get_ext_parm(rig, TOK_RTTY_FLTR, &rfwidth); if (retval != RIG_OK || rfwidth.i >= RTTY_FIL_NB) { return (0); /* use default */ } else { return (rtty_fil[rfwidth.i]); } } } // TODO: Skip for Xiegu G90 too???? if (RIG_MODEL_X108G == rig->caps->rig_model || RIG_MODEL_X5105 == rig->caps->rig_model || RIG_MODEL_G90 == rig->caps->rig_model) { priv->no_1a_03_cmd = ENUM_1A_03_NO; } if (priv->no_1a_03_cmd == ENUM_1A_03_NO) { return (0); } retval = icom_transaction(rig, C_CTL_MEM, fw_sub_cmd, 0, 0, resbuf, &res_len); if (-RIG_ERJCTED == retval && !RIG_IS_IC7300) { if (priv->no_1a_03_cmd == ENUM_1A_03_UNK) { priv->no_1a_03_cmd = ENUM_1A_03_NO; /* do not keep asking */ return (RIG_OK); } else { rig_debug(RIG_DEBUG_ERR, "%s: 1a 03 cmd failed\n", __func__); return (retval); } } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return (RIG_OK); /* use default */ } if (res_len == 3 && resbuf[0] == C_CTL_MEM) { int i; i = (int) from_bcd(resbuf + 2, 2); rig_debug(RIG_DEBUG_TRACE, "%s: i=%d, [0]=%02x, [1]=%02x, [2]=%02x, [3]=%02x\n", __func__, i, resbuf[0], resbuf[1], resbuf[2], resbuf[3]); if (mode & RIG_MODE_AM) { if (i > 49) { rig_debug(RIG_DEBUG_ERR, "%s: Expected max 49, got %d for filter\n", __func__, i); RETURNFUNC2(-RIG_EPROTO); } return ((i + 1) * 200); /* All Icoms that we know of */ } else if (mode & (RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB)) { rig_debug(RIG_DEBUG_TRACE, "%s: using filtericom width=%d\n", __func__, i); if (i > sizeof(filtericom) / sizeof(int)) { i = 40; } RETURNFUNC2(filtericom[i]); } } RETURNFUNC2(RIG_OK); } int icom_set_dsp_flt(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval, rfstatus; unsigned char ackbuf[MAXFRAMELEN]; unsigned char flt_ext; value_t rfwidth; int ack_len = sizeof(ackbuf), flt_idx; struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; unsigned char fw_sub_cmd = RIG_IS_IC7200 ? 0x02 : S_MEM_FILT_WDTH; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: mode=%s, width=%d\n", __func__, rig_strrmode(mode), (int)width); if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC(RIG_OK); } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } // TODO: Rename RIG_FUNC_RF to RIG_FUNC_RTTYFLT ? AMBIGUOUS! if (rig_has_get_func(rig, RIG_FUNC_RF) && (mode & (RIG_MODE_RTTY | RIG_MODE_RTTYR))) { if (!rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_RF, &rfstatus) && (rfstatus)) { int i; for (i = 0; i < RTTY_FIL_NB; i++) { if (rtty_fil[i] == width) { rfwidth.i = i; RETURNFUNC(rig_set_ext_parm(rig, TOK_RTTY_FLTR, rfwidth)); } } /* not found */ RETURNFUNC(-RIG_EINVAL); } } if (priv->no_1a_03_cmd == ENUM_1A_03_NO) { RETURNFUNC(RIG_OK); } // don't bother to try since it doesn't work if (mode & RIG_MODE_AM) { flt_idx = (width / 200) - 1; /* TBC: IC_7800? */ } else if (mode & (RIG_MODE_CW | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB)) { if (width == 0) { width = 1; } flt_idx = width <= 500 ? ((width + 49) / 50) - 1 : ((width + 99) / 100) + 4; if (flt_idx > 40) { flt_idx = 40; } } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(RIG_OK); } to_bcd(&flt_ext, flt_idx, 2); rig_debug(RIG_DEBUG_VERBOSE, "%s: flt_ext=%d, flt_idx=%d\n", __func__, flt_ext, flt_idx); retval = icom_transaction(rig, C_CTL_MEM, fw_sub_cmd, &flt_ext, 1, ackbuf, &ack_len); if (-RIG_ERJCTED == retval) { if (priv->no_1a_03_cmd == ENUM_1A_03_UNK) { priv->no_1a_03_cmd = ENUM_1A_03_NO; /* do not keep asking */ RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_ERR, "%s: 1A 03 %02x failed\n", __func__, flt_ext); RETURNFUNC(retval); } } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC(retval); } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: command not supported ? (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_mode_without_data * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int icom_set_mode_without_data(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; const struct icom_priv_data *priv_data = (const struct icom_priv_data *) rs->priv; unsigned char ackbuf[MAXFRAMELEN]; unsigned char icmode; signed char icmode_ext; int ack_len = sizeof(ackbuf); int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, mode=%s, width=%d, current_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int) width, rig_strvfo(rs->current_vfo)); // We can assume here that mode is not targetable and that VFO swapping has been performed if (priv_caps->r2i_mode != NULL) { retval = priv_caps->r2i_mode(rig, vfo, mode, width, &icmode, &icmode_ext); } else { retval = rig2icom_mode(rig, vfo, mode, width, &icmode, &icmode_ext); } if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error on rig2icom_mode, result=%d\n", __func__, retval); RETURNFUNC2(retval); } if (width == RIG_PASSBAND_NOCHANGE) { icmode_ext = priv_data->filter; } rig_debug(RIG_DEBUG_VERBOSE, "%s: icmode=%d, icmode_ext=%d\n", __func__, icmode, icmode_ext); /* 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_IS_OS456 || RIG_IS_IC375 || RIG_IS_IC726 || RIG_IS_IC475 || RIG_IS_IC746 || RIG_IS_IC746PRO || RIG_IS_IC756 || RIG_IS_IC756PROII || RIG_IS_IC756PROIII || RIG_IS_IC910 || RIG_IS_IC7000) { icmode_ext = -1; } rig_debug(RIG_DEBUG_VERBOSE, "%s: #2 icmode=%d, icmode_ext=%d\n", __func__, icmode, icmode_ext); retval = icom_transaction(rig, C_SET_MODE, icmode, (unsigned char *) &icmode_ext, (icmode_ext == -1 ? 0 : 1), ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } icom_set_dsp_flt(rig, vfo, mode, width); RETURNFUNC2(RIG_OK); } static int icom_get_mode_x26(RIG *rig, vfo_t vfo, int *mode_len, unsigned char *modebuf) { struct icom_priv_data *priv = STATE(rig)->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; if (priv->x26cmdfails > 0 && priv_caps->x25x26_always == 0) { rig_debug(RIG_DEBUG_WARN, "%s: x26cmdfails=%d, x25x26_always=%d\n", __func__, priv->x26cmdfails, priv_caps->x25x26_always); return -RIG_ENAVAIL; } int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, vfo_number=%d\n", __func__, rig_strvfo(vfo), vfo_number); retval = icom_transaction(rig, C_SEND_SEL_MODE, vfo_number, NULL, 0, modebuf, mode_len); if (priv->x26cmdfails < 0 || priv_caps->x25x26_always) { priv->x26cmdfails = (retval == RIG_OK) ? 0 : 1; } if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: mode_len=%d, modebuf=%02x %02x %02x %02x %02x\n", __func__, *mode_len, modebuf[0], modebuf[1], modebuf[2], modebuf[3], modebuf[4]); priv->filter = modebuf[4]; return RIG_OK; } static int icom_set_mode_x26(RIG *rig, vfo_t vfo, rmode_t mode, rmode_t icom_mode, int datamode, int filter, pbwidth_t width) { struct icom_priv_data *priv = STATE(rig)->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; int retval; unsigned char buf[3]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int buf_len = 3; int mode_len; unsigned char mode_buf[4]; if (priv->x26cmdfails > 0 && !priv_caps->x25x26_always) { return -RIG_ENAVAIL; } icom_get_mode_x26(rig, vfo, &mode_len, mode_buf); buf[0] = icom_mode; buf[1] = datamode; // Skip filter selection, because at least IC-7300 has a bug defaulting to filter 2 when changing mode // Tested on IC-7300 and IC-9700 buf[2] = priv->filter; if (mode == RIG_MODE_FM || mode == RIG_MODE_WFM) { // we use the passed in filter for FM mode widths buf[2] = filter; } //rig_debug(RIG_DEBUG_TRACE, "%s: mode=%ld, filters usbd=%d, usb=%d, cw=%d\n", // __func__, mode, priv->filter_usbd, priv->filter_usb, priv->filter_cw); if (priv->filter_usbd > 0 && (mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB)) { rig_debug(RIG_DEBUG_TRACE, "%s: filter usbd=%d, width=%d\n", __func__, priv->filter_usbd, (int)width); buf[2] = priv->filter_usbd; if (width >= 1 && width <= 3) { buf[2] = width; } if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } else if (priv->filter_usb > 0 && (mode == RIG_MODE_USB || mode == RIG_MODE_LSB)) { rig_debug(RIG_DEBUG_TRACE, "%s: filter usb=%d\n", __func__, priv->filter_usb); buf[2] = priv->filter_usb; if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } else if (priv->filter_cw > 0 && (mode == RIG_MODE_CW || mode == RIG_MODE_CWR)) { rig_debug(RIG_DEBUG_TRACE, "%s: filter cw=%d\n", __func__, priv->filter_cw); buf[2] = priv->filter_cw; if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } else if (mode == RIG_MODE_FM || mode == RIG_MODE_PKTFM) { rig_debug(RIG_DEBUG_TRACE, "%s: width=%d\n", __func__, (int)width); buf[2] = width; if (width > 10000) { buf[2] = 1; } else if (width > 7000) { buf[2] = 2; } else if (width > 3) { buf[2] = 3; } if (width == RIG_PASSBAND_NOCHANGE) { buf_len = 1; } } int vfo_number = icom_get_vfo_number_x25x26(rig, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, vfo_number=%d\n", __func__, rig_strvfo(vfo), vfo_number); // allow width of 1,2,3 to set explicit filter if (width >= 1 && width <= 3) { buf[2] = width; } retval = icom_transaction(rig, C_SEND_SEL_MODE, vfo_number, buf, buf_len, ackbuf, &ack_len); if (priv->x26cmdfails < 0 || priv_caps->x25x26_always) { priv->x26cmdfails = (retval == RIG_OK) ? 0 : 1; } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { return retval; } return RIG_OK; } /* * icom_set_mode */ int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct rig_state *rs = STATE(rig); const struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int retval; rmode_t base_mode; rmode_t current_mode; pbwidth_t current_width; int is_data_mode = 0; unsigned char dm_sub_cmd = RIG_IS_IC7200 ? 0x04 : S_MEM_DATA_MODE; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; ENTERFUNC; // Icom 0x26 command can only manipulate VFO A/B *or* VFO Main/Sub modes. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver modes must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!priv_caps->data_mode_supported) { // Use legacy command to set mode if data mode is not supported retval = icom_set_mode_without_data(rig, vfo, mode, width); if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } RETURNFUNC(retval); } // Do nothing if current mode and width is not changing // Reading mode also sets priv->filter to current filter choice retval = rig_get_mode(rig, vfo, ¤t_mode, ¤t_width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } switch (mode) { case RIG_MODE_PKTUSB: base_mode = RIG_MODE_USB; is_data_mode = 1; break; case RIG_MODE_PKTLSB: base_mode = RIG_MODE_LSB; is_data_mode = 1; break; case RIG_MODE_PKTFM: base_mode = RIG_MODE_FM; is_data_mode = 1; break; case RIG_MODE_PKTAM: base_mode = RIG_MODE_AM; is_data_mode = 1; break; default: base_mode = mode; break; } rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d, width=%d, current_vfo=%s\n", __func__, (int) base_mode, (int) width, rig_strvfo(rs->current_vfo)); // It is only necessary to change base mode if command 0x26 is not supported if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { retval = icom_set_mode_without_data(rig, vfo, base_mode, width); } else { retval = RIG_OK; } if (retval == RIG_OK && (mode != current_mode || width != RIG_PASSBAND_NOCHANGE)) { unsigned char datamode[2]; unsigned char mode_icom; // Not used, we only need the width signed char width_icom; HAMLIB_TRACE; datamode[0] = is_data_mode ? 0x01 : 0x00; // Do not change the current filter datamode[1] = priv->filter; if (priv_caps->r2i_mode != NULL) { retval = priv_caps->r2i_mode(rig, vfo, mode, width, &mode_icom, &width_icom); } else { retval = rig2icom_mode(rig, vfo, mode, width, &mode_icom, &width_icom); } if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error on rig2icom_mode, result=%d\n", __func__, retval); RETURNFUNC(retval); } // Check if the filter width byte is needed if (priv_caps->mode_with_filter) { HAMLIB_TRACE; // allow 1,2,3 values to set filter number if (width >= 1 && width <= 3) { datamode[1] = width; } if (datamode[0] == 0) { datamode[1] = 0; } // the only good combo possible according to manual // we need to let FM mode widths through here with datamode[1] set to FM width if ((priv_caps->fm_filters[0] != 0) && (mode == RIG_MODE_FM || mode == RIG_MODE_WFM)) { // assumed fm_filters is ascending sequence -- see ic7300.c for example if (width >= 1 && width <= 3) { datamode[1] = width; } else if (width <= priv_caps->fm_filters[0]) { datamode[1] = 3; } else if (width <= priv_caps->fm_filters[1]) { datamode[1] = 2; } else { datamode[1] = 1; } if (width > 3) { rig_debug(RIG_DEBUG_WARN, "%s: IC7300 width set by 1,2,3 - adjustable width not implemented yet\n", __func__); } } rig_debug(RIG_DEBUG_TRACE, "%s(%d) mode_icom=%d, datamode=%d, filter=%d\n", __func__, __LINE__, mode_icom, datamode[0], datamode[1]); if (force_vfo_swap) { retval = -RIG_ENAVAIL; } else { if (datamode[0] == 0) { datamode[1] = 0; } retval = icom_set_mode_x26(rig, vfo, mode, mode_icom, datamode[0], datamode[1], width); } if (retval != RIG_OK) { HAMLIB_TRACE; retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 2, ackbuf, &ack_len); } } else { HAMLIB_TRACE; retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, datamode, 1, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); } else { if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: command not supported ? (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); } } } } // no change and not setting filter number either if (width <= 3) { rig_debug(RIG_DEBUG_TRACE, "%s: setting filter=%d\n", __func__, (int)width); RETURNFUNC(RIG_OK); } if (((width != RIG_PASSBAND_NOCHANGE) && (width != current_width)) || (priv->filter_usbd > 0 || priv->filter_usb > 0 || priv->filter_cw > 0 || priv->filter_fm > 0)) { icom_set_dsp_flt(rig, vfo, mode, width); } else { rig_debug(RIG_DEBUG_TRACE, "%s: width not changing, keeping filter selection\n", __func__); } int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } RETURNFUNC(retval); } /* * icom_get_mode_without_data * Assumes rig!=NULL, STATE(rig)->priv!=NULL, mode!=NULL, width!=NULL * * TODO: IC-781 doesn't send filter width in wide filter mode, making the frame 1 byte short. */ static int icom_get_mode_without_data(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width, int force_vfo_swap) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv_data = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char modebuf[MAXFRAMELEN]; int mode_len; int retval; ENTERFUNC2; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); *width = 0; HAMLIB_TRACE; // Use command 0x26 to get selected/unselected or Main/Sub VFO mode, data mode and filter width // IC-7800 can set, but not read with 0x26 (although manual states otherwise?) if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && !RIG_IS_IC7800 && !force_vfo_swap) { retval = icom_get_mode_x26(rig, vfo, &mode_len, modebuf); if (retval == RIG_OK) { // mode_len=5, modebuf=26 01 01 01 01 // last 3 bytes are mode, datamode, filter (1-3) priv_data->datamode = modebuf[3]; *width = priv_data->filter = modebuf[4]; modebuf[1] = modebuf[2]; // copy mode to 2-byte format modebuf[2] = modebuf[4]; // copy filter to 2-byte format mode_len = 2; } else if (retval == -RIG_ENAVAIL) // In case it's been disabled { retval = icom_transaction(rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len); } } else { retval = icom_transaction(rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len); } if (--mode_len == 3) { // cppcheck-suppress redundantAssignment priv_data->filter = modebuf[2]; rig_debug(RIG_DEBUG_TRACE, "%s(%d): modebuf[0]=0x%02x, modebuf[1]=0x%02x, modebuf[2]=0x%02x, mode_len=%d, filter=%d\n", __func__, __LINE__, modebuf[0], modebuf[1], modebuf[2], mode_len, priv_data->filter); } else { priv_data->filter = 1; if (mode_len == 2) { priv_data->filter = modebuf[1]; } rig_debug(RIG_DEBUG_TRACE, "%s(%d): modebuf[0]=0x%02x, modebuf[1]=0x%02x, mode_len=%d\n", __func__, __LINE__, modebuf[0], modebuf[1], mode_len); } if (retval != RIG_OK) { RETURNFUNC2(retval); } /* * modebuf should contain Cn,Data area */ if (mode_len != 2 && mode_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, mode_len); RETURNFUNC2(-RIG_ERJCTED); } if (priv_caps->i2r_mode != NULL) { priv_caps->i2r_mode(rig, modebuf[1], mode_len == 2 ? modebuf[2] : -1, mode, width); } else { // we use width to pass in FM width for some rigs to i2r_mode icom2rig_mode(rig, modebuf[1], mode_len == 2 ? modebuf[2] : -1, mode, width); } if ((RIG_IS_IC7300 || RIG_IS_IC9700) && (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM)) { // we already have width from icom2rig_mode RETURNFUNC2(RIG_OK); } // The following rigs do not support querying filter width if ((RIG_IS_IC910) || (RIG_IS_OMNIVIP) || (RIG_IS_IC706) || (RIG_IS_IC706MKII) || (RIG_IS_IC706MKIIG) || (RIG_IS_IC756) || (RIG_IS_IC756PROII) || (RIG_IS_IC756PROIII) || (RIG_IS_ICR30)) { RETURNFUNC2(RIG_OK); } /** * Most rigs return 1-wide, 2-normal, 3-narrow * * For DSP rigs these are presets that can be programmed for 30 - 41 bandwidths, depending on mode. * * The DSP filter width can be read only for the selected VFO, so use cached width for other VFOs. */ pbwidth_t filter_width = 1; if (vfo == rs->current_vfo) { if (!((RIG_IS_IC7300 || RIG_IS_IC9700) && (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM))) // can't do this in FM mode { filter_width = icom_get_dsp_flt(rig, *mode); } } else { freq_t freq_cached; rmode_t mode_cached; pbwidth_t width_cached = 0; int cache_ms_freq, cache_ms_mode, cache_ms_width; rig_get_cache(rig, vfo, &freq_cached, &cache_ms_freq, &mode_cached, &cache_ms_mode, &width_cached, &cache_ms_width); filter_width = width_cached; } *width = filter_width; if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 12000; // some default to 12000 if (RIG_IS_IC7300 || RIG_IS_IC9700) { if (priv_data->filter == 1) { *width = 15000; } else if (priv_data->filter == 2) { *width = 10000; } else if (priv_data->filter == 3) { *width = 7000; } } } RETURNFUNC2(RIG_OK); } /* * icom_get_mode */ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char databuf[MAXFRAMELEN]; int data_len, retval; unsigned char dm_sub_cmd = RIG_IS_IC7200 ? 0x04 : S_MEM_DATA_MODE; int force_vfo_swap = 0; vfo_t vfo_save = rs->current_vfo; ENTERFUNC2; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); // Icom 0x26 command can only manipulate VFO A/B *or* VFO Main/Sub modes. // With (usually satellite-capable) rigs that have Main/Sub + A/B for each, // Sub receiver modes must be manipulated using non-targetable commands. if (VFO_HAS_MAIN_SUB_A_B_ONLY && (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B)) { force_vfo_swap = 1; } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { retval = set_vfo_curr(rig, vfo, rs->current_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } retval = icom_get_mode_without_data(rig, vfo, mode, width, force_vfo_swap); if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s mode=%d\n", __func__, (int) *mode); // Do not query data mode state for rigs that do not support them if (!priv_caps->data_mode_supported) { if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } RETURNFUNC2(retval); } switch (*mode) { case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_AM: case RIG_MODE_FM: // Check data mode state for the modes above if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && !force_vfo_swap) { // The data mode state is already read using command 0x26 for rigs with targetable mode // Fake the response in databuf databuf[2] = priv->datamode; data_len = 3; } else { retval = icom_transaction(rig, C_CTL_MEM, dm_sub_cmd, 0, 0, databuf, &data_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), len=%d\n", __func__, databuf[0], data_len); RETURNFUNC2(-RIG_ERJCTED); } } /* * databuf should contain Cn,Sc,D0[,D1] */ data_len -= 2; if (data_len < 1 || data_len > 2) { /* manual says 1 byte answer but at least IC756 ProIII sends 2 - second byte appears to be same as second byte from 04 command which is filter preset number, whatever it is we ignore it */ rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, data_len); RETURNFUNC2(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_VERBOSE, "%s databuf[2]=%d, mode=%d\n", __func__, (int)databuf[2], (int)*mode); // 0x01/0x02/0x03 -> data mode, 0x00 -> not data mode if (databuf[2]) { switch (*mode) { case RIG_MODE_USB: *mode = RIG_MODE_PKTUSB; break; case RIG_MODE_LSB: *mode = RIG_MODE_PKTLSB; break; case RIG_MODE_AM: *mode = RIG_MODE_PKTAM; break; case RIG_MODE_FM: *mode = RIG_MODE_PKTFM; break; default: break; } } default: break; } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) || force_vfo_swap) { int retval2 = set_vfo_curr(rig, vfo_save, rs->current_vfo); if (retval == RIG_OK) { retval = retval2; } } RETURNFUNC2(retval); } /* * icom_get_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Only some recent Icom rigs support reading the selected band (between Main/Sub). * Even then, they cannot distinguish between VFO A/B. * * Supported rigs so far: IC-7600 (firmware version 2.0+), IC-7610, IC-7800 (firmware version 3.1+), IC-785x * While IC-9700 supports the command too, it provides Main A/B and Sub A/B VFOs too, where A/B selection * cannot be detected. */ int icom_get_vfo(RIG *rig, vfo_t *vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; // TODO: Detect if the command is available for IC-7600 and IC-7800 // -> If not, return cached or -RIG_ENAVAIL? retval = icom_transaction(rig, C_SET_VFO, S_BAND_SEL, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error reading receiver/band selection: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (ackbuf[2] == 0) { *vfo = RIG_VFO_MAIN; } else { *vfo = RIG_VFO_SUB; } RETURNFUNC(RIG_OK); } /* * icom_set_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_vfo(RIG *rig, vfo_t vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), icvfo, retval; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: Asking for currVFO, currVFO=%s\n", __func__, rig_strvfo(rs->current_vfo)); RETURNFUNC2(RIG_OK); } if (vfo == RIG_VFO_MAIN && VFO_HAS_A_B_ONLY) { vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Main changed to %s\n", __func__, rig_strvfo(vfo)); } else if ((vfo == RIG_VFO_SUB) && (VFO_HAS_A_B_ONLY || (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split == RIG_SPLIT_OFF && !cachep->satmode))) { // if rig doesn't have Main/Sub // or if rig has both Main/Sub and A/B -- e.g. 9700 // and we don't have split or satmode turned on // then we don't use Sub -- instead we use Main/VFOB vfo = RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Sub changed to %s\n", __func__, rig_strvfo(vfo)); } else if (vfo == RIG_VFO_TX) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); vfo = RIG_VFO_A; if (VFO_HAS_A_B_ONLY && cachep->satmode) { vfo = RIG_VFO_B; } else if (VFO_HAS_MAIN_SUB_ONLY) { vfo = RIG_VFO_SUB; } else if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->satmode) { vfo = RIG_VFO_SUB; } } else if ((vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) && VFO_HAS_DUAL) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s, split=%d\n", __func__, __LINE__, rig_strvfo(vfo), cachep->split); // If we're being asked for A/Main but we are a MainA/MainB rig change it vfo = RIG_VFO_MAIN; if (cachep->split == RIG_SPLIT_ON && !cachep->satmode) { vfo = RIG_VFO_A; } // Seems the IC821H reverses Main/Sub when in satmode if (RIG_IS_IC821H && cachep->satmode) { vfo = RIG_VFO_SUB; } } else if ((vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) && VFO_HAS_DUAL) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo line#%d vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); // If we're being asked for B/Sub but we are a MainA/MainB rig change it vfo = RIG_VFO_SUB; // If we're in satmode for rigs like IC9700 we want the 2nd VFO if (cachep->satmode) { vfo = RIG_VFO_SUB_A; } else if (cachep->split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; } // Seems the IC821H reverses Main/Sub when in satmode if (RIG_IS_IC821H && cachep->satmode) { vfo = RIG_VFO_MAIN; } } else if ((vfo == RIG_VFO_A || vfo == RIG_VFO_B) && !VFO_HAS_A_B && VFO_HAS_MAIN_SUB) { // If we're being asked for A/B but we are a Main/Sub rig change it vfo_t vfo_old = vfo; vfo = vfo == RIG_VFO_A ? RIG_VFO_MAIN : RIG_VFO_SUB; rig_debug(RIG_DEBUG_ERR, "%s: Rig does not have VFO A/B?\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: Mapping %s=%s\n", __func__, rig_strvfo(vfo_old), rig_strvfo(vfo)); } if ((vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) && !VFO_HAS_MAIN_SUB) { rig_debug(RIG_DEBUG_ERR, "%s: Rig does not have VFO Main/Sub?\n", __func__); RETURNFUNC2(-RIG_EINVAL); } if (vfo != rs->current_vfo) { rig_debug(RIG_DEBUG_TRACE, "%s: VFO changing from %s to %s\n", __func__, rig_strvfo(rs->current_vfo), rig_strvfo(vfo)); cachep->freqCurr = 0; // reset current frequency so set_freq works 1st time } rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__); switch (vfo) { case RIG_VFO_A: icvfo = S_VFOA; break; case RIG_VFO_B: icvfo = S_VFOB; break; case RIG_VFO_MAIN: icvfo = S_MAIN; // If not split or satmode then we must want VFOA if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split == RIG_SPLIT_OFF && !cachep->satmode) { icvfo = S_VFOA; } rig_debug(RIG_DEBUG_TRACE, "%s: Main asked for, ended up with vfo=%s\n", __func__, icvfo == S_MAIN ? "Main" : "VFOA"); break; case RIG_VFO_SUB: icvfo = S_SUB; // If split is on these rigs can only split on Main/VFOB if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { icvfo = S_VFOB; } // If not split or satmode then we must want VFOB if (VFO_HAS_MAIN_SUB_A_B_ONLY && cachep->split == RIG_SPLIT_OFF && !cachep->satmode) { icvfo = S_VFOB; } rig_debug(RIG_DEBUG_TRACE, "%s: Sub asked for, ended up with vfo=%s\n", __func__, icvfo == S_SUB ? "Sub" : "VFOB"); break; case RIG_VFO_TX: icvfo = (cachep->split != RIG_SPLIT_OFF) ? S_VFOB : S_VFOA; vfo = (cachep->split != RIG_SPLIT_OFF) ? RIG_VFO_B : RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: RIG_VFO_TX changing vfo to %s\n", __func__, rig_strvfo(vfo)); break; case RIG_VFO_VFO: retval = icom_transaction(rig, C_SET_VFO, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = vfo; RETURNFUNC2(RIG_OK); case RIG_VFO_MEM: retval = icom_transaction(rig, C_SET_MEM, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = vfo; RETURNFUNC2(RIG_OK); case RIG_VFO_MAIN_A: // we need to select Main before setting VFO case RIG_VFO_MAIN_B: rig_debug(RIG_DEBUG_VERBOSE, "%s: MainA/B logic\n", __func__); retval = icom_transaction(rig, C_SET_VFO, S_MAIN, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } icvfo = vfo == RIG_VFO_MAIN_A ? S_VFOA : S_VFOB; break; case RIG_VFO_SUB_A: // we need to select Sub before setting VFO case RIG_VFO_SUB_B: rig_debug(RIG_DEBUG_VERBOSE, "%s: SubA/B logic\n", __func__); retval = icom_transaction(rig, C_SET_VFO, S_SUB, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } // If SUB_A then we'll assume we're done and probably not in sat mode // If rig has SUB_B active this may be a problem if (vfo == RIG_VFO_SUB_A) { return RIG_OK; } icvfo = vfo == RIG_VFO_SUB_A ? S_VFOA : S_VFOB; break; case RIG_VFO_OTHER: switch (rs->current_vfo) { case RIG_VFO_CURR: break; // no change needed case RIG_VFO_A: vfo = RIG_VFO_B; icvfo = S_VFOB; break; case RIG_VFO_B: vfo = RIG_VFO_A; icvfo = S_VFOA; break; case RIG_VFO_MAIN: vfo = RIG_VFO_SUB; icvfo = S_SUB; break; case RIG_VFO_SUB: vfo = RIG_VFO_MAIN; icvfo = S_MAIN; break; case RIG_VFO_MAIN_A: vfo = RIG_VFO_MAIN_B; icvfo = S_MAIN; // TODO: Select also VFOB? break; case RIG_VFO_MAIN_B: vfo = RIG_VFO_MAIN_A; icvfo = S_MAIN; // TODO: Select also VFOA? break; case RIG_VFO_SUB_A: vfo = RIG_VFO_SUB_B; icvfo = S_SUB; // TODO: Select also VFOB? break; case RIG_VFO_SUB_B: vfo = RIG_VFO_SUB_A; icvfo = S_SUB; // TODO: Select also VFOA? break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown vfo '%s'\n", __func__, rig_strvfo(rs->current_vfo)); } default: if (priv->x25cmdfails == 0 || priv_caps->x25x26_always) rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__); retval = icom_transaction(rig, C_SET_VFO, icvfo, NULL, 0, ackbuf, &ack_len); rig_debug(RIG_DEBUG_TRACE, "%s: line#%d\n", __func__, __LINE__); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rs->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: line#%d curr_vfo=%s\n", __func__, __LINE__, rig_strvfo(rs->current_vfo)); RETURNFUNC2(RIG_OK); } int icom_set_cmd(RIG *rig, vfo_t vfo, struct cmdparams *par, value_t val) { ENTERFUNC; unsigned char cmdbuf[MAXFRAMELEN]; int cmdlen = 0; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = 0; if (!(par->submod & SC_MOD_WR)) { RETURNFUNC(-RIG_EINVAL); } if ((par->submod & SC_MOD_RW12) == SC_MOD_RW12) { cmdbuf[0] = 0x01; cmdlen = 1; } else { cmdlen = par->sublen; memcpy(cmdbuf, par->subext, cmdlen); } int wrd = val.i; int i; switch (par->dattyp) { case CMD_DAT_WRD: for (i = 1; i <= par->datlen; i++) { cmdbuf[cmdlen + par->datlen - i] = wrd & 0xff; wrd >>= 8; } break; case CMD_DAT_BUF: memcpy(&cmdbuf[cmdlen], val.b.d, par->datlen); break; case CMD_DAT_INT: case CMD_DAT_BOL: to_bcd_be(&cmdbuf[cmdlen], val.i, (par->datlen * 2)); break; case CMD_DAT_FLT: to_bcd_be(&cmdbuf[cmdlen], (int) val.f, (par->datlen * 2)); break; case CMD_DAT_LVL: to_bcd_be(&cmdbuf[cmdlen], (int)(val.f * 255.0), (par->datlen * 2)); break; case CMD_DAT_TIM: // returned as seconds since midnight to_bcd_be(&cmdbuf[cmdlen], ((((int)val.i / 3600) * 100) + (((int)val.i / 60) % 60)), (par->datlen * 2)); break; default: break; } cmdlen += par->datlen; RETURNFUNC(icom_transaction(rig, par->command, par->subcmd, cmdbuf, cmdlen, ackbuf, &ack_len)); } int icom_get_cmd(RIG *rig, vfo_t vfo, struct cmdparams *par, value_t *val) { ENTERFUNC; unsigned char ssc = 0x02; unsigned char resbuf[MAXFRAMELEN]; int reslen = sizeof(resbuf); int retval; if (!(par->submod & SC_MOD_RD)) { RETURNFUNC(-RIG_EINVAL); } if ((par->submod & SC_MOD_RW12) == SC_MOD_RW12) { retval = icom_get_raw_buf(rig, par->command, par->subcmd, 1, &ssc, &reslen, resbuf); } else { retval = icom_get_raw_buf(rig, par->command, par->subcmd, par->sublen, (unsigned char *)par->subext, &reslen, resbuf); } if (retval != RIG_OK) { RETURNFUNC(retval); } switch (par->dattyp) { case CMD_DAT_WRD: { int wrd = 0; int i; for (i = 0; i < par->datlen; i++) { wrd = (wrd << 8) + resbuf[i]; } val->i = wrd; } break; case CMD_DAT_STR: if (strlen(val->s) < reslen) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(val->s, resbuf, reslen); val->s[reslen] = 0; break; case CMD_DAT_BUF: if (reslen > val->b.l) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(val->b.d, resbuf, reslen); val->b.l = reslen; break; case CMD_DAT_INT: val->i = from_bcd_be(resbuf, (reslen * 2)); break; case CMD_DAT_FLT: val->f = (float) from_bcd_be(resbuf, (reslen * 2)); break; case CMD_DAT_LVL: val->f = (float) from_bcd_be(resbuf, (reslen * 2)) / 255.0; break; case CMD_DAT_BOL: val->i = (from_bcd_be(resbuf, (reslen * 2)) == 0) ? 0 : 1; break; case CMD_DAT_TIM: val->i = (from_bcd_be(resbuf, 2) * 3600) + (from_bcd_be(&resbuf[1], 2) * 60); break; default: val->i = 0; break; } RETURNFUNC(RIG_OK); } /* * icom_set_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *rs = STATE(rig); unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int cmd_len, ack_len = sizeof(ackbuf); int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int i, retval; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; ENTERFUNC; const struct cmdparams *extcmds = priv_caps->extcmds; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_LEVEL && extcmds[i].id.s == level) { RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], val)); } } /* * Many levels of float type are in [0.0..1.0] range */ if (RIG_LEVEL_IS_FLOAT(level)) { icom_val = val.f * 255; } else { icom_val = val.i; } /* convert values to 0 .. 255 range */ if (RIG_IS_ICR75) { switch (level) { case RIG_LEVEL_NR: icom_val = val.f * 240; break; case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: icom_val = (val.f / 10.0) + 128; if (icom_val > 255) { icom_val = 255; } break; default: break; } } switch (level) { int i; case RIG_LEVEL_KEYSPD: if (val.i < 6) { icom_val = 6; } else if (val.i > 48) { icom_val = 48; } for (i = 0; i < 43; ++i) { if (icom_val == cw_lookup[i][1]) { icom_val = cw_lookup[i][0]; rig_debug(RIG_DEBUG_ERR, "%s: found %d at i=%d\n", __func__, icom_val, i); break; } } break; case RIG_LEVEL_CWPITCH: if (val.i < 300) { icom_val = 300; } else if (val.i >= 900) { icom_val = 900; } icom_val = (int) lroundf(((float) icom_val - 300) * (255.0f / 600.0f)); break; default: break; } /* * Most of the time, the data field is a 3 digit BCD, * but in *big endian* order: 0000..0255 * (from_bcd is little endian) */ cmd_len = 2; to_bcd_be(cmdbuf, (long long) icom_val, cmd_len * 2); switch (level) { case RIG_LEVEL_PREAMP: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_PAMP; cmd_len = 1; if (val.i == 0) { cmdbuf[0] = 0; /* 0=OFF */ break; } for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++) { if (rs->preamp[i] == val.i) { break; } } if (i == HAMLIB_MAXDBLSTSIZ || rs->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported preamp set_level %ddB\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } cmdbuf[0] = i + 1; /* 1=P.AMP1, 2=P.AMP2 */ break; case RIG_LEVEL_ATT: lvl_cn = C_CTL_ATT; /* attenuator level is dB, in BCD mode */ lvl_sc = (val.i / 10) << 4 | (val.i % 10); cmd_len = 0; break; case RIG_LEVEL_AF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_AF; break; case RIG_LEVEL_RF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RF; break; case RIG_LEVEL_SQL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_SQL; break; case RIG_LEVEL_IF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_IF; break; case RIG_LEVEL_APF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_APF; break; case RIG_LEVEL_NR: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NR; break; case RIG_LEVEL_NB: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NB; break; case RIG_LEVEL_PBT_IN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTIN; break; case RIG_LEVEL_PBT_OUT: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTOUT; break; case RIG_LEVEL_CWPITCH: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_CWPITCH; /* use 'set mode' call for CWPITCH on IC-R75 */ if (RIG_IS_ICR75) { lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_MODE_SLCT; cmd_len = 3; cmdbuf[0] = S_PRM_CWPITCH; to_bcd_be(cmdbuf + 1, (long long) icom_val, 4); } break; case RIG_LEVEL_RFPOWER: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RFPOWER; break; case RIG_LEVEL_MICGAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MICGAIN; break; case RIG_LEVEL_KEYSPD: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_KEYSPD; break; case RIG_LEVEL_NOTCHF_RAW: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NOTCHF; break; case RIG_LEVEL_COMP: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_COMP; break; case RIG_LEVEL_AGC_TIME: lvl_cn = C_CTL_MEM; lvl_sc = 0x04; cmd_len = 1; { icom_val = 0; const float *agcp = agc_level; if (rs->current_mode == RIG_MODE_AM) { agcp = agc_level2; } rig_debug(RIG_DEBUG_ERR, "%s: val.f=%f\n", __func__, val.f); for (i = 0; i <= 13; ++i) { if (agcp[i] <= val.f) { rig_debug(RIG_DEBUG_ERR, "%s: agcp=%f <= val.f=%f at %d\n", __func__, agcp[i], val.f, i); icom_val = i; } } cmdbuf[0] = icom_val; } break; case RIG_LEVEL_AGC: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_AGC; cmd_len = 1; if (priv_caps->agc_levels_present) { int found = 0; for (i = 0; i <= HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level != RIG_AGC_LAST; i++) { if (priv_caps->agc_levels[i].level == val.i) { cmdbuf[0] = priv_caps->agc_levels[i].icom_level; found = 1; break; } } if (!found) { RETURNFUNC(-RIG_EINVAL); } } else { // Legacy mapping that does not apply to all rigs switch (val.i) { case RIG_AGC_SLOW: cmdbuf[0] = D_AGC_SLOW; break; case RIG_AGC_MEDIUM: cmdbuf[0] = D_AGC_MID; break; case RIG_AGC_FAST: cmdbuf[0] = D_AGC_FAST; break; case RIG_AGC_SUPERFAST: cmdbuf[0] = D_AGC_SUPERFAST; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported LEVEL_AGC %d\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } } break; case RIG_LEVEL_BKINDL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BKINDL; break; case RIG_LEVEL_BALANCE: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BALANCE; break; case RIG_LEVEL_VOXGAIN: if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_VOXGAIN; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_VOXGAIN; } break; case RIG_LEVEL_ANTIVOX: if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_ANTIVOX; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_ANTIVOX; } break; case RIG_LEVEL_MONITOR_GAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MON; break; case RIG_LEVEL_SPECTRUM_MODE: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MOD; cmd_len = 2; switch (val.i) { case RIG_SPECTRUM_MODE_CENTER: icom_val = SCOPE_MODE_CENTER; break; case RIG_SPECTRUM_MODE_FIXED: icom_val = SCOPE_MODE_FIXED; break; case RIG_SPECTRUM_MODE_CENTER_SCROLL: icom_val = SCOPE_MODE_SCROLL_C; break; case RIG_SPECTRUM_MODE_FIXED_SCROLL: icom_val = SCOPE_MODE_SCROLL_F; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum mode %d\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = icom_val; break; case RIG_LEVEL_SPECTRUM_SPAN: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SPN; cmd_len = 6; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); // Spectrum span is represented as a +/- value for Icom rigs to_bcd(cmdbuf + 1, val.i / 2, 5 * 2); break; case RIG_LEVEL_SPECTRUM_SPEED: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SWP; cmd_len = 2; if (val.i < 0) { val.i = 0; } else if (val.i > 2) { val.i = 2; } switch (val.i) { case 0: icom_val = SCOPE_SPEED_SLOW; break; case 1: icom_val = SCOPE_SPEED_MID; break; case 2: icom_val = SCOPE_SPEED_FAST; break; } cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = icom_val; break; case RIG_LEVEL_SPECTRUM_REF: { float icom_db = (roundf(val.f * 2.0f) / 2.0f) * 100.0f; lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_REF; cmd_len = 4; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); // Spectrum reference level is represented at 0.01dB accuracy, but needs to be rounded to nearest 0.5dB to_bcd_be(cmdbuf + 1, abs((int) icom_db), 2 * 2); // Sign cmdbuf[3] = (icom_db < 0) ? 1 : 0; break; } case RIG_LEVEL_SPECTRUM_EDGE_LOW: case RIG_LEVEL_SPECTRUM_EDGE_HIGH: { int range_id; value_t edge_number_value; value_t opposite_edge_value; setting_t level_opposite_edge = (level == RIG_LEVEL_SPECTRUM_EDGE_LOW) ? RIG_LEVEL_SPECTRUM_EDGE_HIGH : RIG_LEVEL_SPECTRUM_EDGE_LOW; lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_FEF; cmd_len = 12; // Modify the frequency range currently active retval = icom_get_spectrum_edge_frequency_range(rig, vfo, &range_id); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error getting spectrum edge frequency range\n", __func__); RETURNFUNC(retval); } // Modify the edge number currently active retval = icom_get_ext_level(rig, vfo, TOK_SCOPE_EDG, &edge_number_value); if (retval != RIG_OK) { RETURNFUNC(retval); } // Get the current opposite edge frequency retval = icom_get_level(rig, vfo, level_opposite_edge, &opposite_edge_value); if (retval != RIG_OK) { RETURNFUNC(retval); } to_bcd(cmdbuf, range_id, 1 * 2); to_bcd(cmdbuf + 1, edge_number_value.i + 1, 1 * 2); if (level == RIG_LEVEL_SPECTRUM_EDGE_LOW) { to_bcd(cmdbuf + 2, val.i, 5 * 2); to_bcd(cmdbuf + 7, opposite_edge_value.i, 5 * 2); } else { to_bcd(cmdbuf + 2, opposite_edge_value.i, 5 * 2); to_bcd(cmdbuf + 7, val.i, 5 * 2); } break; } case RIG_LEVEL_SPECTRUM_ATT: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_ATT; cmd_len = 2; for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++) { if (rig->caps->spectrum_attenuator[i] == val.i) { break; } } if (val.i != 0 && (i == HAMLIB_MAXDBLSTSIZ || rig->caps->spectrum_attenuator[i] == 0)) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum attenuator level %ddB\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); to_bcd(cmdbuf + 1, val.i, 5 * 2); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL * */ int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *rs; unsigned char cmdbuf[MAXFRAMELEN], respbuf[MAXFRAMELEN]; int cmd_len, resp_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int cmdhead; int retval; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; ENTERFUNC; const struct cmdparams *extcmds = priv_caps->extcmds; int i; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { //rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i); if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_LEVEL && extcmds[i].id.s == level) { RETURNFUNC(icom_get_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], val)); } } rig_debug(RIG_DEBUG_TRACE, "%s: no extcmd found\n", __func__); rs = STATE(rig); cmd_len = 0; switch (level) { case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RAWSTR: lvl_cn = C_RD_SQSM; lvl_sc = S_SML; break; case RIG_LEVEL_ALC: lvl_cn = C_RD_SQSM; lvl_sc = S_ALC; break; case RIG_LEVEL_SWR: lvl_cn = C_RD_SQSM; lvl_sc = S_SWR; break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: lvl_cn = C_RD_SQSM; lvl_sc = S_RFML; break; case RIG_LEVEL_COMP_METER: lvl_cn = C_RD_SQSM; lvl_sc = S_CMP; break; case RIG_LEVEL_VD_METER: lvl_cn = C_RD_SQSM; lvl_sc = S_VD; break; case RIG_LEVEL_ID_METER: lvl_cn = C_RD_SQSM; lvl_sc = S_ID; break; case RIG_LEVEL_PREAMP: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_PAMP; break; case RIG_LEVEL_ATT: lvl_cn = C_CTL_ATT; lvl_sc = -1; break; case RIG_LEVEL_AF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_AF; break; case RIG_LEVEL_RF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RF; break; case RIG_LEVEL_SQL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_SQL; break; case RIG_LEVEL_IF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_IF; break; case RIG_LEVEL_APF: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_APF; break; case RIG_LEVEL_NR: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NR; break; case RIG_LEVEL_NB: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NB; break; case RIG_LEVEL_PBT_IN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTIN; break; case RIG_LEVEL_PBT_OUT: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_PBTOUT; break; case RIG_LEVEL_CWPITCH: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_CWPITCH; /* use 'set mode' call for CWPITCH on IC-R75 */ if (RIG_IS_ICR75) { lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_MODE_SLCT; cmd_len = 1; cmdbuf[0] = S_PRM_CWPITCH; } break; case RIG_LEVEL_RFPOWER: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_RFPOWER; break; case RIG_LEVEL_MICGAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MICGAIN; break; case RIG_LEVEL_KEYSPD: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_KEYSPD; break; case RIG_LEVEL_NOTCHF_RAW: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_NOTCHF; break; case RIG_LEVEL_COMP: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_COMP; break; case RIG_LEVEL_AGC: lvl_cn = C_CTL_FUNC; lvl_sc = S_FUNC_AGC; break; case RIG_LEVEL_BKINDL: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BKINDL; break; case RIG_LEVEL_BALANCE: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_BALANCE; break; case RIG_LEVEL_VOXGAIN: /* IC-910H */ if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_VOXGAIN; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_VOXGAIN; } break; case RIG_LEVEL_ANTIVOX: if (RIG_IS_IC910) { /* IC-910H */ lvl_cn = C_CTL_MEM; lvl_sc = S_MEM_ANTIVOX; } else { lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_ANTIVOX; } break; case RIG_LEVEL_MONITOR_GAIN: lvl_cn = C_CTL_LVL; lvl_sc = S_LVL_MON; break; case RIG_LEVEL_SPECTRUM_MODE: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MOD; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_SPAN: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SPN; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_SPEED: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SWP; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_REF: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_REF; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_SPECTRUM_EDGE_LOW: case RIG_LEVEL_SPECTRUM_EDGE_HIGH: { int range_id; value_t edge_number_value; lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_FEF; cmd_len = 2; // Get the frequency range currently active retval = icom_get_spectrum_edge_frequency_range(rig, vfo, &range_id); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error getting spectrum edge frequency range\n", __func__); RETURNFUNC(retval); } // Get the edge number currently active retval = icom_get_ext_level(rig, vfo, TOK_SCOPE_EDG, &edge_number_value); if (retval != RIG_OK) { RETURNFUNC(retval); } to_bcd(cmdbuf, range_id, 1 * 2); to_bcd(cmdbuf + 1, edge_number_value.i + 1, 1 * 2); break; } case RIG_LEVEL_SPECTRUM_ATT: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_ATT; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case RIG_LEVEL_USB_AF: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_ATT; cmd_len = 1; break; case RIG_LEVEL_AGC_TIME: lvl_cn = C_CTL_MEM; lvl_sc = 0x04; // IC-9700, 7300, 705 so far cmd_len = 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s\n", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } /* use cmdbuf and cmd_len for 'set mode' subcommand */ retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, respbuf, &resp_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = ((lvl_sc == -1) ? 1 : 2) + cmd_len; resp_len -= cmdhead; if (respbuf[0] != lvl_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, respbuf[0], resp_len); RETURNFUNC(-RIG_ERJCTED); } /* * The result is a 3 digit BCD, but in *big endian* order: 0000..0255 * (from_bcd is little endian) */ icom_val = from_bcd_be(respbuf + cmdhead, resp_len * 2); switch (level) { case RIG_LEVEL_STRENGTH: val->i = round(rig_raw2val(icom_val, &rig->caps->str_cal)); break; case RIG_LEVEL_RAWSTR: /* raw value */ val->i = icom_val; break; case RIG_LEVEL_AGC: if (priv_caps->agc_levels_present) { int found = 0; for (i = 0; i <= HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level >= 0; i++) { if (priv_caps->agc_levels[i].icom_level == icom_val) { val->i = priv_caps->agc_levels[i].level; found = 1; break; } } if (!found) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected AGC 0x%02x\n", __func__, icom_val); RETURNFUNC(-RIG_EPROTO); } } else { switch (icom_val) { case D_AGC_SLOW: val->i = RIG_AGC_SLOW; break; case D_AGC_MID: val->i = RIG_AGC_MEDIUM; break; case D_AGC_FAST: val->i = RIG_AGC_FAST; break; case D_AGC_SUPERFAST: val->i = RIG_AGC_SUPERFAST; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected AGC 0x%02x\n", __func__, icom_val); RETURNFUNC(-RIG_EPROTO); } } break; case RIG_LEVEL_ALC: if (rig->caps->alc_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_alc_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->alc_cal); } break; case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_swr_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->swr_cal); } break; case RIG_LEVEL_RFPOWER_METER: // rig table in Watts needs to be divided by 100 if (rig->caps->rfpower_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_rfpower_meter_cal) * 0.01; } else { val->f = rig_raw2val_float(icom_val, &rig->caps->rfpower_meter_cal) * 0.01; } break; case RIG_LEVEL_RFPOWER_METER_WATTS: { freq_range_t range_list; // All Icom backends should be in Watts now if (rig->caps->rfpower_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_rfpower_meter_cal); rig_debug(RIG_DEBUG_TRACE, "%s: using rig table to convert %d to %.01f\n", __func__, icom_val, val->f); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->rfpower_meter_cal); rig_debug(RIG_DEBUG_TRACE, "%s: using default icom table to convert %d to %.01f\n", __func__, icom_val, val->f); } if (RIG_IS_IC9700 && CACHE(rig)->freqMainA >= 1e9) { val->f /= 10; // power scale is different for 10GHz } rig_get_range(&range_list, STATE(rig)->current_freq, STATE(rig)->current_mode); rig_debug(RIG_DEBUG_VERBOSE, "%s: maxpower=%d\n", __func__, range_list.high_power); break; } case RIG_LEVEL_COMP_METER: if (rig->caps->comp_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_comp_meter_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->comp_meter_cal); } break; case RIG_LEVEL_VD_METER: if (rig->caps->vd_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_vd_meter_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->vd_meter_cal); } break; case RIG_LEVEL_ID_METER: if (rig->caps->id_meter_cal.size == 0) { val->f = rig_raw2val_float(icom_val, &icom_default_id_meter_cal); } else { val->f = rig_raw2val_float(icom_val, &rig->caps->id_meter_cal); } break; case RIG_LEVEL_CWPITCH: val->i = (int) lroundf(300.0f + ((float) icom_val * 600.0f / 255.0f)); break; case RIG_LEVEL_KEYSPD: for (i = 0; i < 43; ++i) { int rigval = cw_lookup[i][0]; if (rigval >= icom_val) { icom_val = cw_lookup[i][1]; val->i = icom_val; break; } } if (i == 43) { rig_debug(RIG_DEBUG_ERR, "%s: did not find KEYSPD=%d\n", __func__, icom_val); } break; case RIG_LEVEL_PREAMP: if (icom_val == 0) { val->i = 0; break; } if (icom_val > HAMLIB_MAXDBLSTSIZ || rs->preamp[icom_val - 1] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported preamp get_level %ddB\n", __func__, icom_val); RETURNFUNC(-RIG_EPROTO); } val->i = rs->preamp[icom_val - 1]; break; case RIG_LEVEL_SPECTRUM_MODE: switch (icom_val) { case SCOPE_MODE_CENTER: val->i = RIG_SPECTRUM_MODE_CENTER; break; case SCOPE_MODE_FIXED: val->i = RIG_SPECTRUM_MODE_FIXED; break; case SCOPE_MODE_SCROLL_C: val->i = RIG_SPECTRUM_MODE_CENTER_SCROLL; break; case SCOPE_MODE_SCROLL_F: val->i = RIG_SPECTRUM_MODE_FIXED_SCROLL; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum mode %d\n", __func__, icom_val); RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_SPECTRUM_SPAN: icom_val = (int) from_bcd(respbuf + cmdhead, resp_len * 2); // Spectrum span is represented as a +/- value for Icom rigs val->i = icom_val * 2; break; case RIG_LEVEL_SPECTRUM_SPEED: switch (icom_val) { case SCOPE_SPEED_SLOW: val->i = 0; break; case SCOPE_SPEED_MID: val->i = 1; break; case SCOPE_SPEED_FAST: val->i = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported spectrum speed %d\n", __func__, icom_val); RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_SPECTRUM_REF: { unsigned char *icom_ref = respbuf + cmdhead; // Spectrum reference level is represented at 0.01dB accuracy, but is rounded to nearest 0.5dB float db = (float) from_bcd_be(icom_ref, 2 * 2) / 100.0f; // Sign if (icom_ref[2] != 0) { db = -db; } val->f = db; break; } case RIG_LEVEL_SPECTRUM_EDGE_LOW: val->i = (int) from_bcd(respbuf + cmdhead, 5 * 2); break; case RIG_LEVEL_SPECTRUM_EDGE_HIGH: val->i = (int) from_bcd(respbuf + cmdhead + 5, 5 * 2); break; case RIG_LEVEL_AGC_TIME: // some rigs have different level interpretaions for different modes if (rs->current_mode == RIG_MODE_AM) { val->f = agc_level2[icom_val]; } else { val->f = agc_level[icom_val]; } break; /* RIG_LEVEL_ATT/RIG_LEVEL_SPECTRUM_ATT: returned value is already an integer in dB (coded in BCD) */ default: if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float) icom_val / 255; } else { val->i = icom_val; } } /* convert values from 0 .. 255 range */ if (RIG_IS_ICR75) { switch (level) { case RIG_LEVEL_NR: val->f = (float) icom_val / 240; break; case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: if (icom_val == 255) { val->f = 1280.0; } else { val->f = (float)(icom_val - 128) * 10.0; } break; default: break; } } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, resp_len, icom_val, val->i, val->f); RETURNFUNC(RIG_OK); } int icom_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { const struct confparams *cfp = rig->caps->extlevels; unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int cmd_len, ack_len = sizeof(ackbuf); int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int i, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called: token=%ld int=%d float=%f\n", __func__, token, val.i, val.f); switch (token) { case TOK_SCOPE_MSS: if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MSS; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_SDS: if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SDS; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_STX: // TODO: Should be a func? if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_STX; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_CFQ: if (val.i < 0 || val.i > 2) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_CFQ; cmd_len = 1; cmdbuf[0] = val.i; break; case TOK_SCOPE_EDG: if (val.i < 0 || val.i > 3) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_EDG; cmd_len = 2; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = val.i + 1; break; case TOK_SCOPE_VBW: if (val.i < 0 || val.i > 1) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_VBW; cmd_len = 2; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = val.i; break; case TOK_SCOPE_RBW: if (val.i < 0 || val.i > 2) { RETURNFUNC2(-RIG_EINVAL); } lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_RBW; cmd_len = 2; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); cmdbuf[1] = val.i; break; default: cfp = (cfp == NULL) ? icom_ext_levels : cfp; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_levels);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_levels; i = 0; } else if (cfp[i].token == token) { RETURNFUNC2(icom_set_ext_cmd(rig, vfo, token, val)); } else { i++; } } rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_ext_level token: %ld\n", __func__, token); RETURNFUNC2(-RIG_EINVAL); } retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } int icom_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { const struct confparams *cfp = rig->caps->extlevels; unsigned char cmdbuf[MAXFRAMELEN], respbuf[MAXFRAMELEN]; int cmd_len, resp_len; int lvl_cn, lvl_sc; /* Command Number, Subcommand */ int icom_val; int cmdhead; int retval; int i; ENTERFUNC; cmd_len = 0; lvl_sc = -1; switch (token) { case TOK_SCOPE_MSS: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_MSS; break; case TOK_SCOPE_SDS: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_SDS; break; case TOK_SCOPE_STX: // TODO: Should be a func? lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_STX; break; case TOK_SCOPE_CFQ: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_CFQ; break; case TOK_SCOPE_EDG: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_EDG; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case TOK_SCOPE_VBW: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_VBW; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; case TOK_SCOPE_RBW: lvl_cn = C_CTL_SCP; lvl_sc = S_SCP_RBW; cmd_len = 1; cmdbuf[0] = icom_get_spectrum_vfo(rig, vfo); break; default: cfp = (cfp == NULL) ? icom_ext_levels : cfp; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_levels);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_levels; i = 0; } else if (cfp[i].token == token) { RETURNFUNC(icom_get_ext_cmd(rig, vfo, token, val)); } else { i++; } } rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_ext_level token: %ld\n", __func__, token); RETURNFUNC(-RIG_EINVAL); } /* use cmdbuf and cmd_len for 'set mode' subcommand */ retval = icom_transaction(rig, lvl_cn, lvl_sc, cmdbuf, cmd_len, respbuf, &resp_len); if (retval != RIG_OK) { RETURNFUNC(retval); } cmdhead = ((lvl_sc == -1) ? 1 : 2) + cmd_len; resp_len -= cmdhead; if (respbuf[0] != lvl_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, respbuf[0], resp_len); RETURNFUNC(-RIG_ERJCTED); } icom_val = from_bcd_be(respbuf + cmdhead, resp_len * 2); switch (token) { case TOK_SCOPE_EDG: val->i = icom_val - 1; break; default: val->i = icom_val; break; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, resp_len, icom_val, val->i, val->f); RETURNFUNC(RIG_OK); } int icom_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { ENTERFUNC; const struct confparams *cfp = rig->caps->extfuncs; cfp = (cfp == NULL) ? icom_ext_funcs : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_funcs);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_funcs; i = 0; } else if (cfp[i].token == token) { value_t value = { .i = status }; RETURNFUNC(icom_set_ext_cmd(rig, vfo, token, value)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { ENTERFUNC; const struct confparams *cfp = rig->caps->extfuncs; cfp = (cfp == NULL) ? icom_ext_funcs : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_funcs);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_funcs; i = 0; } else if (cfp[i].token == token) { value_t value; int result = icom_get_ext_cmd(rig, vfo, token, &value); if (result == RIG_OK) { *status = value.i; } RETURNFUNC(result); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { ENTERFUNC; const struct confparams *cfp = rig->caps->extparms; cfp = (cfp == NULL) ? icom_ext_parms : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_parms);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_parms; i = 0; } else if (cfp[i].token == token) { RETURNFUNC(icom_set_ext_cmd(rig, RIG_VFO_NONE, token, val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { ENTERFUNC; const struct confparams *cfp = rig->caps->extparms; cfp = (cfp == NULL) ? icom_ext_parms : cfp; int i; for (i = 0; (cfp[i].token != RIG_CONF_END) || (cfp != icom_ext_parms);) { if (cfp[i].token == RIG_CONF_END) { cfp = icom_ext_parms; i = 0; } else if (cfp[i].token == token) { RETURNFUNC(icom_get_ext_cmd(rig, RIG_VFO_NONE, token, val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } int icom_get_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int i; ENTERFUNC; for (i = 0; rig->caps->ext_tokens && rig->caps->ext_tokens[i] != TOK_BACKEND_NONE; i++) { if (rig->caps->ext_tokens[i] == token) { const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *cmd = priv->extcmds ? priv->extcmds : icom_ext_cmd; for (i = 0; (cmd[i].id.t != 0) || (cmd != icom_ext_cmd);) { if (cmd[i].id.t == 0) { cmd = icom_ext_cmd; i = 0; } else if (cmd[i].cmdparamtype == CMD_PARAM_TYPE_TOKEN && cmd[i].id.t == token) { RETURNFUNC(icom_get_cmd(rig, vfo, (struct cmdparams *)&cmd[i], val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } } RETURNFUNC(-RIG_EINVAL); } int icom_set_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int i; ENTERFUNC; for (i = 0; rig->caps->ext_tokens && rig->caps->ext_tokens[i] != TOK_BACKEND_NONE; i++) { if (rig->caps->ext_tokens[i] == token) { const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *cmd = priv->extcmds ? priv->extcmds : icom_ext_cmd; for (i = 0; (cmd[i].id.t != 0) || (cmd != icom_ext_cmd);) { if (cmd[i].id.t == 0) { cmd = icom_ext_cmd; i = 0; } else if (cmd->cmdparamtype == CMD_PARAM_TYPE_TOKEN && cmd[i].id.t == token) { RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&cmd[i], val)); } else { i++; } } RETURNFUNC(-RIG_EINVAL); } } RETURNFUNC(-RIG_EINVAL); } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct icom_priv_data *priv; struct rig_state *rs; ENTERFUNC; rs = STATE(rig); priv = (struct icom_priv_data *) rs->priv; switch (token) { case TOK_CIVADDR: if (val[0] == '0' && val[1] == 'x') { priv->re_civ_addr = strtol(val, (char **) NULL, 16); } else { priv->re_civ_addr = atoi(val); } break; case TOK_MODE731: priv->civ_731_mode = atoi(val) ? 1 : 0; break; case TOK_NOXCHG: priv->no_xchg = atoi(val) ? 1 : 0; break; case TOK_TONE_ENABLE: priv->tone_enable = atoi(val) ? 1 : 0; break; case TOK_FILTER_USBD: priv->filter_usbd = atoi(val); if (priv->filter_usbd > 3) { priv->filter_usbd = 3; } if (priv->filter_usbd < 1) { priv->filter_usbd = 1; } break; case TOK_FILTER_USB: priv->filter_usb = atoi(val); if (priv->filter_usb > 3) { priv->filter_usb = 3; } if (priv->filter_usb < 1) { priv->filter_usb = 1; } break; case TOK_FILTER_CW: priv->filter_cw = atoi(val); if (priv->filter_cw > 3) { priv->filter_cw = 3; } if (priv->filter_cw < 1) { priv->filter_cw = 1; } break; case TOK_FILTER_FM: priv->filter_fm = atoi(val); if (priv->filter_fm > 3) { priv->filter_fm = 3; } if (priv->filter_fm < 1) { priv->filter_fm = 1; } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int icom_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct icom_priv_data *priv; struct rig_state *rs; ENTERFUNC; rs = STATE(rig); priv = (struct icom_priv_data *) rs->priv; switch (token) { case TOK_CIVADDR: SNPRINTF(val, val_len, "%d", priv->re_civ_addr); break; case TOK_MODE731: SNPRINTF(val, val_len, "%d", priv->civ_731_mode); break; case TOK_NOXCHG: SNPRINTF(val, val_len, "%d", priv->no_xchg); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int icom_get_conf(RIG *rig, hamlib_token_t token, char *val) { return icom_get_conf2(rig, token, val, 128); } /* * icom_set_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char ackbuf[MAXFRAMELEN], pttbuf[1]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; pttbuf[0] = ptt == RIG_PTT_ON ? 1 : 0; retval = icom_transaction(rig, C_CTL_PTT, S_PTT, pttbuf, 1, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL, ptt!=NULL */ int icom_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { unsigned char pttbuf[MAXFRAMELEN]; int ptt_len, retval; int retry = 5; ENTERFUNC; do { retval = icom_transaction(rig, C_CTL_PTT, S_PTT, NULL, 0, pttbuf, &ptt_len); } while (--retry > 0 && retval != RIG_OK); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * pttbuf should contain Cn,Sc,Data area */ ptt_len -= 2; if (ptt_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ptt_len); RETURNFUNC(-RIG_ERJCTED); } *ptt = pttbuf[2] == 1 ? RIG_PTT_ON : RIG_PTT_OFF; RETURNFUNC(RIG_OK); } /* * icom_get_dcd * Assumes rig!=NULL, STATE(rig)->priv!=NULL, ptt!=NULL */ int icom_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { unsigned char dcdbuf[MAXFRAMELEN]; int dcd_len, retval; ENTERFUNC; retval = icom_transaction(rig, C_RD_SQSM, S_SQL, NULL, 0, dcdbuf, &dcd_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * dcdbuf should contain Cn,Data area */ dcd_len -= 2; if (dcd_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, dcd_len); RETURNFUNC(-RIG_ERJCTED); } /* * 0x00=sql closed, 0x01=sql open */ *dcd = dcdbuf[2] == 1 ? RIG_DCD_ON : RIG_DCD_OFF; RETURNFUNC(RIG_OK); } /* * icom_set_rptr_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int rptr_sc; ENTERFUNC; switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: rptr_sc = S_DUP_OFF; /* Simplex mode */ break; case RIG_RPT_SHIFT_MINUS: rptr_sc = S_DUP_M; /* Duplex - mode */ break; case RIG_RPT_SHIFT_PLUS: rptr_sc = S_DUP_P; /* Duplex + mode */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported shift %d\n", __func__, rptr_shift); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, C_CTL_SPLT, rptr_sc, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_rptr_shift * Assumes rig!=NULL, STATE(rig)->priv!=NULL, rptr_shift!=NULL * will not work for IC-746 Pro * NOTE: seems not to work (tested on IC-706MkIIG), please report --SF */ int icom_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { unsigned char rptrbuf[MAXFRAMELEN]; int rptr_len, retval; ENTERFUNC; retval = icom_transaction(rig, C_CTL_SPLT, -1, NULL, 0, rptrbuf, &rptr_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * rptrbuf should contain Cn,Sc */ rptr_len--; if (rptr_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, rptr_len); RETURNFUNC(-RIG_ERJCTED); } switch (rptrbuf[1]) { case S_DUP_OFF: case S_DUP_DD_RPS: *rptr_shift = RIG_RPT_SHIFT_NONE; /* Simplex mode */ break; case S_DUP_M: *rptr_shift = RIG_RPT_SHIFT_MINUS; /* Duplex - mode */ break; case S_DUP_P: *rptr_shift = RIG_RPT_SHIFT_PLUS; /* Duplex + mode */ break; // The same command indicates split state, which means simplex mode case S_SPLT_OFF: case S_SPLT_ON: *rptr_shift = RIG_RPT_SHIFT_NONE; /* Simplex mode */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported shift %d\n", __func__, rptrbuf[1]); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } /* * icom_set_rptr_offs * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { int offs_len; unsigned char offsbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; const struct icom_priv_caps *priv_caps; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; offs_len = (priv_caps->offs_len) ? priv_caps->offs_len : OFFS_LEN; /* * Icoms are using a 100Hz unit (at least on 706MKIIg) -- SF */ to_bcd(offsbuf, rptr_offs / 100, offs_len * 2); retval = icom_transaction(rig, C_SET_OFFS, -1, offsbuf, offs_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_rptr_offs * Assumes rig!=NULL, STATE(rig)->priv!=NULL, rptr_offs!=NULL */ int icom_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { int offs_len; unsigned char offsbuf[MAXFRAMELEN]; int buf_len, retval; const struct icom_priv_caps *priv_caps; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; offs_len = (priv_caps->offs_len) ? priv_caps->offs_len : OFFS_LEN; retval = icom_transaction(rig, C_RD_OFFS, -1, NULL, 0, offsbuf, &buf_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * offsbuf should contain Cn */ buf_len--; if (buf_len != offs_len) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, buf_len); RETURNFUNC(-RIG_ERJCTED); } /* * Icoms are using a 100Hz unit (at least on 706MKIIg) -- SF */ *rptr_offs = from_bcd(offsbuf + 1, buf_len * 2) * 100; RETURNFUNC(RIG_OK); } /* * Helper function to go back and forth split VFO */ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); ENTERFUNC; // Initialize TX VFO if not done yet if (rs->tx_vfo == RIG_VFO_NONE || rs->tx_vfo == RIG_VFO_CURR || rs->tx_vfo == RIG_VFO_TX) { if (cachep->split == RIG_SPLIT_OFF) { rs->tx_vfo = rs->current_vfo; } else { rs->tx_vfo = vfo_fixup(rig, RIG_VFO_OTHER, cachep->split); } } if (VFO_HAS_A_B_ONLY) { if (cachep->split == RIG_SPLIT_OFF) { *rx_vfo = *tx_vfo = rs->current_vfo; } else { *rx_vfo = rs->current_vfo; *tx_vfo = rs->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_A_B_ONLY, split=%d, rx=%s, tx=%s\n", __func__, cachep->split, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo)); } else if (VFO_HAS_MAIN_SUB_ONLY) { if (cachep->split == RIG_SPLIT_OFF) { *rx_vfo = *tx_vfo = rs->current_vfo; } else { *rx_vfo = rs->current_vfo; *tx_vfo = rs->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_MAIN_SUB_ONLY, split=%d, rx=%s, tx=%s\n", __func__, cachep->split, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo)); } else if (VFO_HAS_MAIN_SUB_A_B_ONLY) { int satmode = 0; // e.g. IC-9700 split on Main/Sub does not work // only Main VFOA/B and SubRx/MainTx split works if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } // don't care about retval here, only care about satmode=1 if (satmode) { *rx_vfo = RIG_VFO_MAIN; *tx_vfo = RIG_VFO_SUB; cachep->satmode = 1; } else if (cachep->split == RIG_SPLIT_OFF) { *rx_vfo = *tx_vfo = rs->current_vfo; cachep->satmode = 0; } else { *rx_vfo = rs->current_vfo; *tx_vfo = rs->tx_vfo; } rig_debug(RIG_DEBUG_TRACE, "%s: VFO_HAS_MAIN_SUB_A_B_ONLY, split=%d, rx=%s, tx=%s\n", __func__, cachep->split, rig_strvfo(*rx_vfo), rig_strvfo(*tx_vfo)); } else { rig_debug(RIG_DEBUG_ERR, "%s: unknown VFO setup\n", __func__); RETURNFUNC(-RIG_ENAVAIL); } RETURNFUNC(RIG_OK); } /* * icom_set_split_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * icom_set_vfo,icom_set_freq works for this rig * * Assumes also that the current VFO is the rx VFO. */ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called for %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: satmode=%d, tx_vfo=%s\n", __func__, cachep->satmode, rig_strvfo(rs->tx_vfo)); if (vfo == RIG_VFO_TX) { if (cachep->satmode) { vfo = RIG_VFO_SUB; } else { vfo = rs->tx_vfo; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo is now %s\n", __func__, rig_strvfo(vfo)); if (rs->current_vfo == RIG_VFO_NONE || rs->current_vfo == RIG_VFO_CURR) { HAMLIB_TRACE; retval = icom_set_default_vfo(rig); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_default_vfo failed: %s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } } // Use the command 0x25 if the rig supports it // This eliminates VFO swapping and improves split operations if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (priv->x25cmdfails <= 0 || priv_caps->x25x26_always)) { int satmode = 0; // Return value is not important, as only satmode=1 means anything if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } // only worth trying if not in satmode if (satmode == 0) { int freq_len; short retry_save; unsigned char freqbuf[32]; freq_len = priv->civ_731_mode ? 4 : 5; to_bcd(freqbuf, tx_freq, freq_len * 2); retry_save = rp->retry; rp->retry = 1; retval = icom_set_freq_x25(rig, vfo, tx_freq, freq_len, freqbuf); rp->retry = retry_save; if (retval == RIG_OK) { if (priv->tone_enable) { rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TONE, 1); } RETURNFUNC2(retval); } } } if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { rig_debug(RIG_DEBUG_TRACE, "%s: Using XCHG to swap/set/swap\n", __func__); if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_set_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } } retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: rx_vfo=%s, tx_vfo=%s\n", __func__, rig_strvfo(rx_vfo), rig_strvfo(tx_vfo)); HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ)) { retval = rig_set_vfo(rig, tx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } retval = rig_set_freq(rig, tx_vfo, tx_freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (VFO_HAS_MAIN_SUB_A_B_ONLY) { // Then we return the VFO to the rx_vfo rig_debug(RIG_DEBUG_TRACE, "%s: SATMODE split_on=%d rig so setting vfo to %s\n", __func__, cachep->split, rig_strvfo(rx_vfo)); HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ)) { retval = rig_set_vfo(rig, rx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } } else if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { HAMLIB_TRACE; RETURNFUNC2(retval); } if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } if (priv->tone_enable) { rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_TONE, 1); } RETURNFUNC2(retval); } /* * icom_get_split_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, rx_freq!=NULL, tx_freq!=NULL * icom_set_vfo,icom_get_freq works for this rig */ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = rs->priv; const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); if (RIG_IS_IC910) { ptt_t ptt; retval = rig_get_ptt(rig, RIG_VFO_CURR, &ptt); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (ptt) { int cache_ms_freq; rig_get_cache_freq(rig, vfo, tx_freq, &cache_ms_freq); rig_debug(RIG_DEBUG_TRACE, "%s: ptt is on so returning last known freq\n", __func__); RETURNFUNC2(RIG_OK); } } rig_debug(RIG_DEBUG_VERBOSE, "%s curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); if (rs->current_vfo == RIG_VFO_NONE) { HAMLIB_TRACE; icom_set_default_vfo(rig); } // Use the command 0x25 if the rig supports it // This eliminates VFO swapping and improves split operations // This does not work in satellite mode for the IC-9700 if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (priv->x25cmdfails <= 0 || priv_caps->x25x26_always)) { int satmode = 0; // Return value is not important, as only satmode=1 means anything if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } if (satmode == 0) { // Only worth trying if the rig is not in satmode short retry_save = rp->retry; int freqbuf_offset; rp->retry = 0; retval = icom_get_freq_x25(rig, vfo, &ack_len, ackbuf, &freqbuf_offset); rp->retry = retry_save; if (retval == RIG_OK) { *tx_freq = from_bcd(&ackbuf[freqbuf_offset], (priv->civ_731_mode ? 4 : 5) * 2); RETURNFUNC2(retval); } } else { // The rig is in satmode so attempt to get the TX frequency using another command int freqbuf_offset; retval = icom_get_tx_freq(rig, &ack_len, ackbuf, &freqbuf_offset); if (retval == RIG_OK) { *tx_freq = from_bcd(&ackbuf[freqbuf_offset], (priv->civ_731_mode ? 4 : 5) * 2); RETURNFUNC2(retval); } } } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_get_freq(rig, tx_vfo, tx_freq))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { HAMLIB_TRACE; RETURNFUNC2(retval); } if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } RETURNFUNC2(retval); } /* * icom_set_split_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * icom_set_vfo,icom_set_mode works for this rig */ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; ENTERFUNC; if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && rs->current_vfo != RIG_VFO_MEM) { RETURNFUNC(icom_set_mode(rig, vfo, tx_mode, tx_width)); } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->set_mode(rig, tx_vfo, tx_mode, tx_width))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC(retval); } if (VFO_HAS_A_B_ONLY && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(retval); } /* * icom_get_split_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL * icom_set_vfo,icom_get_mode works for this rig */ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; ENTERFUNC; if ((rs->targetable_vfo & RIG_TARGETABLE_MODE) && rs->current_vfo != RIG_VFO_MEM) { RETURNFUNC(icom_get_mode(rig, vfo, tx_mode, tx_width)); } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC(retval); } if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(retval); } /* * icom_set_split_freq_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * icom_set_vfo,icom_set_mode works for this rig */ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int split_assumed = 0; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rs->current_vfo)); // If the user is asking to set split on VFO_CURR we'll assume split mode // WSJT-X calls this function before turning on split mode if (vfo == RIG_VFO_CURR) { split_assumed = 1; } if (rs->current_vfo == RIG_VFO_NONE) { HAMLIB_TRACE; icom_set_default_vfo(rig); } if (rs->current_vfo != RIG_VFO_MEM) { if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (rs->targetable_vfo & RIG_TARGETABLE_MODE)) { retval = icom_set_freq(rig, vfo, tx_freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(icom_set_mode(rig, vfo, tx_mode, tx_width)); } } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC2(retval); } RETURNFUNC2(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B && (split_assumed || CACHE(rig)->split != RIG_SPLIT_OFF)) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } } rig_debug(RIG_DEBUG_VERBOSE, "%s: before get_split_vfos rx_vfo=%s tx_vfo=%s\n", __func__, rig_strvfo(rs->rx_vfo), rig_strvfo(rs->tx_vfo)); if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC2(retval); } // WSJT-X calls this function before setting split // So in this case we have to force the tx_vfo if (split_assumed && vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: split_assumed so tx_vfo=%s\n", __func__, rig_strvfo(vfo)); tx_vfo = VFO_HAS_A_B_ONLY ? RIG_VFO_B : RIG_VFO_SUB; } rig_debug(RIG_DEBUG_VERBOSE, "%s: after get_split_vfos rx_vfo=%s tx_vfo=%s\n", __func__, rig_strvfo(rs->rx_vfo), rig_strvfo(rs->tx_vfo)); // if not asking for RIG_VFO_CURR we'll use the requested VFO in the function call as tx_vfo if (CACHE(rig)->split == RIG_SPLIT_OFF && vfo != RIG_VFO_CURR) { tx_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: split not on so using requested vfo=%s\n", __func__, rig_strvfo(tx_vfo)); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_FREQ) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC2(retval); } if (RIG_OK != (retval = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC2(retval); } HAMLIB_TRACE; if (!(rs->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC2(retval); } if (VFO_HAS_A_B && CACHE(rig)->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } RETURNFUNC2(retval); } /* * icom_get_split_freq_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * rx_mode!=NULL, rx_width!=NULL, tx_mode!=NULL, tx_width!=NULL * icom_set_vfo,icom_get_mode works for this rig */ int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); vfo_t rx_vfo, tx_vfo; int retval; ENTERFUNC; if (rs->current_vfo != RIG_VFO_MEM) { if ((rs->targetable_vfo & RIG_TARGETABLE_FREQ) && (rs->targetable_vfo & RIG_TARGETABLE_MODE)) { retval = icom_get_freq(rig, vfo, tx_freq); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(icom_get_mode(rig, vfo, tx_mode, tx_width)); } } /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } if (RIG_OK != (retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { RETURNFUNC(retval); } RETURNFUNC(retval); } /* broken if user changes split on rig :( */ if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } } if (RIG_OK != (retval = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq))) { RETURNFUNC(retval); } if (RIG_OK != (retval = rig->caps->get_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { RETURNFUNC(retval); } HAMLIB_TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, rx_vfo))) { RETURNFUNC(retval); } if (VFO_HAS_A_B_ONLY && CACHE(rig)->split != RIG_SPLIT_OFF) { /* Re-enable split */ retval = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } } RETURNFUNC(retval); } /* * icom_set_split * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo) { struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); const struct icom_priv_caps *priv_caps = rig->caps->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int split_sc; /* For Icom which VFO is active for this call is not important * S VFOA 1 VFOB -- RX on VFOA, TX on VFOB * S VFOB 1 VFOA -- RX on VFOB, TX on VFOA * S Main 1 Sub -- RX on Main, TX on Sub * S Sub 1 Main -- RX on Sub, TX on Main */ rig_debug(RIG_DEBUG_VERBOSE, "%s called rx_vfo='%s', split=%d, tx_vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(rx_vfo), split, rig_strvfo(tx_vfo), rig_strvfo(rs->current_vfo)); // This should automatically switch between satmode on/off based on the requested split rx_vfo if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { int satmode = 0; // Check SATMODE status, because it affects commands related to split rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); if ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB) && !cachep->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: requesting split for Main/Sub VFO and satmode is OFF so turning satmode ON\n", __func__); retval = rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 1); // Split cannot be turned on in satmode, so return after enabling satmode RETURNFUNC2(retval); } else if ((tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B) && cachep->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: requesting split for VFO A/B and satmode is ON so turning satmode OFF\n", __func__); rig_set_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, 0); } else if ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB) && cachep->satmode && split == RIG_SPLIT_ON) { rig_debug(RIG_DEBUG_VERBOSE, "%s: requesting split for Main/Sub VFO and rig is already in satmode so setting split on " "is redundant and will result in an error, returning OK\n", __func__); // Return OK as satmode is a split mode and gpredict wants to see the OK response here RETURNFUNC2(RIG_OK); } } if (rs->current_vfo != rx_vfo && rx_vfo != RIG_VFO_CURR) { // Icom split command requires switching to the RX VFO first retval = rig_set_vfo(rig, rx_vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } switch (split) { case RIG_SPLIT_OFF: split_sc = S_SPLT_OFF; break; case RIG_SPLIT_ON: split_sc = S_SPLT_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %d", __func__, split); RETURNFUNC2(-RIG_EINVAL); } if (priv_caps->dualwatch_split) { int wvfo = (tx_vfo & (RIG_VFO_A | RIG_VFO_MAIN)) ? S_SUB : S_MAIN; retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, split_sc); if (retval != RIG_OK) { RETURNFUNC2(retval); } retval = icom_transaction(rig, C_SET_VFO, wvfo, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } else { retval = icom_transaction(rig, C_CTL_SPLT, split_sc, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: curr_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n", __func__, rig_strvfo(rs->current_vfo), rig_strvfo(rx_vfo), rig_strvfo(tx_vfo), split); RETURNFUNC2(RIG_OK); } /* * icom_get_split_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL, split!=NULL * * Does not appear to be supported by any mode? * \sa icom_mem_get_split_vfo() */ int icom_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo) { unsigned char splitbuf[MAXFRAMELEN]; int split_len, retval, satmode = 0; struct rig_state *rs = STATE(rig); ENTERFUNC; retval = icom_transaction(rig, C_CTL_SPLT, -1, NULL, 0, splitbuf, &split_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: CTL_SPLT failed?\n", __func__); RETURNFUNC(retval); } /* * splitbuf should contain Cn,Sc */ split_len--; if (split_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, split_len); RETURNFUNC(-RIG_ERJCTED); } switch (splitbuf[1]) { case S_SPLT_OFF: *split = RIG_SPLIT_OFF; break; case S_SPLT_ON: *split = RIG_SPLIT_ON; break; // The same command indicates repeater shift state, which means that split is off case S_DUP_OFF: case S_DUP_M: case S_DUP_P: case S_DUP_DD_RPS: *split = RIG_SPLIT_OFF; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %d", __func__, splitbuf[1]); RETURNFUNC(-RIG_EPROTO); } if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { // Check SATMODE status, because it affects commands related to split rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } // Update cache early for icom_get_split_vfos() CACHE(rig)->split = *split; icom_get_split_vfos(rig, &rs->rx_vfo, &rs->tx_vfo); *tx_vfo = rs->tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: rx_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n", __func__, rig_strvfo(rx_vfo), rig_strvfo(rs->rx_vfo), rig_strvfo(rs->tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * icom_mem_get_split_vfo * Assumes rig!=NULL, STATE(rig)->priv!=NULL, split!=NULL */ int icom_mem_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval; ENTERFUNC; /* this hacks works only when in memory mode * I have no clue how to detect split in regular VFO mode */ if (STATE(rig)->current_vfo != RIG_VFO_MEM || !rig_has_vfo_op(rig, RIG_OP_XCHG)) { *split = CACHE(rig)->split; // we set this but still return ENAVAIL RETURNFUNC(-RIG_ENAVAIL); } retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval == RIG_OK) { *split = RIG_SPLIT_ON; /* get it back to normal */ retval = icom_vfo_op(rig, vfo, RIG_OP_XCHG); if (retval != RIG_OK) { RETURNFUNC(retval); } } else if (retval == -RIG_ERJCTED) { *split = RIG_SPLIT_OFF; } else { /* this is really an error! */ RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_ts * Assumes rig!=NULL, rig->caps->priv!=NULL */ int icom_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { const struct icom_priv_caps *priv_caps; unsigned char ackbuf[MAXFRAMELEN]; int i, ack_len = sizeof(ackbuf), retval; int ts_sc = 0; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if (priv_caps->ts_sc_list[i].ts == ts) { ts_sc = priv_caps->ts_sc_list[i].sc; break; } } if (i >= HAMLIB_TSLSTSIZ) { RETURNFUNC(-RIG_EINVAL); /* not found, unsupported */ } retval = icom_transaction(rig, C_SET_TS, ts_sc, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ts * Assumes rig!=NULL, rig->caps->priv!=NULL, ts!=NULL * NOTE: seems not to work (tested on IC-706MkIIG), please report --SF Not available on 746pro */ int icom_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { const struct icom_priv_caps *priv_caps; unsigned char tsbuf[MAXFRAMELEN]; int ts_len, i, retval; ENTERFUNC; priv_caps = (const struct icom_priv_caps *) rig->caps->priv; retval = icom_transaction(rig, C_SET_TS, -1, NULL, 0, tsbuf, &ts_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * tsbuf should contain Cn,Sc */ ts_len--; if (ts_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ts_len); RETURNFUNC(-RIG_ERJCTED); } for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if (priv_caps->ts_sc_list[i].sc == tsbuf[1]) { *ts = priv_caps->ts_sc_list[i].ts; break; } } if (i >= HAMLIB_TSLSTSIZ) { RETURNFUNC(-RIG_EPROTO); /* not found, unsupported */ } RETURNFUNC(RIG_OK); } /* * icom_set_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char fctbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int fct_len, ack_len, retval; int fct_cn, fct_sc; /* Command Number, Subcommand */ struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; ENTERFUNC; const struct icom_priv_caps *priv_caps = rig->caps->priv; const struct cmdparams *extcmds = priv_caps->extcmds; int i; value_t value = { .i = status }; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_FUNC && extcmds[i].id.s == func) { RETURNFUNC(icom_set_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], value)); } } fctbuf[0] = status ? 0x01 : 0x00; fct_len = 1; switch (func) { case RIG_FUNC_NB: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NB; break; case RIG_FUNC_COMP: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_COMP; break; case RIG_FUNC_VOX: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VOX; break; case RIG_FUNC_TONE: /* repeater tone */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TONE; break; case RIG_FUNC_TSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TSQL; break; case RIG_FUNC_SBKIN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_BKIN; if (status != 0) { fctbuf[0] = 0x01; } else { fctbuf[0] = 0x00; } break; case RIG_FUNC_FBKIN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_BKIN; if (status != 0) { fctbuf[0] = 0x02; } else { fctbuf[0] = 0x00; } break; case RIG_FUNC_ANF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_ANF; break; case RIG_FUNC_NR: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NR; break; case RIG_FUNC_APF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_APF; break; case RIG_FUNC_MON: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MON; break; case RIG_FUNC_MN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MN; break; case RIG_FUNC_RF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_RF; break; case RIG_FUNC_VSC: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VSC; break; case RIG_FUNC_LOCK: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DIAL_LK; break; case RIG_FUNC_AFC: /* IC-910H */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_AFC; break; case RIG_FUNC_SCOPE: fct_cn = C_CTL_SCP; fct_sc = S_SCP_STS; fctbuf[0] = status; fct_len = 1; break; case RIG_FUNC_SPECTRUM: fct_cn = C_CTL_SCP; fct_sc = S_SCP_DOP; fctbuf[0] = status; fct_len = 1; break; case RIG_FUNC_SPECTRUM_HOLD: fct_cn = C_CTL_SCP; fct_sc = S_SCP_HLD; fct_len = 2; fctbuf[0] = icom_get_spectrum_vfo(rig, vfo); fctbuf[1] = status; break; case RIG_FUNC_RESUME: /* IC-910H & IC-746-Pro */ fct_cn = C_CTL_SCAN; fct_sc = status ? S_SCAN_RSMON : S_SCAN_RSMOFF; fct_len = 0; break; case RIG_FUNC_CSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_CSQL; break; case RIG_FUNC_DSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DSSQL; if (status <= 2) { fctbuf[0] = status; } else { fctbuf[0] = 0; } break; case RIG_FUNC_AFLT: fct_cn = C_CTL_MEM; fct_sc = S_MEM_AFLT; break; case RIG_FUNC_ANL: fct_cn = C_CTL_MEM; fct_sc = S_MEM_ANL; break; case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ fct_cn = C_CTL_MEM; fct_sc = S_FUNC_IPPLUS; break; case RIG_FUNC_RIT: fct_cn = C_CTL_RIT; fct_sc = S_RIT; break; case RIG_FUNC_XIT: fct_cn = C_CTL_RIT; fct_sc = S_XIT; break; case RIG_FUNC_TUNER: fct_cn = C_CTL_PTT; fct_sc = S_ANT_TUN; break; case RIG_FUNC_DUAL_WATCH: if ((RIG_IS_IC9100) || (RIG_IS_IC9700) || (RIG_IS_ID5100)) { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_DUALMODE; } else { fct_cn = C_SET_VFO; fct_sc = status ? S_DUAL_ON : S_DUAL_OFF; fct_len = 0; } break; case RIG_FUNC_SATMODE: if (RIG_IS_IC910) { // Is the 910 the only one that uses this command? fct_cn = C_CTL_MEM; fct_sc = S_MEM_SATMODE910; } else { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_SATMODE; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if (ack_len != 1) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ack_len); RETURNFUNC(-RIG_EPROTO); } if (func == RIG_FUNC_SATMODE) { int satmode = status ? 1 : 0; if (satmode != CACHE(rig)->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): changed satmode=%d\n", __func__, __LINE__, satmode); // Reset x25cmdfails to current status, because it fails in SATMODE icom_set_x25x26_ability(rig, satmode ? 1 : -1); // Reset x1cx03cmdfails to test it again priv->x1cx03cmdfails = 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): satmode=%d\n", __func__, __LINE__, satmode); } CACHE(rig)->satmode = satmode; icom_satmode_fix(rig, satmode); // Turning satmode ON/OFF can change the TX/RX VFOs // Split is OFF always in satmode if (VFO_HAS_MAIN_SUB_A_B_ONLY) { vfo_t tx_vfo; split_t split; // Update split status (updates rig state/cache internally) retval = icom_get_split_vfo(rig, RIG_VFO_CURR, &split, &tx_vfo); if (retval != RIG_OK) { RETURNFUNC(retval); } } } RETURNFUNC(RIG_OK); } /* * icom_get_func * Assumes rig!=NULL, STATE(rig)->priv!=NULL * FIXME: IC8500 and no-sc, any support? */ int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int fct_cn, fct_sc; /* Command Number, Subcommand */ unsigned char fctbuf[MAXFRAMELEN]; int fct_len = 0; const struct icom_priv_caps *priv_caps = rig->caps->priv; const struct cmdparams *extcmds = priv_caps->extcmds; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ENTERFUNC; value_t value; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { //rig_debug(RIG_DEBUG_TRACE, "%s: i=%d\n", __func__, i); if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_FUNC && extcmds[i].id.s == func) { int result = icom_get_cmd(rig, vfo, (struct cmdparams *)&extcmds[i], &value); if (result == RIG_OK) { *status = value.i; } RETURNFUNC(result); } } switch (func) { case RIG_FUNC_NB: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NB; break; case RIG_FUNC_COMP: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_COMP; break; case RIG_FUNC_VOX: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VOX; break; case RIG_FUNC_TONE: /* repeater tone */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TONE; break; case RIG_FUNC_TSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_TSQL; break; case RIG_FUNC_SBKIN: /* returns 1 for semi and 2 for full adjusted below */ case RIG_FUNC_FBKIN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_BKIN; break; case RIG_FUNC_ANF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_ANF; break; case RIG_FUNC_NR: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_NR; break; case RIG_FUNC_APF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_APF; break; case RIG_FUNC_MON: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MON; break; case RIG_FUNC_MN: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_MN; break; case RIG_FUNC_RF: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_RF; break; case RIG_FUNC_VSC: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_VSC; break; case RIG_FUNC_LOCK: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DIAL_LK; break; case RIG_FUNC_AFC: /* IC-910H */ fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_AFC; break; case RIG_FUNC_SCOPE: fct_cn = C_CTL_SCP; fct_sc = S_SCP_STS; break; case RIG_FUNC_SPECTRUM: fct_cn = C_CTL_SCP; fct_sc = S_SCP_DOP; break; case RIG_FUNC_SPECTRUM_HOLD: fct_cn = C_CTL_SCP; fct_sc = S_SCP_HLD; fctbuf[0] = icom_get_spectrum_vfo(rig, vfo); fct_len = 1; break; case RIG_FUNC_AIP: /* IC-R8600 IP+ function, misusing AIP since RIG_FUNC_ word is full (32 bit) */ fct_cn = C_CTL_MEM; /* 1a */ fct_sc = S_FUNC_IPPLUS; break; case RIG_FUNC_CSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_CSQL; break; case RIG_FUNC_DSQL: fct_cn = C_CTL_FUNC; fct_sc = S_FUNC_DSSQL; break; case RIG_FUNC_AFLT: fct_cn = C_CTL_MEM; fct_sc = S_MEM_AFLT; break; case RIG_FUNC_ANL: fct_cn = C_CTL_MEM; fct_sc = S_MEM_ANL; break; case RIG_FUNC_RIT: fct_cn = C_CTL_RIT; fct_sc = S_RIT; break; case RIG_FUNC_XIT: fct_cn = C_CTL_RIT; fct_sc = S_XIT; break; case RIG_FUNC_TUNER: fct_cn = C_CTL_PTT; fct_sc = S_ANT_TUN; break; case RIG_FUNC_DUAL_WATCH: if ((RIG_IS_IC9100) || (RIG_IS_IC9700) || (RIG_IS_ID5100)) { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_DUALMODE; } else { fct_cn = C_SET_VFO; fct_sc = S_DUAL; } break; case RIG_FUNC_SATMODE: if (RIG_IS_IC910) { // Is the 910 the only one that uses this command? fct_cn = C_CTL_MEM; fct_sc = S_MEM_SATMODE910; } else { fct_cn = C_CTL_FUNC; fct_sc = S_MEM_SATMODE; } break; case RIG_FUNC_OVF_STATUS: { fct_cn = C_RD_SQSM; fct_sc = S_OVF; break; } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s\n", __func__, rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, fct_cn, fct_sc, fctbuf, fct_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if (ack_len != (3 + fct_len)) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ack_len); RETURNFUNC(-RIG_EPROTO); } if (func == RIG_FUNC_FBKIN) { *status = ackbuf[2] == 2 ? 1 : 0; } else if (func == RIG_FUNC_SATMODE) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = rs->priv; int satmode = ackbuf[2 + fct_len]; *status = satmode; if (satmode != CACHE(rig)->satmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): changed satmode=%d\n", __func__, __LINE__, satmode); // Reset x25cmdfails to current status, because it fails in SATMODE icom_set_x25x26_ability(rig, satmode ? 1 : -1); // Reset x1cx03cmdfails to test it again priv->x1cx03cmdfails = 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): satmode=%d\n", __func__, __LINE__, satmode); } CACHE(rig)->satmode = satmode; icom_satmode_fix(rig, satmode); } else { *status = ackbuf[2 + fct_len]; } RETURNFUNC(RIG_OK); } /* * icom_set_parm * Assumes rig!=NULL * * NOTE: Most of the parm commands are rig-specific. * * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands. * * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used. */ int icom_set_parm(RIG *rig, setting_t parm, value_t val) { ENTERFUNC; int i; const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *extcmds = priv->extcmds; for (i = 0; extcmds && extcmds[i].id.s != 0; i++) { if (extcmds[i].cmdparamtype == CMD_PARAM_TYPE_PARM && extcmds[i].id.s == parm) { RETURNFUNC(icom_set_cmd(rig, RIG_VFO_NONE, (struct cmdparams *)&extcmds[i], val)); } } switch (parm) { case RIG_PARM_ANN: { int ann_mode; switch (val.i) { case RIG_ANN_OFF: ann_mode = S_ANN_ALL; break; case RIG_ANN_FREQ: ann_mode = S_ANN_FREQ; break; case RIG_ANN_RXMODE: ann_mode = S_ANN_MODE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported RIG_PARM_ANN %d\n", __func__, val.i); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0)); } default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_parm %s\n", __func__, rig_strparm(parm)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } const char *icom_get_band(RIG *rig, int band) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); const char *s = rig_get_band_str(rig, band, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: %d=%s\n", __func__, band, s); return s; } /* * icom_get_parm * Assumes rig!=NULL * * NOTE: Most of the parm commands are rig-specific. * * See the IC-7300 backend how to implement them for newer rigs that have 0x1A 0x05-based commands. * * For older rigs, see the IC-R75 backend where icom_set_raw()/icom_get_raw() are used. */ int icom_get_parm(RIG *rig, setting_t parm, value_t *val) { ENTERFUNC; const struct icom_priv_caps *priv = rig->caps->priv; const struct cmdparams *cmd = priv->extcmds; int i; for (i = 0; cmd && cmd[i].id.s != 0; i++) { if (cmd[i].cmdparamtype == CMD_PARAM_TYPE_PARM && cmd[i].id.s == parm) { int retval = icom_get_cmd(rig, RIG_VFO_NONE, (struct cmdparams *)&cmd[i], val); if (parm == RIG_PARM_BANDSELECT) { char *s = (char *)icom_get_band(rig, val->i); val->s = s; } RETURNFUNC(retval); } } switch (parm) { default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_parm %s", __func__, rig_strparm(parm)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } /* * icom_set_ctcss_tone * Assumes rig!=NULL, STATE(rig)->priv!=NULL * * Works for 746 pro and should work for 756 xx and 7800 */ int icom_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int tone_len, ack_len = sizeof(ackbuf), retval; ENTERFUNC; caps = rig->caps; if (caps->ctcss_list) { int i; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { RETURNFUNC(-RIG_EINVAL); } } /* Sent as frequency in tenth of Hz */ tone_len = 3; to_bcd_be(tonebuf, tone, tone_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_RPTR, tonebuf, tone_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ctcss_tone * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_RPTR, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* cn,sc,data*3 */ if (tone_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, tonebuf[0], tone_len); RETURNFUNC(-RIG_ERJCTED); } tone_len -= 2; *tone = from_bcd_be(tonebuf + 2, tone_len * 2); if (!caps->ctcss_list) { RETURNFUNC(RIG_OK); } /* check this tone exists. That's better than nothing. */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == *tone) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%#.2x)\n", __func__, tonebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_ctcss_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int tone_len, ack_len = sizeof(ackbuf), retval; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { RETURNFUNC(-RIG_EINVAL); } /* Sent as frequency in tenth of Hz */ tone_len = 3; to_bcd_be(tonebuf, tone, tone_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_SQL, tonebuf, tone_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_ctcss_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { const struct rig_caps *caps; unsigned char tonebuf[MAXFRAMELEN]; int tone_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_SQL, NULL, 0, tonebuf, &tone_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if (tone_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, tonebuf[0], tone_len); RETURNFUNC(-RIG_ERJCTED); } tone_len -= 2; *tone = from_bcd_be(tonebuf + 2, tone_len * 2); /* check this tone exists. That's better than nothing. */ for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == *tone) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%#.2x)\n", __func__, tonebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_dcs_code * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int code_len, ack_len = sizeof(ackbuf), retval; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == code) { break; } } if (caps->dcs_list[i] != code) { RETURNFUNC(-RIG_EINVAL); } /* DCS Polarity ignored, by setting code_len to 3 it's forced to 0 (= Tx:norm, Rx:norm). */ code_len = 3; to_bcd_be(codebuf, code, code_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, codebuf, code_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_dcs_code * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN]; int code_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, NULL, 0, codebuf, &code_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* cn,sc,data*3 */ if (code_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, codebuf[0], code_len); RETURNFUNC(-RIG_ERJCTED); } /* buf is cn,sc, polarity, code_lo, code_hi, so code bytes start at 3, len is 2 polarity is not decoded yet, hard to do without breaking ABI */ code_len -= 3; *code = from_bcd_be(codebuf + 3, code_len * 2); /* check this code exists. That's better than nothing. */ for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == *code) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: DTCS NG (%#.2x)\n", __func__, codebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_dcs_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int code_len, ack_len = sizeof(ackbuf), retval; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == code) { break; } } if (caps->dcs_list[i] != code) { RETURNFUNC(-RIG_EINVAL); } /* DCS Polarity ignored, by setting code_len to 3 it's forced to 0 (= Tx:norm, Rx:norm). */ code_len = 3; to_bcd_be(codebuf, code, code_len * 2); retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, codebuf, code_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_dcs_sql * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { const struct rig_caps *caps; unsigned char codebuf[MAXFRAMELEN]; int code_len, retval; int i; ENTERFUNC; caps = rig->caps; retval = icom_transaction(rig, C_SET_TONE, S_TONE_DTCS, NULL, 0, codebuf, &code_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* cn,sc,data*3 */ if (code_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, codebuf[0], code_len); RETURNFUNC(-RIG_ERJCTED); } /* buf is cn,sc, polarity, code_lo, code_hi, so code bytes start at 3, len is 2 polarity is not decoded yet, hard to do without breaking ABI */ code_len -= 3; *code = from_bcd_be(codebuf + 3, code_len * 2); /* check this code exists. That's better than nothing. */ for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == *code) { RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: DTCS NG (%#.2x)\n", __func__, codebuf[2]); RETURNFUNC(-RIG_EPROTO); } /* * icom_set_powerstat * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_powerstat(RIG *rig, powerstat_t status) { unsigned char ackbuf[200]; int ack_len = sizeof(ackbuf), retval = RIG_OK; int pwr_sc; // so we'll do up to 150 for 115,200 int fe_max = 150; unsigned char fe_buf[fe_max]; // for FE's to power up int i; int retry; short retry_save, timeout_retry_save; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called status=%d\n", __func__, (int) status); // elimininate retries to speed this up // especially important when rig is not turned on retry_save = rp->retry; timeout_retry_save = rp->timeout_retry; rp->retry = 0; rp->timeout_retry = 0; switch (status) { case RIG_POWER_ON: // ic7300 manual says ~150 for 115,200 // we'll just send a few more to be sure for all speeds switch (rp->parm.serial.rate) { case 4800: fe_max = 7; break; case 9600: fe_max = 13; break; case 19200: fe_max = 25; break; case 38400: fe_max = 50; break; case 57600: fe_max = 75; break; case 115200: default: fe_max = 150; } memset(fe_buf, 0xfe, fe_max); // sending more than enough 0xfe's to wake up the rs232 write_block(rp, fe_buf, fe_max); // need to wait a bit for RigPI and others to queue the echo hl_usleep(400 * 1000); // we'll try 0x18 0x01 now -- should work on STBY rigs too pwr_sc = S_PWR_ON; fe_buf[0] = 0; priv->serial_USB_echo_off = 1; retval = icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len); float sec_wait = 5.5; // 5.5 worked for IC-9700 -- we default to worst-case-found if (RIG_IS_IC7300) { sec_wait = 3.8; } rig_debug(RIG_DEBUG_VERBOSE, "%s: waiting %g seconds for rig to wake up\n", __func__, sec_wait); hl_usleep(sec_wait * 1000 * 1000); // some are slow to start up -- may need to add more rigs // poweron == 0 means never powered -- == 2 means CAT turned off if (priv->poweron == 0 || priv->poweron == 2) { int echo_status = -1; for (i = 0; i < 10 && echo_status < 0; ++i) { echo_status = icom_get_usb_echo_off(rig); if (echo_status < 0) { hl_usleep(500 * 1000); } } if (echo_status >= 0) { priv->poweron = 1; } rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; return RIG_OK; } break; default: pwr_sc = S_PWR_OFF; fe_buf[0] = 0; retval = icom_transaction(rig, C_SET_PWR, pwr_sc, NULL, 0, ackbuf, &ack_len); priv->poweron = 2; } i = 0; retry = 3; if (status == RIG_POWER_ON) // wait for wakeup only { for (i = 0; i < retry; ++i) // up to 10 attempts { freq_t freq; // need to see if echo is on or not first // until such time as rig is awake we don't know retval = icom_get_usb_echo_off(rig); if (retval == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_WARN, "%s: get_usb_echo_off timeout...try#%d\n", __func__, i + 1); continue; } // Use get_freq as all rigs should respond to this retval = rig_get_freq(rig, RIG_VFO_CURR, &freq); if (retval == RIG_OK) { int satmode; if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { // Getting satmode state updates RX/TX VFOs internally rig_get_func(rig, RIG_VFO_CURR, RIG_FUNC_SATMODE, &satmode); } rs->current_vfo = icom_current_vfo(rig); rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; RETURNFUNC2(retval); } else { rig_debug(RIG_DEBUG_TRACE, "%s: get_freq err=%s\n", __func__, rigerror(retval)); } rig_debug(RIG_DEBUG_TRACE, "%s: Wait %d of %d for get_powerstat\n", __func__, i + 1, retry); } } rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; if (i == retry) { rig_debug(RIG_DEBUG_TRACE, "%s: Wait failed for get_powerstat\n", __func__); // close and re-open the rig // on linux the USB gets reset during power on rig_close(rig); sleep(1); rig_open(rig); retval = -RIG_ETIMEOUT; } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: retval != RIG_OK, =%s\n", __func__, rigerror(retval)); RETURNFUNC2(retval); } if (status == RIG_POWER_OFF && (ack_len != 1 || ackbuf[0] != ACK)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC2(-RIG_ERJCTED); } RETURNFUNC2(RIG_OK); } /* * icom_get_powerstat * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_get_powerstat(RIG *rig, powerstat_t *status) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; *status = RIG_POWER_OFF; // default return until proven otherwise /* r75 has no way to get power status, so fake it */ 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 */ int cmd_len = 1; unsigned char cmdbuf[MAXFRAMELEN]; cmdbuf[0] = S_PRM_TIME; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_MODE_SLCT, cmdbuf, cmd_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = ((ack_len == 6) && (ackbuf[0] == C_CTL_MEM)) ? RIG_POWER_ON : RIG_POWER_OFF; } HAMLIB_TRACE; 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; hamlib_port_t *rp = RIGPORT(rig); short retry_save = rp->retry; short timeout_retry_save = rp->timeout_retry; HAMLIB_TRACE; rp->retry = 0; rp->timeout_retry = 0; retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: get freq failed, assuming power is off\n", __func__); } HAMLIB_TRACE; rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; // Assume power is OFF if get_freq fails *status = retval == RIG_OK ? RIG_POWER_ON : RIG_POWER_OFF; // Modify rig_state powerstat directly to reflect power ON/OFF status, but return the result of rig_get_freq, // because the error could indicate other connectivity issues too STATE(rig)->powerstat = *status; RETURNFUNC(retval); } else { retval = icom_transaction(rig, C_SET_PWR, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { // Assume power is OFF if getting power status fails // Modify rig_state powerstat directly to reflect power ON/OFF status, but return the result of rig_get_freq, // because the error could indicate other connectivity issues too rig_debug(RIG_DEBUG_WARN, "%s: get powerstat failed, assuming power is off\n", __func__); STATE(rig)->powerstat = RIG_POWER_OFF; RETURNFUNC(retval); } *status = ackbuf[1] == S_PWR_ON ? RIG_POWER_ON : RIG_POWER_OFF; } RETURNFUNC(RIG_OK); } /* * icom_set_mem * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char membuf[2]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int chan_len; ENTERFUNC; chan_len = ch < 100 ? 1 : 2; to_bcd_be(membuf, ch, chan_len * 2); retval = icom_transaction(rig, C_SET_MEM, -1, membuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_bank * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_bank(RIG *rig, vfo_t vfo, int bank) { unsigned char bankbuf[2]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; to_bcd_be(bankbuf, bank, BANK_NB_LEN * 2); retval = icom_transaction(rig, C_SET_MEM, S_BANK, bankbuf, CHAN_NB_LEN, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_set_ant * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { unsigned char antopt[2]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval, i_ant = 0; int antopt_len = 0; const struct icom_priv_caps *priv_caps = (const struct icom_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x, option=%d, antack_len=%d\n", __func__, ant, option.i, priv_caps->antack_len); // query the antennas once and find out how many we have if (ant >= rig_idx2setting(priv_caps->ant_count)) { RETURNFUNC2(-RIG_EINVAL); } if (ant > RIG_ANT_4) { RETURNFUNC2(-RIG_EDOM); } switch (ant) { case RIG_ANT_1: i_ant = 0; break; case RIG_ANT_2: i_ant = 1; break; case RIG_ANT_3: i_ant = 2; break; case RIG_ANT_4: i_ant = 3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported ant %#x", __func__, ant); RETURNFUNC2(-RIG_EINVAL); } if (priv_caps->antack_len == 0) // we need to find out the antack_len { ant_t tmp_ant, ant_tx, ant_rx; int ant0 = 0; value_t tmp_option; retval = rig_get_ant(rig, vfo, ant0, &tmp_option, &tmp_ant, &ant_tx, &ant_rx); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_ant error: %s \n", __func__, rigerror(retval)); RETURNFUNC2(retval); } } // Some rigs have 3-byte ant cmd so there is an option to be set too if (priv_caps->antack_len == 3) { if (option.i != 0 && option.i != 1) { rig_debug(RIG_DEBUG_ERR, "%s: option.i != 0 or 1, ==%d?\n", __func__, option.i); RETURNFUNC2(-RIG_EINVAL); } antopt_len = 1; antopt[0] = option.i; // we have to set the rx option by itself apparently rig_debug(RIG_DEBUG_TRACE, "%s: setting antopt=%d\n", __func__, antopt[0]); retval = icom_transaction(rig, C_CTL_ANT, i_ant, antopt, antopt_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d, antopt=0x%02x\n", __func__, priv_caps->antack_len, antopt_len, antopt[0]); } else if (priv_caps->antack_len == 2) { antopt_len = 0; rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d\n", __func__, priv_caps->antack_len, antopt_len); } else { rig_debug(RIG_DEBUG_TRACE, "%s: antack_len=%d so antopt_len=%d\n", __func__, priv_caps->antack_len, antopt_len); antopt_len = 0; rig_debug(RIG_DEBUG_ERR, "%s: rig does not have antenna select? antack_len=%d\n", __func__, priv_caps->antack_len); } rig_debug(RIG_DEBUG_TRACE, "%s: i_ant=%d, antopt=0x%02x, antopt_len=%d\n", __func__, i_ant, antopt[0], antopt_len); retval = icom_transaction(rig, C_CTL_ANT, i_ant, antopt, antopt_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC2(retval); } RETURNFUNC2(RIG_OK); } /* * icom_get_ant * Assumes rig!=NULL, STATE(rig)->priv!=NULL * only meaningful for HF */ int icom_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval = -RIG_EINTERNAL; struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, ant=0x%02x\n", __func__, ant); if (ant != RIG_ANT_CURR) { ant = rig_setting2idx(ant); if (ant >= priv_caps->ant_count) { rig_debug(RIG_DEBUG_ERR, "%s: ant index=%u > ant_count=%d\n", __func__, ant, priv_caps->ant_count); RETURNFUNC2(-RIG_EINVAL); } } // Should be able to use just C_CTL_ANT for 1 or 2 antennas hopefully if (ant == RIG_ANT_CURR || priv_caps->ant_count <= 2) { retval = icom_transaction(rig, C_CTL_ANT, -1, NULL, 0, ackbuf, &ack_len); } else if (RIG_IS_IC785X) { unsigned char buf[2]; buf[0] = 0x03; buf[1] = 0x05 + ant; *ant_curr = ant; retval = icom_transaction(rig, C_CTL_MEM, 0x05, buf, sizeof(buf), ackbuf, &ack_len); if (retval == RIG_OK) { option->i = ackbuf[4]; RETURNFUNC2(RIG_OK); } } else { rig_debug(RIG_DEBUG_ERR, "%s: asking for non-current antenna and ant_count==0?\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to implement ant control for this rig?\n", __func__); RETURNFUNC2(-RIG_EINVAL); } if (retval != RIG_OK) { RETURNFUNC2(retval); } // ack_len should be either 2 or 3 // ant cmd format is one of // 0x12 0xaa // 0x12 0xaa 0xrr // Where aa is a zero-base antenna number and rr is a binary for rx only if ((ack_len != 2 && ack_len != 3) || ackbuf[0] != C_CTL_ANT || ackbuf[1] > 3) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d, ant=%d\n", __func__, ackbuf[0], ack_len, ackbuf[1]); RETURNFUNC2(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_ERR, "%s: ackbuf= 0x%02x 0x%02x 0x%02x\n", __func__, ackbuf[0], ackbuf[1], ackbuf[2]); *ant_curr = *ant_tx = *ant_rx = rig_idx2setting(ackbuf[1]); // Note: with IC756/IC-756Pro/IC-7800 and more, ackbuf[2] deals with [RX ANT] // Hopefully any ack_len=3 can fit in the option field if (ack_len == 3) { option->i = ackbuf[2]; *ant_rx = rig_idx2setting(ackbuf[2]); } RETURNFUNC2(RIG_OK); } /* * icom_vfo_op, Mem/VFO operation * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { unsigned char mvbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN]; int mv_len = 0, ack_len = sizeof(ackbuf), retval; int mv_cn, mv_sc; int vfo_list; ENTERFUNC; switch (op) { case RIG_OP_CPY: mv_cn = C_SET_VFO; vfo_list = STATE(rig)->vfo_list; if ((vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)) { mv_sc = S_BTOA; } else if ((vfo_list & (RIG_VFO_MAIN | RIG_VFO_SUB)) == (RIG_VFO_MAIN | RIG_VFO_SUB)) { mv_sc = S_SUBTOMAIN; } else { RETURNFUNC(-RIG_ENAVAIL); } break; case RIG_OP_XCHG: mv_cn = C_SET_VFO; mv_sc = S_XCHNG; break; case RIG_OP_FROM_VFO: mv_cn = C_WR_MEM; mv_sc = -1; break; case RIG_OP_TO_VFO: mv_cn = C_MEM2VFO; mv_sc = -1; break; case RIG_OP_MCL: mv_cn = C_CLR_MEM; mv_sc = -1; break; case RIG_OP_TUNE: mv_cn = C_CTL_PTT; mv_sc = S_ANT_TUN; mvbuf[0] = 2; mv_len = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mem/vfo op %#x", __func__, op); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, mv_cn, mv_sc, mvbuf, mv_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } // since we're messing with VFOs our cache may be invalid CACHE_RESET; if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK)) { // if we don't get ACK/NAK some serial corruption occurred // so we'll call it a timeout for retry purposes RETURNFUNC(-RIG_ETIMEOUT); } if (ack_len != 1 || ackbuf[0] != ACK) { if (op != RIG_OP_XCHG) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); } RETURNFUNC(-RIG_ERJCTED); } RETURNFUNC(RIG_OK); } /* * icom_scan, scan operation * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { unsigned char scanbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN]; int scan_len, ack_len = sizeof(ackbuf), retval; int scan_cn, scan_sc; vfo_t myvfo = vfo; ENTERFUNC; scan_len = 0; scan_cn = C_CTL_SCAN; // for current vfo just switch to VFO mode (we might be in MEM) if (myvfo == RIG_VFO_CURR) { myvfo = RIG_VFO_VFO; } switch (scan) { case RIG_SCAN_STOP: scan_sc = S_SCAN_STOP; break; case RIG_SCAN_VFO: case RIG_SCAN_MEM: HAMLIB_TRACE; retval = rig_set_vfo(rig, scan == RIG_SCAN_MEM ? RIG_VFO_MEM : myvfo); if (retval != RIG_OK) { RETURNFUNC(retval); } /* Looks like all the IC-R* have this command, * but some old models don't have it. * Should be put in icom_priv_caps ? */ if (rig->caps->rig_type == RIG_TYPE_RECEIVER && scan == RIG_SCAN_MEM) { scan_sc = S_SCAN_MEM2; } else { scan_sc = S_SCAN_START; } break; case RIG_SCAN_SLCT: HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_MEM); if (retval != RIG_OK) { RETURNFUNC(retval); } scan_sc = S_SCAN_START; break; case RIG_SCAN_PRIO: case RIG_SCAN_PROG: /* TODO: for SCAN_PROG, check this is an edge chan */ /* BTW, I'm wondering if this is possible with CI-V */ retval = icom_set_mem(rig, RIG_VFO_CURR, ch); if (retval != RIG_OK) { RETURNFUNC(retval); } HAMLIB_TRACE; retval = rig_set_vfo(rig, RIG_VFO_VFO); if (retval != RIG_OK) { RETURNFUNC(retval); } scan_sc = S_SCAN_START; break; case RIG_SCAN_DELTA: scan_sc = S_SCAN_DELTA; /* TODO: delta-f support */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported scan %#x\n", __func__, scan); RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, scan_cn, scan_sc, scanbuf, scan_len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_send_morse * Assumes rig!=NULL, msg!=NULL */ int icom_send_morse(RIG *rig, vfo_t vfo, const char *msg) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int len; int retry = 20; ENTERFUNC; len = strlen(msg); if (len > 30) { len = 30; } rig_debug(RIG_DEBUG_TRACE, "%s: %s\n", __func__, msg); morse_retry: retval = icom_transaction(rig, C_SND_CW, -1, (unsigned char *) msg, len, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { if (retval == -RIG_ERJCTED) { if (len == 1 && --retry > 0) { // 50 retries should be around 200ms --plenty of time to clear out some characters hl_usleep(10 * 1000); goto morse_retry; } } RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_stop_morse * Assumes rig!=NULL, msg!=NULL */ int icom_stop_morse(RIG *rig, vfo_t vfo) { unsigned char ackbuf[MAXFRAMELEN]; unsigned char cmd[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; cmd[0] = 0xff; retval = icom_transaction(rig, C_SND_CW, -1, (unsigned char *) cmd, 1, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int icom_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { const freq_range_t *range_list; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); range_list = rig_get_range(rig->caps->tx_range_list1, freq, mode); if (range_list == NULL) { *mwpower = power * 100000; // default to 100W if no range_list RETURNFUNC(RIG_OK); } rig_debug(RIG_DEBUG_VERBOSE, "%s: maxpower=%d\n", __func__, range_list->high_power); *mwpower = power * range_list->high_power; RETURNFUNC(RIG_OK); } int icom_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { int rig_id; ENTERFUNC; rig_id = rig->caps->rig_model; rig_debug(RIG_DEBUG_TRACE, "%s: passed mwpower = %u\n", __func__, mwpower); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %" PRIfreq " Hz\n", __func__, freq); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); if (mwpower > 100000) { RETURNFUNC(-RIG_EINVAL); } switch (rig_id) { default: /* Default to a 100W radio */ *power = ((float) mwpower / 100000); break; } RETURNFUNC(RIG_OK); } #if defined(HAVE_PTHREAD) static int icom_parse_spectrum_frame(RIG *rig, size_t length, const unsigned char *frame_data) { struct rig_caps *caps = rig->caps; struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) caps->priv; struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; struct icom_spectrum_scope_cache *cache; int division = (int) from_bcd(frame_data + 1, 1 * 2); int max_division = (int) from_bcd(frame_data + 2, 1 * 2); size_t spectrum_data_length_in_frame; const unsigned char *spectrum_data_start_in_frame; ENTERFUNC; // The first byte indicates spectrum scope ID/VFO: 0 = Main, 1 = Sub int spectrum_id = frame_data[0]; if (spectrum_id >= priv->spectrum_scope_count) { rig_debug(RIG_DEBUG_ERR, "%s: invalid spectrum scope ID from CI-V frame: %d\n", __func__, spectrum_id); RETURNFUNC(-RIG_EPROTO); } cache = &priv->spectrum_scope_cache[spectrum_id]; if (division == 1) { int spectrum_scope_mode = frame_data[3]; int out_of_range = frame_data[14]; cache->spectrum_mode = RIG_SPECTRUM_MODE_NONE; switch (spectrum_scope_mode) { case SCOPE_MODE_CENTER: cache->spectrum_mode = RIG_SPECTRUM_MODE_CENTER; cache->spectrum_center_freq = (freq_t) from_bcd(frame_data + 4, 5 * 2); cache->spectrum_span_freq = (freq_t) from_bcd(frame_data + 9, 5 * 2) * 2; cache->spectrum_low_edge_freq = cache->spectrum_center_freq - cache->spectrum_span_freq / 2; cache->spectrum_high_edge_freq = cache->spectrum_center_freq + cache->spectrum_span_freq / 2; break; case SCOPE_MODE_FIXED: cache->spectrum_mode = RIG_SPECTRUM_MODE_FIXED; case SCOPE_MODE_SCROLL_C: if (cache->spectrum_mode == RIG_SPECTRUM_MODE_NONE) { cache->spectrum_mode = RIG_SPECTRUM_MODE_CENTER_SCROLL; } case SCOPE_MODE_SCROLL_F: if (cache->spectrum_mode == RIG_SPECTRUM_MODE_NONE) { cache->spectrum_mode = RIG_SPECTRUM_MODE_FIXED_SCROLL; } cache->spectrum_low_edge_freq = (freq_t) from_bcd(frame_data + 4, 5 * 2); cache->spectrum_high_edge_freq = (freq_t) from_bcd(frame_data + 9, 5 * 2); cache->spectrum_span_freq = (cache->spectrum_high_edge_freq - cache->spectrum_low_edge_freq); cache->spectrum_center_freq = cache->spectrum_high_edge_freq - cache->spectrum_span_freq / 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown Icom spectrum scope mode: %d\n", __func__, spectrum_scope_mode); RETURNFUNC(-RIG_EPROTO); } spectrum_data_length_in_frame = length - 15; spectrum_data_start_in_frame = frame_data + 15; memset(cache->spectrum_data, 0, priv_caps->spectrum_scope_caps.spectrum_line_length); cache->spectrum_data_length = 0; cache->spectrum_metadata_valid = 1; rig_debug(RIG_DEBUG_TRACE, "%s: Spectrum line start: id=%d division=%d max_division=%d mode=%d center=%.0f span=%.0f low_edge=%.0f high_edge=%.0f oor=%d data_length=%d\n", __func__, spectrum_id, division, max_division, spectrum_scope_mode, cache->spectrum_center_freq, cache->spectrum_span_freq, cache->spectrum_low_edge_freq, cache->spectrum_high_edge_freq, out_of_range, (int)spectrum_data_length_in_frame); } else { spectrum_data_length_in_frame = length - 3; spectrum_data_start_in_frame = frame_data + 3; } if (spectrum_data_length_in_frame > 0) { int frame_length = priv_caps->spectrum_scope_caps.single_frame_data_length; int data_frame_index = (max_division > 1) ? (division - 2) : (division - 1); int offset = data_frame_index * frame_length; if (offset + spectrum_data_length_in_frame > priv_caps->spectrum_scope_caps.spectrum_line_length) { rig_debug(RIG_DEBUG_ERR, "%s: too much spectrum scope data received: %d bytes > %d bytes expected\n", __func__, (int)(offset + spectrum_data_length_in_frame), priv_caps->spectrum_scope_caps.spectrum_line_length); RETURNFUNC(-RIG_EPROTO); } memcpy(cache->spectrum_data + offset, spectrum_data_start_in_frame, spectrum_data_length_in_frame); cache->spectrum_data_length = offset + spectrum_data_length_in_frame; } if (cache->spectrum_metadata_valid && division == max_division) { struct rig_spectrum_line spectrum_line = { .id = spectrum_id, .data_level_min = priv_caps->spectrum_scope_caps.data_level_min, .data_level_max = priv_caps->spectrum_scope_caps.data_level_max, .signal_strength_min = priv_caps->spectrum_scope_caps.signal_strength_min, .signal_strength_max = priv_caps->spectrum_scope_caps.signal_strength_max, .spectrum_mode = cache->spectrum_mode, .center_freq = cache->spectrum_center_freq, .span_freq = cache->spectrum_span_freq, .low_edge_freq = cache->spectrum_low_edge_freq, .high_edge_freq = cache->spectrum_high_edge_freq, .spectrum_data_length = cache->spectrum_data_length, .spectrum_data = cache->spectrum_data, }; #if defined(HAVE_PTHREAD) rig_fire_spectrum_event(rig, &spectrum_line); #endif cache->spectrum_metadata_valid = 0; } RETURNFUNC(RIG_OK); } #endif int icom_is_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame) { if (frame_length < ACKFRMLEN) { return 0; } /* Spectrum scope data is not CI-V transceive data, but handled the same way as it is pushed by the rig */ // IC-7100 sends 0xe1 for broadcast frame? return frame[2] == BCASTID || frame[2] == C_SND_MODE || (frame[2] == CTRLID && frame[4] == C_CTL_SCP && frame[5] == S_SCP_DAT); } int icom_process_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; rmode_t mode; pbwidth_t width; ENTERFUNC; /* * the first 2 bytes must be 0xfe * the 3rd one 0x00 since this is transceive mode * the 4th one the emitter * then the command number * the rest is data * and don't forget one byte at the end for the EOM */ if (frame[2] != 0x00 || frame[2] == 0x01) { // just ignoring 0x01 for now // fe fe 01 94 1c 03 00 80 07 07 00 fd rig_debug(RIG_DEBUG_VERBOSE, "%s: 3rd byte not 0x00 or is 0x01...not async\n", __func__); RETURNFUNC(RIG_OK); } switch (frame[4]) { case C_RD_FREQ: case C_SND_FREQ: { // TODO: The freq length might be less than 4 or 5 bytes on older rigs! // TODO: Disable cache timeout for frequency after first transceive packet once we figure out how to get active VFO reliably with transceive updates // TODO: rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_FREQ, HAMLIB_CACHE_ALWAYS); freq_t freq = (freq_t) from_bcd(frame + 5, (priv->civ_731_mode ? 4 : 5) * 2); #if defined(HAVE_PTHREAD) rig_fire_freq_event(rig, RIG_VFO_CURR, freq); #endif #if 0 if (rs->use_cached_freq != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): use_cached_freq turning on\n", __func__, __LINE__); rs->use_cached_freq = 0; } #endif break; } case C_SND_MODE: // TODO: Disable cache timeout for frequency after first transceive packet once we figure out how to get active VFO reliably with transceive updates // TODO: rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_MODE, HAMLIB_CACHE_ALWAYS); icom2rig_mode(rig, frame[5], frame[6], &mode, &width); #if defined(HAVE_PTHREAD) rig_fire_mode_event(rig, RIG_VFO_CURR, mode, width); #endif if (rs->use_cached_mode != 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): use_cached_mode turning on\n", __func__, __LINE__); rs->use_cached_mode = 0; } break; #if defined(HAVE_PTHREAD) case C_CTL_SCP: if (frame[5] == S_SCP_DAT) { icom_parse_spectrum_frame(rig, frame_length - (6 + 1), frame + 6); } break; #endif default: rig_debug(RIG_DEBUG_VERBOSE, "%s: transceive cmd unsupported %#2.2x\n", __func__, frame[4]); RETURNFUNC(-RIG_ENIMPL); } RETURNFUNC(RIG_OK); } /* * icom_decode is called by sa_sigio, when some asynchronous * data has been received from the rig */ int icom_decode_event(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char buf[MAXFRAMELEN]; int retval, frm_len; ENTERFUNC; rs = STATE(rig); priv = (struct icom_priv_data *) rs->priv; frm_len = read_icom_frame(RIGPORT(rig), buf, sizeof(buf)); if (frm_len == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: got a timeout before the first character\n", __func__); RETURNFUNC(-RIG_ETIMEOUT); } if (frm_len < 1) { RETURNFUNC(RIG_OK); } retval = icom_frame_fix_preamble(frm_len, buf); if (retval < 0) { RETURNFUNC(retval); } frm_len = retval; if (frm_len < 1) { rig_debug(RIG_DEBUG_ERR, "Unexpected frame len=%d\n", frm_len); RETURNFUNC(-RIG_EPROTO); } switch (buf[frm_len - 1]) { case COL: rig_debug(RIG_DEBUG_VERBOSE, "%s: saw a collision\n", __func__); /* Collision */ RETURNFUNC(-RIG_BUSBUSY); case FI: /* Ok, normal frame */ break; default: /* Timeout after reading at least one character */ /* Problem on ci-v bus? */ RETURNFUNC(-RIG_EPROTO); } if (!icom_is_async_frame(rig, frm_len, buf)) { rig_debug(RIG_DEBUG_WARN, "%s: CI-V %#x called for %#x!\n", __func__, priv->re_civ_addr, buf[2]); } RETURNFUNC(icom_process_async_frame(rig, frm_len, buf)); } int icom_read_frame_direct(RIG *rig, size_t buffer_length, const unsigned char *buffer) { return read_icom_frame_direct(RIGPORT(rig), buffer, buffer_length); } int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, int val) { unsigned char cmdbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int cmdbuflen = subcmdbuflen; int retval; ENTERFUNC; if (subcmdbuflen > 0) { if (subcmdbuf == NULL) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(cmdbuf, subcmdbuf, subcmdbuflen); } if (val_bytes > 0) { to_bcd_be(cmdbuf + subcmdbuflen, (long long) val, val_bytes * 2); cmdbuflen += val_bytes; } retval = icom_transaction(rig, cmd, subcmd, cmdbuf, cmdbuflen, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int icom_get_raw_buf(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *reslen, unsigned char *res) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int cmdhead = subcmdbuflen; int retval; ENTERFUNC; retval = icom_transaction(rig, cmd, subcmd, subcmdbuf, subcmdbuflen, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } cmdhead += (subcmd == -1) ? 1 : 2; ack_len -= cmdhead; rig_debug(RIG_DEBUG_TRACE, "%s: ack_len=%d\n", __func__, ack_len); if (ack_len < 0) { RETURNFUNC(-RIG_EPROTO); } if (*reslen < ack_len || res == NULL) { RETURNFUNC(-RIG_EINTERNAL); } memcpy(res, ackbuf + cmdhead, ack_len); *reslen = ack_len; RETURNFUNC(RIG_OK); } int icom_get_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *val) { unsigned char resbuf[MAXFRAMELEN]; int reslen = sizeof(resbuf); int retval; ENTERFUNC; retval = icom_get_raw_buf(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &reslen, resbuf); if (retval != RIG_OK) { RETURNFUNC(retval); } * val = from_bcd_be(resbuf, reslen * 2); rig_debug(RIG_DEBUG_TRACE, "%s: %d %d\n", __func__, reslen, *val); RETURNFUNC(RIG_OK); } int icom_set_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, value_t val) { int icom_val; ENTERFUNC; if (RIG_LEVEL_IS_FLOAT(level)) { icom_val = (int)(val.f * 255.0f); } else { icom_val = val.i; } RETURNFUNC(icom_set_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, val_bytes, icom_val)); } int icom_get_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, value_t *val) { int icom_val; int retval; ENTERFUNC; retval = icom_get_raw(rig, cmd, subcmd, subcmdbuflen, subcmdbuf, &icom_val); if (retval != RIG_OK) { RETURNFUNC(retval); } if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float) icom_val / 255.0f; } else { val->i = icom_val; } RETURNFUNC(RIG_OK); } int icom_stop_voice_mem(RIG *rig, vfo_t vfo) { return icom_send_voice_mem(rig, vfo, 0); } /* * icom_send_voice_mem * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int icom_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char chbuf[1]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; to_bcd_be(chbuf, ch, 2); retval = icom_transaction(rig, C_SND_VOICE, 0, chbuf, 1, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((retval = icom_check_ack(ack_len, ackbuf)) != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } /* * icom_get_freq_range * Assumes rig!=NULL, STATE(rig)->priv!=NULL * Always returns RIG_OK */ int icom_get_freq_range(RIG *rig) { int nrange = 0; int i; int cmd, subcmd; int retval; unsigned char cmdbuf[MAXFRAMELEN]; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); // struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; // int freq_len = priv->civ_731_mode ? 4 : 5; int freq_len = 5; cmd = C_CTL_EDGE; subcmd = 0; retval = icom_transaction(rig, cmd, subcmd, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: rig does not have 0x1e command so skipping this check\n", __func__); RETURNFUNC2(RIG_OK); } rig_debug(RIG_DEBUG_TRACE, "%s: ackbuf[0]=%02x, ackbuf[1]=%02x\n", __func__, ackbuf[0], ackbuf[1]); nrange = from_bcd(&ackbuf[2], 2); rig_debug(RIG_DEBUG_TRACE, "%s: nrange=%d\n", __func__, nrange); for (i = 1; i <= nrange; ++i) { cmd = C_CTL_EDGE; subcmd = 1; to_bcd(cmdbuf, i, 2); retval = icom_transaction(rig, cmd, subcmd, cmdbuf, 1, ackbuf, &ack_len); if (retval == RIG_OK) { freq_t freqlo, freqhi; rig_debug(RIG_DEBUG_TRACE, "%s: ackbuf= %02x %02x %02x %02x...\n", __func__, ackbuf[0], ackbuf[1], ackbuf[2], ackbuf[3]); freqlo = from_bcd(&ackbuf[3], freq_len * 2); freqhi = from_bcd(&ackbuf[3 + freq_len + 1], freq_len * 2); rig_debug(RIG_DEBUG_TRACE, "%s: rig chan %d, low=%.0f, high=%.0f\n", __func__, i, freqlo, freqhi); } else { rig_debug(RIG_DEBUG_ERR, "%s: error from C_CTL_EDGE? err=%s\n", __func__, rigerror(retval)); } } // To be implemented // Automatically fill in the freq range for this rig if available rig_debug(RIG_DEBUG_TRACE, "%s: Hamlib ranges\n", __func__); for (i = 0; i < HAMLIB_FRQRANGESIZ && !RIG_IS_FRNG_END(rig->caps->rx_range_list1[i]); i++) { rig_debug(RIG_DEBUG_TRACE, "%s: rig chan %d, low=%.0f, high=%.0f\n", __func__, i, (double)rig->caps->rx_range_list1[i].startf, (double)rig->caps->rx_range_list1[i].endf); } RETURNFUNC2(RIG_OK); } // Sets rig vfo && STATE(rig)->current_vfo to default VFOA, or current vfo, or the vfo requested static int set_vfo_curr(RIG *rig, vfo_t vfo, vfo_t curr_vfo) { int retval; struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(curr_vfo)); if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: Asking for currVFO, currVFO=%s\n", __func__, rig_strvfo(rs->current_vfo)); vfo = rs->current_vfo; RETURNFUNC2(RIG_OK); } if (vfo == RIG_VFO_MAIN && VFO_HAS_A_B_ONLY) { vfo = RIG_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Main=%s\n", __func__, rig_strvfo(vfo)); } else if (vfo == RIG_VFO_SUB && VFO_HAS_A_B_ONLY) { vfo = RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: Rig does not have MAIN/SUB so Sub=%s\n", __func__, rig_strvfo(vfo)); } /* This method works also in memory mode(RIG_VFO_MEM) */ // first time we will set default to VFOA or Main as // So if you ask for frequency or such without setting VFO first you'll get Main/VFOA if (rs->current_vfo == RIG_VFO_NONE && vfo == RIG_VFO_CURR) { HAMLIB_TRACE; icom_set_default_vfo(rig); } // asking for vfo_curr so give it to them else if (rs->current_vfo != RIG_VFO_NONE && vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: using curr_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); vfo = rs->current_vfo; } // only need to set vfo if it's changed else if (rs->current_vfo != vfo) { if (!(VFO_HAS_MAIN_SUB_A_B_ONLY && CACHE(rig)->split == RIG_SPLIT_OFF && !CACHE(rig)->satmode && vfo == RIG_VFO_SUB && rs->current_vfo == RIG_VFO_B)) { rig_debug(RIG_DEBUG_TRACE, "%s: setting new vfo=%s\n", __func__, rig_strvfo(vfo)); HAMLIB_TRACE; retval = rig_set_vfo(rig, vfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } } rig_debug(RIG_DEBUG_TRACE, "%s: curr_vfo now=%s\n", __func__, rig_strvfo(rs->current_vfo)); rs->current_vfo = vfo; RETURNFUNC2(RIG_OK); } static int icom_get_spectrum_vfo(RIG *rig, vfo_t vfo) { if (STATE(rig)->targetable_vfo & RIG_TARGETABLE_SPECTRUM) { RETURNFUNC2(ICOM_GET_VFO_NUMBER(vfo)); } RETURNFUNC2(0); } static int icom_get_spectrum_edge_frequency_range(RIG *rig, vfo_t vfo, int *range_id) { freq_t freq; rmode_t mode; pbwidth_t width; int cache_ms_freq, cache_ms_mode, cache_ms_width; int i, retval; struct icom_priv_caps *priv_caps = (struct icom_priv_caps *) rig->caps->priv; retval = rig_get_cache(rig, vfo, &freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); if (retval != RIG_OK) { RETURNFUNC2(retval); } // Get frequency if it is not cached or value is old if (freq == 0 || cache_ms_freq >= 1000) { retval = rig_get_freq(rig, vfo, &freq); if (retval != RIG_OK) { RETURNFUNC2(retval); } } for (i = 0; i < ICOM_MAX_SPECTRUM_FREQ_RANGES; i++) { int id = priv_caps->spectrum_edge_frequency_ranges[i].range_id; if (id < 1) { break; } if (freq >= priv_caps->spectrum_edge_frequency_ranges[i].low_freq && freq < priv_caps->spectrum_edge_frequency_ranges[i].high_freq) { *range_id = id; RETURNFUNC2(RIG_OK); } } RETURNFUNC2(-RIG_EINVAL); } /* * init_icom is called by rig_probe_all (register.c) * * probe_icom reports all the devices on the CI-V bus. * * rig_model_t probeallrigs_icom(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(icom) { unsigned char buf[MAXFRAMELEN], civ_addr, civ_id; int frm_len, i; rig_model_t model = RIG_MODEL_NONE; int rates[] = { 19200, 9600, 300, 0 }; int rates_idx; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!port) { return (RIG_MODEL_NONE); } if (port->type.rig != RIG_PORT_SERIAL) { return (RIG_MODEL_NONE); } port->write_delay = port->post_write_delay = 0; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { int retval; port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 40; retval = serial_open(port); if (retval != RIG_OK) { return (RIG_MODEL_NONE); } /* * try all possible addresses on the CI-V bus * FIXME: actually, old rigs do not support C_RD_TRXID cmd! * Try to be smart, and deduce model depending * on freq range, return address, and * available commands. */ for (civ_addr = 0x01; civ_addr <= 0x7f; civ_addr++) { frm_len = make_cmd_frame(buf, civ_addr, CTRLID, C_RD_TRXID, S_RD_TRXID, NULL, 0); rig_flush(port); write_block(port, buf, frm_len); /* read out the bytes we just sent * TODO: check this is what we expect */ read_icom_frame(port, buf, sizeof(buf)); /* this is the reply */ frm_len = read_icom_frame(port, buf, sizeof(buf)); /* timeout.. nobody's there */ if (frm_len <= 0) { continue; } if (buf[7] != FI && buf[5] != FI) { /* protocol error, unexpected reply. * is this a CI-V device? */ close(port->fd); return (RIG_MODEL_NONE); } else if (buf[4] == NAK) { /* * this is an Icom, but it does not support transceiver ID * try to guess from the return address */ civ_id = buf[3]; } else { civ_id = buf[6]; } for (i = 0; icom_addr_list[i].model != RIG_MODEL_NONE; i++) { if (icom_addr_list[i].re_civ_addr == civ_id) { rig_debug(RIG_DEBUG_VERBOSE, "%s: found %#x at %#x\n", __func__, civ_id, buf[3]); model = icom_addr_list[i].model; if (cfunc) { (*cfunc)(port, model, data); } break; } } /* * not found in known table.... * update icom_addr_list[]! */ if (icom_addr_list[i].model == RIG_MODEL_NONE) rig_debug(RIG_DEBUG_WARN, "%s: found unknown device " "with CI-V ID %#x, please report to Hamlib " "developers.\n", __func__, civ_id); } /* * Try to identify OptoScan */ for (civ_addr = 0x80; civ_addr <= 0x8f; civ_addr++) { frm_len = make_cmd_frame(buf, civ_addr, CTRLID, C_CTL_MISC, S_OPTO_RDID, NULL, 0); rig_flush(port); write_block(port, buf, frm_len); /* read out the bytes we just sent * TODO: check this is what we expect */ read_icom_frame(port, buf, sizeof(buf)); /* this is the reply */ frm_len = read_icom_frame(port, buf, sizeof(buf)); /* timeout.. nobody's there */ if (frm_len <= 0) { continue; } /* wrong protocol? */ if (frm_len != 7 || buf[4] != C_CTL_MISC || buf[5] != S_OPTO_RDID) { continue; } rig_debug(RIG_DEBUG_VERBOSE, "%s: " "found OptoScan%c%c%c, software version %d.%d, " "interface version %d.%d, at %#x\n", __func__, buf[2], buf[3], buf[4], buf[5] >> 4, buf[5] & 0xf, buf[6] >> 4, buf[6] & 0xf, civ_addr); if (buf[6] == '5' && buf[7] == '3' && buf[8] == '5') { model = RIG_MODEL_OS535; } else if (buf[6] == '4' && buf[7] == '5' && buf[8] == '6') { model = RIG_MODEL_OS456; } else { continue; } if (cfunc) { (*cfunc)(port, model, data); } break; } close(port->fd); /* * Assumes all the rigs on the bus are running at same speed. * So if one at least has been found, none will be at lower speed. */ if (model != RIG_MODEL_NONE) { return (model); } } return (model); } static int icom_is_x25x26_potentially_supported(RIG *rig) { const struct icom_priv_caps *priv_caps = rig->caps->priv; // Handle rigs that will never support the 0x25 or 0x26 commands // The IC-751 doesn't even reject the command and has to time out if (priv_caps->x25x26_possibly || priv_caps->x25x26_always) { return 1; } return 0; } static void icom_set_x25x26_ability(RIG *rig, int status) { struct icom_priv_data *priv = STATE(rig)->priv; if (!icom_is_x25x26_potentially_supported(rig)) { // No change for rigs that don't support these commands anyway rig_debug(RIG_DEBUG_VERBOSE, "%s: Hamlib thinks rig does not support x25/x26 command\n", __func__); return; } priv->x25cmdfails = status; priv->x26cmdfails = status; } /** * Resolves the VFO number for Icom commands 0x25 and 0x26 */ static int icom_get_vfo_number_x25x26(RIG *rig, vfo_t vfo) { int vfo_number = 0x00; struct rig_cache *cachep = CACHE(rig); struct rig_state *rs = STATE(rig); // Rigs with *only* Main/Sub VFOs can directly address VFOs: 0 = Main, 1 = Sub if (RIG_IS_IC7600 || RIG_IS_IC7610 || RIG_IS_IC7800 || RIG_IS_IC785X) { vfo_t actual_vfo = vfo_fixup(rig, vfo, cachep->split); if (actual_vfo == RIG_VFO_CURR) { actual_vfo = rs->current_vfo; } if (actual_vfo & (RIG_VFO_B | RIG_VFO_SUB)) { vfo_number = 0x01; } } else { // Other Icom rigs have: 0 = selected VFO, 1 = unselected VFO if (vfo == RIG_VFO_CURR) { vfo_number = 0x00; // selected VFO } else if (vfo == RIG_VFO_OTHER) { vfo_number = 0x01; // unselected VFO } else { vfo_t vfo_unselected = RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B | RIG_VFO_OTHER; // Check if we are on the requested VFO already if (rs->current_vfo & vfo_unselected) { HAMLIB_TRACE; vfo_unselected = RIG_VFO_A | RIG_VFO_MAIN | RIG_VFO_SUB_A | RIG_VFO_MAIN_A | RIG_VFO_OTHER; } // Check if we are not on the unselected VFO if ((vfo & vfo_unselected) && !(rs->current_vfo & vfo_unselected)) { HAMLIB_TRACE; vfo_number = 0x01; // unselected VFO } // The split VFO is active when transmitting in split mode vfo_number = (cachep->split && cachep->ptt) ? !vfo_number : vfo_number; } } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): current_vfo=%s, vfo=%s -> vfo_number=%d\n", __func__, __LINE__, rig_strvfo(rs->current_vfo), rig_strvfo(vfo), vfo_number); return vfo_number; } /* * initrigs_icom is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(icom) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ic703_caps); rig_register(&ic705_caps); rig_register(&ic706_caps); rig_register(&ic706mkii_caps); rig_register(&ic706mkiig_caps); rig_register(&ic718_caps); rig_register(&ic725_caps); rig_register(&ic726_caps); rig_register(&ic735_caps); rig_register(&ic736_caps); rig_register(&ic737_caps); rig_register(&ic738_caps); rig_register(&ic7410_caps); rig_register(&ic746_caps); rig_register(&ic746pro_caps); rig_register(&ic751_caps); rig_register(&ic761_caps); rig_register(&ic775_caps); rig_register(&ic756_caps); rig_register(&ic756pro_caps); rig_register(&ic756pro2_caps); rig_register(&ic756pro3_caps); rig_register(&ic7600_caps); rig_register(&ic765_caps); rig_register(&ic7700_caps); rig_register(&ic78_caps); rig_register(&ic7800_caps); rig_register(&ic785x_caps); rig_register(&ic7000_caps); rig_register(&ic7100_caps); rig_register(&ic7200_caps); rig_register(&ic7300_caps); rig_register(&ic7610_caps); rig_register(&ic7760_caps); rig_register(&ic781_caps); rig_register(&ic707_caps); rig_register(&ic728_caps); rig_register(&ic729_caps); rig_register(&ic820h_caps); rig_register(&ic821h_caps); rig_register(&ic905_caps); rig_register(&ic910_caps); rig_register(&ic9100_caps); rig_register(&ic970_caps); rig_register(&ic9700_caps); rig_register(&icrx7_caps); rig_register(&icr6_caps); rig_register(&icr10_caps); rig_register(&icr20_caps); rig_register(&icr30_caps); rig_register(&icr71_caps); rig_register(&icr72_caps); rig_register(&icr75_caps); rig_register(&icr7000_caps); rig_register(&icr7100_caps); rig_register(&icr8500_caps); rig_register(&icr8600_caps); rig_register(&icr9000_caps); rig_register(&icr9500_caps); rig_register(&ic271_caps); rig_register(&ic275_caps); rig_register(&ic375_caps); rig_register(&ic471_caps); rig_register(&ic475_caps); rig_register(&ic575_caps); rig_register(&ic1275_caps); rig_register(&icf8101_caps); rig_register(&os535_caps); rig_register(&os456_caps); rig_register(&omnivip_caps); rig_register(&delta2_caps); rig_register(&ic92d_caps); rig_register(&id1_caps); rig_register(&id31_caps); rig_register(&id51_caps); rig_register(&id4100_caps); rig_register(&id5100_caps); rig_register(&ic2730_caps); rig_register(&perseus_caps); rig_register(&x108g_caps); rig_register(&x6100_caps); rig_register(&g90_caps); rig_register(&x5105_caps); rig_register(&x6200_caps); return (RIG_OK); } hamlib-4.6.2/rigs/icom/Makefile.in0000644000175000017500000010433614752216216013655 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/icom ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_icom_la_LIBADD = am__objects_1 = icom.lo frame.lo ic706.lo icr8500.lo ic735.lo ic775.lo \ ic756.lo ic275.lo ic475.lo ic1275.lo ic820h.lo ic821h.lo \ icr7000.lo ic910.lo ic9100.lo ic970.lo ic725.lo ic737.lo \ ic718.lo os535.lo os456.lo omni.lo delta2.lo ic92d.lo ic736.lo \ ic738.lo ic7410.lo ic746.lo ic703.lo ic726.lo ic271.lo \ ic765.lo ic781.lo ic471.lo icr9000.lo icr9500.lo icr10.lo \ icr20.lo icr30.lo icr6.lo icr71.lo icr72.lo icr75.lo icrx7.lo \ icr8600.lo id1.lo id31.lo id51.lo id4100.lo id5100.lo \ perseus.lo ic2730.lo ic707.lo ic728.lo ic751.lo ic761.lo \ ic78.lo ic7800.lo ic785x.lo ic7000.lo ic7100.lo ic7200.lo \ ic7300.lo ic7600.lo ic7610.lo ic7700.lo ic7760.lo icf8101.lo \ optoscan.lo xiegu.lo am_libhamlib_icom_la_OBJECTS = $(am__objects_1) libhamlib_icom_la_OBJECTS = $(am_libhamlib_icom_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/delta2.Plo ./$(DEPDIR)/frame.Plo \ ./$(DEPDIR)/ic1275.Plo ./$(DEPDIR)/ic271.Plo \ ./$(DEPDIR)/ic2730.Plo ./$(DEPDIR)/ic275.Plo \ ./$(DEPDIR)/ic471.Plo ./$(DEPDIR)/ic475.Plo \ ./$(DEPDIR)/ic7000.Plo ./$(DEPDIR)/ic703.Plo \ ./$(DEPDIR)/ic706.Plo ./$(DEPDIR)/ic707.Plo \ ./$(DEPDIR)/ic7100.Plo ./$(DEPDIR)/ic718.Plo \ ./$(DEPDIR)/ic7200.Plo ./$(DEPDIR)/ic725.Plo \ ./$(DEPDIR)/ic726.Plo ./$(DEPDIR)/ic728.Plo \ ./$(DEPDIR)/ic7300.Plo ./$(DEPDIR)/ic735.Plo \ ./$(DEPDIR)/ic736.Plo ./$(DEPDIR)/ic737.Plo \ ./$(DEPDIR)/ic738.Plo ./$(DEPDIR)/ic7410.Plo \ ./$(DEPDIR)/ic746.Plo ./$(DEPDIR)/ic751.Plo \ ./$(DEPDIR)/ic756.Plo ./$(DEPDIR)/ic7600.Plo \ ./$(DEPDIR)/ic761.Plo ./$(DEPDIR)/ic7610.Plo \ ./$(DEPDIR)/ic765.Plo ./$(DEPDIR)/ic7700.Plo \ ./$(DEPDIR)/ic775.Plo ./$(DEPDIR)/ic7760.Plo \ ./$(DEPDIR)/ic78.Plo ./$(DEPDIR)/ic7800.Plo \ ./$(DEPDIR)/ic781.Plo ./$(DEPDIR)/ic785x.Plo \ ./$(DEPDIR)/ic820h.Plo ./$(DEPDIR)/ic821h.Plo \ ./$(DEPDIR)/ic910.Plo ./$(DEPDIR)/ic9100.Plo \ ./$(DEPDIR)/ic92d.Plo ./$(DEPDIR)/ic970.Plo \ ./$(DEPDIR)/icf8101.Plo ./$(DEPDIR)/icom.Plo \ ./$(DEPDIR)/icr10.Plo ./$(DEPDIR)/icr20.Plo \ ./$(DEPDIR)/icr30.Plo ./$(DEPDIR)/icr6.Plo \ ./$(DEPDIR)/icr7000.Plo ./$(DEPDIR)/icr71.Plo \ ./$(DEPDIR)/icr72.Plo ./$(DEPDIR)/icr75.Plo \ ./$(DEPDIR)/icr8500.Plo ./$(DEPDIR)/icr8600.Plo \ ./$(DEPDIR)/icr9000.Plo ./$(DEPDIR)/icr9500.Plo \ ./$(DEPDIR)/icrx7.Plo ./$(DEPDIR)/id1.Plo ./$(DEPDIR)/id31.Plo \ ./$(DEPDIR)/id4100.Plo ./$(DEPDIR)/id51.Plo \ ./$(DEPDIR)/id5100.Plo ./$(DEPDIR)/omni.Plo \ ./$(DEPDIR)/optoscan.Plo ./$(DEPDIR)/os456.Plo \ ./$(DEPDIR)/os535.Plo ./$(DEPDIR)/perseus.Plo \ ./$(DEPDIR)/xiegu.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_icom_la_SOURCES) DIST_SOURCES = $(libhamlib_icom_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ICOMSRC = icom.c icom.h icom_defs.h frame.c frame.h ic706.c icr8500.c ic735.c ic775.c ic756.c \ ic275.c ic475.c ic1275.c ic820h.c ic821h.c \ icr7000.c ic910.c ic9100.c ic970.c ic725.c ic737.c ic718.c \ os535.c os456.c omni.c delta2.c ic92d.c \ ic736.c ic738.c ic7410.c ic746.c ic703.c ic726.c ic271.c \ ic765.c ic781.c ic471.c icr9000.c icr9500.c \ icr10.c icr20.c icr30.c icr6.c icr71.c icr72.c icr75.c icrx7.c icr8600.c \ id1.c id31.c id51.c id4100.c id5100.c perseus.c ic2730.c \ ic707.c ic728.c ic751.c ic761.c \ ic78.c ic7800.c ic785x.c \ ic7000.c ic7100.c ic7200.c ic7300.c ic7600.c ic7610.c ic7700.c ic7760.c icf8101.c \ ic7300.h optoscan.c optoscan.h xiegu.c level_gran_icom.h noinst_LTLIBRARIES = libhamlib-icom.la libhamlib_icom_la_SOURCES = $(ICOMSRC) EXTRA_DIST = README.icom TODO.icom Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/icom/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/icom/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-icom.la: $(libhamlib_icom_la_OBJECTS) $(libhamlib_icom_la_DEPENDENCIES) $(EXTRA_libhamlib_icom_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_icom_la_OBJECTS) $(libhamlib_icom_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delta2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic1275.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic271.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic2730.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic275.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic471.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic475.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic703.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic706.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic707.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic718.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic725.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic726.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic728.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7300.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic735.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic736.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic737.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic738.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7410.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic746.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic751.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic756.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic761.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7610.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic765.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic775.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7760.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic78.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic7800.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic781.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic785x.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic820h.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic821h.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic910.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic9100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic92d.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic970.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icf8101.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icom.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr20.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr30.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr6.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr7000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr71.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr72.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr75.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr8500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr8600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr9000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icr9500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icrx7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id1.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id31.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id4100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id51.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id5100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omni.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optoscan.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os456.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os535.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perseus.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiegu.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/delta2.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f ./$(DEPDIR)/ic1275.Plo -rm -f ./$(DEPDIR)/ic271.Plo -rm -f ./$(DEPDIR)/ic2730.Plo -rm -f ./$(DEPDIR)/ic275.Plo -rm -f ./$(DEPDIR)/ic471.Plo -rm -f ./$(DEPDIR)/ic475.Plo -rm -f ./$(DEPDIR)/ic7000.Plo -rm -f ./$(DEPDIR)/ic703.Plo -rm -f ./$(DEPDIR)/ic706.Plo -rm -f ./$(DEPDIR)/ic707.Plo -rm -f ./$(DEPDIR)/ic7100.Plo -rm -f ./$(DEPDIR)/ic718.Plo -rm -f ./$(DEPDIR)/ic7200.Plo -rm -f ./$(DEPDIR)/ic725.Plo -rm -f ./$(DEPDIR)/ic726.Plo -rm -f ./$(DEPDIR)/ic728.Plo -rm -f ./$(DEPDIR)/ic7300.Plo -rm -f ./$(DEPDIR)/ic735.Plo -rm -f ./$(DEPDIR)/ic736.Plo -rm -f ./$(DEPDIR)/ic737.Plo -rm -f ./$(DEPDIR)/ic738.Plo -rm -f ./$(DEPDIR)/ic7410.Plo -rm -f ./$(DEPDIR)/ic746.Plo -rm -f ./$(DEPDIR)/ic751.Plo -rm -f ./$(DEPDIR)/ic756.Plo -rm -f ./$(DEPDIR)/ic7600.Plo -rm -f ./$(DEPDIR)/ic761.Plo -rm -f ./$(DEPDIR)/ic7610.Plo -rm -f ./$(DEPDIR)/ic765.Plo -rm -f ./$(DEPDIR)/ic7700.Plo -rm -f ./$(DEPDIR)/ic775.Plo -rm -f ./$(DEPDIR)/ic7760.Plo -rm -f ./$(DEPDIR)/ic78.Plo -rm -f ./$(DEPDIR)/ic7800.Plo -rm -f ./$(DEPDIR)/ic781.Plo -rm -f ./$(DEPDIR)/ic785x.Plo -rm -f ./$(DEPDIR)/ic820h.Plo -rm -f ./$(DEPDIR)/ic821h.Plo -rm -f ./$(DEPDIR)/ic910.Plo -rm -f ./$(DEPDIR)/ic9100.Plo -rm -f ./$(DEPDIR)/ic92d.Plo -rm -f ./$(DEPDIR)/ic970.Plo -rm -f ./$(DEPDIR)/icf8101.Plo -rm -f ./$(DEPDIR)/icom.Plo -rm -f ./$(DEPDIR)/icr10.Plo -rm -f ./$(DEPDIR)/icr20.Plo -rm -f ./$(DEPDIR)/icr30.Plo -rm -f ./$(DEPDIR)/icr6.Plo -rm -f ./$(DEPDIR)/icr7000.Plo -rm -f ./$(DEPDIR)/icr71.Plo -rm -f ./$(DEPDIR)/icr72.Plo -rm -f ./$(DEPDIR)/icr75.Plo -rm -f ./$(DEPDIR)/icr8500.Plo -rm -f ./$(DEPDIR)/icr8600.Plo -rm -f ./$(DEPDIR)/icr9000.Plo -rm -f ./$(DEPDIR)/icr9500.Plo -rm -f ./$(DEPDIR)/icrx7.Plo -rm -f ./$(DEPDIR)/id1.Plo -rm -f ./$(DEPDIR)/id31.Plo -rm -f ./$(DEPDIR)/id4100.Plo -rm -f ./$(DEPDIR)/id51.Plo -rm -f ./$(DEPDIR)/id5100.Plo -rm -f ./$(DEPDIR)/omni.Plo -rm -f ./$(DEPDIR)/optoscan.Plo -rm -f ./$(DEPDIR)/os456.Plo -rm -f ./$(DEPDIR)/os535.Plo -rm -f ./$(DEPDIR)/perseus.Plo -rm -f ./$(DEPDIR)/xiegu.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/delta2.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f ./$(DEPDIR)/ic1275.Plo -rm -f ./$(DEPDIR)/ic271.Plo -rm -f ./$(DEPDIR)/ic2730.Plo -rm -f ./$(DEPDIR)/ic275.Plo -rm -f ./$(DEPDIR)/ic471.Plo -rm -f ./$(DEPDIR)/ic475.Plo -rm -f ./$(DEPDIR)/ic7000.Plo -rm -f ./$(DEPDIR)/ic703.Plo -rm -f ./$(DEPDIR)/ic706.Plo -rm -f ./$(DEPDIR)/ic707.Plo -rm -f ./$(DEPDIR)/ic7100.Plo -rm -f ./$(DEPDIR)/ic718.Plo -rm -f ./$(DEPDIR)/ic7200.Plo -rm -f ./$(DEPDIR)/ic725.Plo -rm -f ./$(DEPDIR)/ic726.Plo -rm -f ./$(DEPDIR)/ic728.Plo -rm -f ./$(DEPDIR)/ic7300.Plo -rm -f ./$(DEPDIR)/ic735.Plo -rm -f ./$(DEPDIR)/ic736.Plo -rm -f ./$(DEPDIR)/ic737.Plo -rm -f ./$(DEPDIR)/ic738.Plo -rm -f ./$(DEPDIR)/ic7410.Plo -rm -f ./$(DEPDIR)/ic746.Plo -rm -f ./$(DEPDIR)/ic751.Plo -rm -f ./$(DEPDIR)/ic756.Plo -rm -f ./$(DEPDIR)/ic7600.Plo -rm -f ./$(DEPDIR)/ic761.Plo -rm -f ./$(DEPDIR)/ic7610.Plo -rm -f ./$(DEPDIR)/ic765.Plo -rm -f ./$(DEPDIR)/ic7700.Plo -rm -f ./$(DEPDIR)/ic775.Plo -rm -f ./$(DEPDIR)/ic7760.Plo -rm -f ./$(DEPDIR)/ic78.Plo -rm -f ./$(DEPDIR)/ic7800.Plo -rm -f ./$(DEPDIR)/ic781.Plo -rm -f ./$(DEPDIR)/ic785x.Plo -rm -f ./$(DEPDIR)/ic820h.Plo -rm -f ./$(DEPDIR)/ic821h.Plo -rm -f ./$(DEPDIR)/ic910.Plo -rm -f ./$(DEPDIR)/ic9100.Plo -rm -f ./$(DEPDIR)/ic92d.Plo -rm -f ./$(DEPDIR)/ic970.Plo -rm -f ./$(DEPDIR)/icf8101.Plo -rm -f ./$(DEPDIR)/icom.Plo -rm -f ./$(DEPDIR)/icr10.Plo -rm -f ./$(DEPDIR)/icr20.Plo -rm -f ./$(DEPDIR)/icr30.Plo -rm -f ./$(DEPDIR)/icr6.Plo -rm -f ./$(DEPDIR)/icr7000.Plo -rm -f ./$(DEPDIR)/icr71.Plo -rm -f ./$(DEPDIR)/icr72.Plo -rm -f ./$(DEPDIR)/icr75.Plo -rm -f ./$(DEPDIR)/icr8500.Plo -rm -f ./$(DEPDIR)/icr8600.Plo -rm -f ./$(DEPDIR)/icr9000.Plo -rm -f ./$(DEPDIR)/icr9500.Plo -rm -f ./$(DEPDIR)/icrx7.Plo -rm -f ./$(DEPDIR)/id1.Plo -rm -f ./$(DEPDIR)/id31.Plo -rm -f ./$(DEPDIR)/id4100.Plo -rm -f ./$(DEPDIR)/id51.Plo -rm -f ./$(DEPDIR)/id5100.Plo -rm -f ./$(DEPDIR)/omni.Plo -rm -f ./$(DEPDIR)/optoscan.Plo -rm -f ./$(DEPDIR)/os456.Plo -rm -f ./$(DEPDIR)/os535.Plo -rm -f ./$(DEPDIR)/perseus.Plo -rm -f ./$(DEPDIR)/xiegu.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/icom/ic718.c0000644000175000017500000001530114752216205012576 00000000000000/* * Hamlib CI-V backend - description of IC-718 caps * Copyright (c) 2000-2010 by Stephane Fillod * Caps submitted by Chuck Gilkes WD0FCL/4 * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #include "bandplan.h" #define IC718_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC718_1MHZ_TS_MODES (RIG_MODE_AM) #define IC718_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) /* tx doesn't have WFM. * 100W in all modes but AM (40W) */ #define IC718_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC718_AM_TX_MODES (RIG_MODE_AM) #define IC718_FUNC_ALL (RIG_FUNC_NR|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_ANF) #define IC718_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_MICGAIN|RIG_LEVEL_NR|RIG_LEVEL_CWPITCH|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RAWSTR|RIG_LEVEL_SQL) #define IC718_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC718_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC718_SCAN_OPS (RIG_SCAN_MEM) /* * TODO: check whether func and levels are stored in memory */ #define IC718_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ } #define IC718_STR_CAL UNKNOWN_IC_STR_CAL static const struct icom_priv_caps IC718_priv_caps = { 0x5e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic718_ts_sc_list }; struct rig_caps ic718_caps = { RIG_MODEL(RIG_MODEL_IC718), .model_name = "IC-718", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC718_FUNC_ALL, .has_set_func = IC718_FUNC_ALL, .has_get_level = IC718_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC718_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .str_cal = IC718_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC718_VFO_OPS, .scan_ops = IC718_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC718_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC718_MEM_CAP }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30) - 1, IC718_ALL_RX_MODES, -1, -1, IC718_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC718_OTHER_TX_MODES, W(5), W(100), IC718_VFO_ALL, RIG_ANT_1), FRQ_RNG_HF(1, IC718_AM_TX_MODES, W(2), W(40), IC718_VFO_ALL, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30) - 1, IC718_ALL_RX_MODES, -1, -1, IC718_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC718_OTHER_TX_MODES, W(5), W(100), IC718_VFO_ALL, RIG_ANT_1), FRQ_RNG_HF(2, IC718_AM_TX_MODES, W(2), W(40), IC718_VFO_ALL, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC718_1HZ_TS_MODES, 1}, {IC718_ALL_RX_MODES, 10}, {IC718_ALL_RX_MODES, 100}, {IC718_ALL_RX_MODES, kHz(1)}, {IC718_ALL_RX_MODES, kHz(5)}, {IC718_ALL_RX_MODES, kHz(9)}, {IC718_ALL_RX_MODES, kHz(10)}, {IC718_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.1)}, /* builtin */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, /* FL-52A */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(250)}, /* FL-53A */ {RIG_MODE_SSB, kHz(2.8)}, /* FL-96 */ {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1.8)}, /* FL-222 */ {RIG_MODE_AM, kHz(6)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC718_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr9500.c0000644000175000017500000001636614752216205013052 00000000000000/* * Hamlib CI-V backend - IC-R9500 descriptions * Copyright (c) 2000-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "icom.h" #include "tones.h" #define ICR9500_MODES (RIG_MODE_AM|RIG_MODE_AMS|\ RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_WFM) #define ICR9500_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR9500_FUNCS (RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_NR|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK) #define ICR9500_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_AGC_TIME) #define ICR9500_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define ICR9500_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|RIG_SCAN_PRIO) /* TBC */ #define ICR9500_HF_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define ICR9500_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define ICR9500_MEM_CAP { /* FIXME */ \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_ATT, \ } /* TODO: S-Meter measurements */ /* This is just a copy if IC9700_STR_CAL */ /* Hope it's correct */ #define ICR9500_STR_CAL { 7, \ { \ { 0, -54 }, \ { 10, -48 }, \ { 30, -36 }, \ { 60, -24 }, \ { 90, -12 }, \ { 120, 0 }, \ { 241, 64 } \ } } static struct icom_priv_caps icr9500_priv_caps = { 0x72, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ .ts_sc_list = r9500_ts_sc_list, .antack_len = 2, .ant_count = 3 }; /* * ICR9500A rig capabilities. */ struct rig_caps icr9500_caps = { RIG_MODEL(RIG_MODEL_ICR9500), .model_name = "IC-R9500", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR9500_FUNCS, .has_set_func = ICR9500_FUNCS, .has_get_level = ICR9500_LEVELS, .has_set_level = RIG_LEVEL_SET(ICR9500_LEVELS), .has_get_parm = ICR9500_PARMS, .has_set_parm = RIG_PARM_SET(ICR9500_PARMS), .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, 20, RIG_DBLST_END }, /* FIXME: TBC */ .attenuator = { 6, 10, 12, 18, 20, 24, 30, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR9500_OPS, .scan_ops = ICR9500_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 12, .chan_desc_sz = 0, /* FIXME */ .chan_list = { { 0, 999, RIG_MTYPE_MEM, ICR9500_MEM_CAP }, /* TBC */ { 1000, 1099, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* Bank-A (Auto) */ { 1100, 1199, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* Bank-S (skip) */ { 1200, 1219, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, /* Bank-P (Scan edge), 2 by 2 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(5), MHz(30) - 1, ICR9500_MODES, -1, -1, ICR9500_VFOS, ICR9500_HF_ANTS}, {MHz(30), MHz(3335), ICR9500_MODES, -1, -1, ICR9500_VFOS, RIG_ANT_4}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(5), MHz(30) - 1, ICR9500_MODES, -1, -1, ICR9500_VFOS, ICR9500_HF_ANTS}, {MHz(30), MHz(3335), ICR9500_MODES, -1, -1, ICR9500_VFOS, RIG_ANT_4}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR9500_MODES, 1}, /* resolution */ {ICR9500_MODES, 10}, {ICR9500_MODES, 100}, {ICR9500_MODES, kHz(1)}, {ICR9500_MODES, kHz(2.5)}, {ICR9500_MODES, kHz(5)}, {ICR9500_MODES, kHz(6.25)}, {ICR9500_MODES, kHz(9)}, {ICR9500_MODES, kHz(10)}, {ICR9500_MODES, 12500}, {ICR9500_MODES, kHz(20)}, {ICR9500_MODES, kHz(25)}, {ICR9500_MODES, kHz(100)}, {ICR9500_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(350)}, RIG_FLT_END, }, .str_cal = ICR9500_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr9500_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/icom/level_gran_icom.h0000644000175000017500000001045714752216205015104 00000000000000/* LVL_IF LVL_RAWSTR LVL_SPECTRUM_AVG LVL_SPECTRUM_REF LVL_SPECTRUM_SPEED LVL_PBT_IN LVL_PBT_OUT LVL_KEYSPD */ // Once included these values can be overridden in the back-end // Known variants are AGC_TIME, PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 12 }, .step = { .i = 0 } }, [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 10 }, .step = { .f = 1 } }, /* levels with WPM units */ #if !defined(NO_LVL_KEYSPD) [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, #endif /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 5 } }, #endif [LVL_IF] = { .min = { .i = -1200 }, .max = { .i = 1200 }, .step = { .i = 20 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, /* levels with time units */ [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, [LVL_BKINDL] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, [LVL_BKIN_DLYMS] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, [LVL_AGC_TIME] = { .min = { .f = 0.0f }, .max = { .f = 8.0f }, .step = { .f = 0.1f } }, /* level with misc units */ [LVL_SWR] = { .min = { .f = 0 }, .max = { .f = 5.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_BAND_SELECT] = { .min = { .i = 0 }, .max = { .i = 16 }, .step = { .i = 1 } }, /* levels with 0-1 values -- increment based on rig's range */ [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/15.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ID_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_VD_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_MICGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_VOXGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ANTIVOX] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ALC] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/120.0f } }, #if !defined(NO_LVL_USB_AF) [LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_PBT_IN) [LVL_PBT_IN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_PBT_OUT) [LVL_PBT_OUT] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif hamlib-4.6.2/rigs/icom/ic751.c0000644000175000017500000002107314752216205012576 00000000000000/* * Hamlib CI-V backend - description of IC-751 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" /* * FM is an option on the Icom IC-751, and built-in in the Icom IC-751A */ #define IC751_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) /* * 200W in all modes but AM (40W) */ #define IC751_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC751_AM_TX_MODES (RIG_MODE_AM) #define IC751_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define IC751_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC751_SCAN_OPS (RIG_SCAN_NONE) #define IC751_ANTS RIG_ANT_1 /* * S-Meter measurements * (Only the Piexx UX-14px rev.2 and up has an S-meter option.) * Values based on the readings of my IC-751A S-meter, i.e. not * actual signal strength. -- Lars, sm6rpz */ #define IC751_STR_CAL { 16, { \ { 3, -52 }, /* S0.5 */ \ { 12, -48 }, /* S1 */ \ { 33, -42 }, /* S2 */ \ { 45, -36 }, /* S3 */ \ { 60, -30 }, /* S4 */ \ { 73, -24 }, /* S5 */ \ { 86, -18 }, /* S6 */ \ { 100, -12 }, /* S7 */ \ { 115, -6 }, /* S8 */ \ { 129, 0 }, /* S9 */ \ { 160, 10 }, /* S9+10 */ \ { 186, 20 }, /* S9+20 */ \ { 208, 30 }, /* S9+30 */ \ { 226, 40 }, /* S9+40 */ \ { 241, 50 }, /* S9+50 */ \ { 255, 60 } /* S9+60 */ \ } } /* */ static const struct icom_priv_caps ic751_priv_caps = { 0x1c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic751_caps = { RIG_MODEL(RIG_MODEL_IC751), .model_name = "IC-751", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, /* Piexx UX-14px has a PTT option */ .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, /* Piexx UX-14px can use 9600 */ .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, /* Piexx UX-14px has an S-meter option */ .has_get_level = (RIG_LEVEL_RAWSTR | RIG_LEVEL_STRENGTH), .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC751_VFO_OPS, .scan_ops = IC751_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 32, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC751_ALL_RX_MODES, -1, -1, IC751_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1.8), MHz(1.99999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC751_ALL_RX_MODES, -1, -1, IC751_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {MHz(1.8), MHz(1.99999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_OTHER_TX_MODES, W(10), W(200), IC751_VFO_ALL}, {MHz(27.95), MHz(30), IC751_AM_TX_MODES, W(10), W(40), IC751_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC751_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.3)}, {RIG_MODE_RTTY | RIG_MODE_CW, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_CW, Hz(250)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC751_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic751_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .get_level = icom_get_level, .set_ptt = icom_set_ptt,/* Piexx UX-14px has no get_ptt only set_ptt */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/TODO.icom0000644000175000017500000000012514752216205013213 00000000000000hamlib - (C) 2008 Hamlib Group TODO.icom Test and verify each and every model! hamlib-4.6.2/rigs/icom/ic746.c0000644000175000017500000011765614752216205012617 00000000000000/* * Hamlib CI-V backend - description of IC-746 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" #include "misc.h" #include "tones.h" /* * IC-746 and IC-746pro * * TODO: * - advanced scanning functions * - set_ctcss_tone/ctcss_sql * - set keyer? * - test all that stuff.. */ #define IC746_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC746_1HZ_TS_MODES IC746_ALL_RX_MODES /* * 100W in all modes but AM (40W) * deleted rig_mode_tx_modes */ #define IC746_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC746_AM_TX_MODES (RIG_MODE_AM) #define IC746_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_RF|RIG_FUNC_ANF|RIG_FUNC_APF|RIG_FUNC_RESUME|RIG_FUNC_ARO) #define IC746_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_APF|RIG_LEVEL_AGC_TIME|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define IC746_GET_PARM (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP) #define IC746_SET_PARM (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP|RIG_PARM_ANN) #define IC746_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC746_ANTS (RIG_ANT_1|RIG_ANT_2) #define IC746_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC746_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_SLCT|RIG_SCAN_PROG|RIG_SCAN_DELTA) #define IC746_STR_CAL { 16, \ { \ { 0, -60 }, \ { 10, -55 }, \ { 27, -49 }, \ { 45, -42 }, \ { 60, -35 }, \ { 76, -28 }, \ { 89, -21 }, \ { 100, -14 }, \ { 110, -7 }, \ { 120, 0 }, \ { 125, 10 }, \ { 129, 20 }, \ { 133, 30 }, \ { 138, 40 }, \ { 142, 50 }, \ { 146, 60 } \ } } #define IC746PRO_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .split = 1, \ .rptr_shift = 1,\ .ctcss_tone = 1,\ .ctcss_sql = 1, \ .dcs_code = 1, \ .flags = 1, \ .channel_desc = 1, \ } /* Memory channel buffer structure for IC-746 pro and ? Note requires an ack_buff of 64 bytes and data length is 46. */ typedef struct { unsigned char freq[5]; /* little endian frequency */ unsigned char mode; signed char pb; /* passband or filter selection*/ unsigned char data; /* data port 0=off 1=on */ unsigned char dup; /* duplex, tone, tonesql and DTCS Values in hex are "or"ed together 00 = Simplex 10 = -DUP 20 = +DUP 01 = ctcss tone on 02 = tone_sql on 03 = DTCS on */ unsigned char tone[3]; /* ctcss tone bigendian first byte fixed 00 */ unsigned char tone_sql[3]; /* tone squelch frequency as tone */ struct { unsigned char code[2]; /* DTCS code bigendian */ } dcs; } channel_str_t; typedef struct { char chan_flag; /* split 0x10 = on; scan select 0x01 = on */ channel_str_t rx; channel_str_t tx; char name[9]; /*name 9 ascii no null terminator */ } mem_buf_t; #define MAX_MEM_BUF_LEN sizeof(mem_buf_t) /* IC-746 Pro has a 3 "band-stacking registers" defined for each hamband and general coverage. These are updated and rotated when band is changed from front panel. The most recent is rolled down and the oldest discarded. The structure of the register is roughly half a memory buffer. */ typedef channel_str_t band_stack_reg_t; static int ic746_set_parm(RIG *rig, setting_t parm, value_t val); static int ic746_get_parm(RIG *rig, setting_t parm, value_t *val); static int ic746pro_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int ic746pro_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ic746pro_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int ic746pro_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); /* * IC-746 rig capabilities. */ static const struct icom_priv_caps ic746_priv_caps = { 0x56, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_SLOW, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_FAST, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, }; struct rig_caps ic746_caps = { RIG_MODEL(RIG_MODEL_IC746), .model_name = "IC-746", .mfg_name = "Icom", .version = BACKEND_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC746_FUNC_ALL, .has_set_func = IC746_FUNC_ALL, .has_get_level = IC746_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC746_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_ANN, .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC746_VFO_OPS, .scan_ops = IC746_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(108), MHz(174), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, /* most it2 rigs have 108-174 coverage*/ .rx_range_list2 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(108), MHz(174), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC746_1HZ_TS_MODES, 1}, {IC746_ALL_RX_MODES, 100}, {IC746_ALL_RX_MODES, kHz(1)}, {IC746_ALL_RX_MODES, kHz(5)}, {IC746_ALL_RX_MODES, kHz(9)}, {IC746_ALL_RX_MODES, kHz(10)}, {IC746_ALL_RX_MODES, kHz(12.5)}, {IC746_ALL_RX_MODES, kHz(20)}, {IC746_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTYR | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC746_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic746_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = ic746_set_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* IC-746Pro Rig parameters Only available in this namespace. This is a partial list */ #define S_MEM_SC_LEN 2 /* 756PRO S_MEM subcmd length */ #define S_MEM_LCD_CONT 0x501 /* LCD Contrast 0-256/0-100% */ #define S_MEM_BKLIT 0x502 /* Backlight 0-256/0-100% */ #define S_MEM_BEEP 0x506 /* Button confirmation */ #define S_MEM_SQL_CTL 0x508 /* RF/SQL ctl set 0=auto; 1 = sql; 2 = RF+SQL */ #define S_MEM_QSPLT 0x511 /* enable quick split mode */ /* values -9.999 MHz to + 9.999 Mhz */ #define S_MEM_SPLT_OFST 0x512 /* default split offset 4 bytes little endian last byte sign*/ #define S_MEM_SPLT_LOCK 0x513 /* split lock set */ /* values 0.000 MHz to + 9.999 Mhz */ #define S_MEM_HF_DUP_OFST 0x514 /* default HF band duplex offset 3 byte little endian */ #define S_MEM_6M_DUP_OFST 0x515 /* default 50 mHz duplex offset 3 byte little endian */ #define S_MEM_2M_DUP_OFST 0x516 /* default 144 MHz duplex offset 3 byte little endian */ #define S_MEM_AUTO_RPTR 0x518 /* auto repeater set 0=OFF; 1=ON-1; 2=ON-2 */ #define S_MEM_LANG 0x523 /* 0=English 1=Japanese for voice announcer */ #define S_MEM_TRCV 0x536 /* CI-V trancieve mode */ #define S_MEM_CMP_LVL 0x538 /* speech compressor level 0-10 */ #define S_MEM_SBASS 0x539 /* SSB TX tone bass level */ #define S_MEM_RTTY_FL_PB 0x562 /* 0=250 Hz, 1=300' 2 = 350, 3 = 500, 4 = 1 KHz */ #define S_MEM_RTTY_TWNPK 0x563 /* rtty twin peak filter off/on */ #define S_MEM_SCN_SPD 0x570 /* 0 = low; 1 = high */ #define S_MEM_NB_LVL 0x572 /* NB level 0-255 */ #define S_MEM_VOX_GN_LVL 0x573 /* vox gain */ #define S_MEM_AVOX_GN_LVL 0x574 /* anti-vox gain */ #define S_MEM_VOX_DEL_LVL 0x575 /* vox delay 0=0 - 20=2.0 sec */ static const struct confparams ic746pro_ext_parms[] = { { TOK_SSBBASS, "ssbbass", "SSB Tx Tone (Bass)", "SSB Tx Tone (Bass)", NULL, RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } }, { TOK_SQLCTRL, "sqlctrl", "RF/Sql control", "set RF/Squelch control", NULL, RIG_CONF_COMBO, { .c = {{ "Auto", "Sql", "RF+Sql", NULL }} } }, { TOK_RTTY_FLTR, "rttyfltr", "RTTY Fltr Width preset", "Set/Read RTTY preset filter width", "350", RIG_CONF_COMBO, { .c = {{"250", "300", "350", "500", "1000", NULL }} } }, { RIG_CONF_END, NULL, } }; /* * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ /* * IC-746pro rig capabilities. */ static const struct icom_priv_caps ic746pro_priv_caps = { 0x66, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_SLOW, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_FAST, .icom_level = 3 }, { .level = -1, .icom_level = 0 }, }, }; struct rig_caps ic746pro_caps = { RIG_MODEL(RIG_MODEL_IC746PRO), .model_name = "IC-746PRO", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC746_FUNC_ALL | RIG_FUNC_TUNER | RIG_FUNC_VSC, .has_set_func = IC746_FUNC_ALL | RIG_FUNC_TUNER | RIG_FUNC_VSC, .has_get_level = IC746_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC746_LEVEL_ALL), .has_get_parm = IC746_GET_PARM, .has_set_parm = IC746_SET_PARM, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .extparms = ic746pro_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC746_VFO_OPS | RIG_OP_TUNE, .scan_ops = IC746_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 9, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC746PRO_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC746PRO_MEM_CAP }, /* two by two */ { 102, 102, RIG_MTYPE_CALL, IC746PRO_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(144), MHz(146), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(1, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(1, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, /* most it2 rigs have 108-174 coverage*/ .rx_range_list2 = { {kHz(30), MHz(60), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, {MHz(108), MHz(174), IC746_ALL_RX_MODES, -1, -1, IC746_VFO_ALL, IC746_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_6m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_2m(2, IC746_OTHER_TX_MODES, W(5), W(100), IC746_VFO_ALL, IC746_ANTS), FRQ_RNG_HF(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_6m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ FRQ_RNG_2m(2, IC746_AM_TX_MODES, W(2), W(40), IC746_VFO_ALL, IC746_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC746_1HZ_TS_MODES, 1}, {IC746_ALL_RX_MODES, 100}, {IC746_ALL_RX_MODES, kHz(1)}, {IC746_ALL_RX_MODES, kHz(5)}, {IC746_ALL_RX_MODES, kHz(9)}, {IC746_ALL_RX_MODES, kHz(10)}, {IC746_ALL_RX_MODES, kHz(12.5)}, {IC746_ALL_RX_MODES, kHz(20)}, {IC746_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! It might be better to rewrite and just put all filter widths for 1 mode together in 1 record. Remember these are defaults, with dsp rigs you can change them to anything you want (except rtty filter modes). */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, /* There are 5 rtty filters when rtty filter mode is set (default condition) { 1k, 500, 350, 300, 250 }. These are fixed. If rtty filter mode is unset there are 3 general IF filters { 2.4k, 500, 250 are the defaults }. These can be changed. There is a "twin-peak" filter mode as well. It boosts the 2125 and 2295 receive frequency response. The S_FUNC_RF (rtty filter) turns the rtty filter mode on and off. */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, /* RTTY & "normal" IF Filters */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, /* RTTY & "narrow" IF Filters */ {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.4)}, /* "wide" IF filter */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1)}, /*RTTY mode Filter*/ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(350)}, /*"Default " rtty mode filter*/ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, /* RTTY mode Filter */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC746_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic746pro_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = ic746_set_parm, .get_parm = ic746_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .set_ext_parm = ic746pro_set_ext_parm, .get_ext_parm = ic746pro_get_ext_parm, .get_channel = ic746pro_get_channel, .set_channel = ic746pro_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ic746pro_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, ep_len, val_len; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ int icom_val = 0; int retval; ep_len = 0; /* 0 implies BCD data */ val_len = 1; switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; icom_val = val.f; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; /* TODO: check range this actually doesn't decode the input type 'string' */ icom_val = val.i; break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 = 250, 300, 350, 500, 1000 */ if (val.i < 0 || val.i > 4) { return -RIG_EINVAL; } ep_sc = S_MEM_RTTY_FL_PB; icom_val = val.i; break; default: return -RIG_EINVAL; } if (ep_len == 0) { to_bcd_be(epbuf, (long long)icom_val, val_len * 2); ep_len += val_len; } retval = icom_transaction(rig, ep_cmd, ep_sc, epbuf, ep_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ static int ic746pro_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { const struct confparams *cfp; unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val = 0; int cmdhead; int retval; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 */ ep_sc = S_MEM_RTTY_FL_PB; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_ext_parm %s", rig_strparm(token)); return -RIG_EINVAL; } retval = icom_transaction(rig, ep_cmd, ep_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (ep_sc == -1) ? 1 : S_MEM_SC_LEN + 1; res_len -= cmdhead; /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != ep_cmd) { if (resbuf[0] == ACK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } } cfp = rig_ext_lookup_tok(rig, token); switch (cfp->type) { case RIG_CONF_STRING: memcpy(val->s, resbuf, res_len); break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: val->i = from_bcd_be(resbuf + cmdhead, res_len * 2); break; case RIG_CONF_NUMERIC: val->f = from_bcd_be(resbuf + cmdhead, res_len * 2); break; default: rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } /* * icom_set_parm * Assumes rig!=NULL * These are very much rig specific and should probably be in rig files. These are for IC-746Pro. * The 746 has no parameters. */ int ic746_set_parm(RIG *rig, setting_t parm, value_t val) { unsigned char prmbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, prm_len; int prm_cn, prm_sc; int retval, icom_val; prm_cn = C_CTL_MEM; /* Most parm are 0x05xx */ prm_sc = S_MEM_PARM; switch (parm) { case RIG_PARM_ANN: if ((val.i == RIG_ANN_FREQ) || (val.i == RIG_ANN_RXMODE)) { prm_cn = C_CTL_ANN; prm_sc = val.i; prm_len = 0; } else { if ((val.i == RIG_ANN_ENG) || (val.i == RIG_ANN_JAP)) { prm_cn = C_CTL_MEM; prm_sc = S_MEM_LANG; prm_len = 1; prmbuf[0] = (val.i == RIG_ANN_ENG ? 0 : 1); } else { rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm_ann %d\n", val.i); return -RIG_EINVAL; } } break; case RIG_PARM_BACKLIGHT: prm_sc = S_MEM_BKLIT; prm_len = 2; icom_val = val.f * 255 ; to_bcd_be(prmbuf + 1, (long long)icom_val, 4); break; case RIG_PARM_BEEP: prm_sc = S_MEM_BEEP; prm_len = 1; prmbuf[1] = val.i; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm %s\n", rig_strparm(parm)); return -RIG_EINVAL; } retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1) { rig_debug(RIG_DEBUG_ERR, "icom_set_parm: wrong frame len=%d\n", ack_len); return -RIG_EPROTO; } return RIG_OK; } /* * icom_get_parm * Assumes rig!=NULL */ int ic746_get_parm(RIG *rig, setting_t parm, value_t *val) { unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val; int prm_cn, prm_sc; int cmdhead; int retval; prm_cn = C_CTL_MEM; switch (parm) { case RIG_PARM_BACKLIGHT: prm_sc = S_MEM_BKLIT; break; case RIG_PARM_BEEP: prm_sc = S_MEM_BEEP; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_parm %s", rig_strparm(parm)); return -RIG_EINVAL; } retval = icom_transaction(rig, prm_cn, prm_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (prm_sc == -1) ? 1 : 3; res_len -= cmdhead; /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != prm_cn) { if (resbuf[0] == ACK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } } icom_val = from_bcd_be(resbuf + cmdhead, res_len * 2); if (RIG_PARM_IS_FLOAT(parm)) { val->f = (float)icom_val / 255; } else { val->i = icom_val; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } /* * ic746pro_get_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL * * If memory is empty it will return RIG_OK,but every thing will be null. Where do we boundary check? */ int ic746pro_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char chanbuf[MAXFRAMELEN]; int chan_len, freq_len, retval, data_len; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; to_bcd_be(chanbuf, chan->channel_num, 4); chan_len = 2; freq_len = priv->civ_731_mode ? 4 : 5; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, chanbuf, &chan_len); if (retval != RIG_OK) { return retval; } chan->vfo = RIG_VFO_MEM; chan->ant = RIG_ANT_NONE; chan->freq = 0; chan->mode = RIG_MODE_NONE; chan->width = RIG_PASSBAND_NORMAL; chan->rptr_shift = RIG_RPT_SHIFT_NONE; chan->rptr_offs = 0; chan->tuning_step = 0; chan->tx_freq = 0; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = RIG_PASSBAND_NORMAL; chan->tx_vfo = RIG_VFO_NONE; chan->rit = 0; chan->xit = 0; chan->funcs = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PREAMP)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_ATT)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_RF)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_SQL)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_NR)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_IN)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_PBT_OUT)].f = 0; chan->levels[rig_setting2idx(RIG_LEVEL_CWPITCH)].i = 0; chan->levels[rig_setting2idx(RIG_LEVEL_AGC)].i = RIG_AGC_OFF; chan->ctcss_tone = 0; chan->ctcss_sql = 0; chan->dcs_code = 0; chan->dcs_sql = 0; chan->scan_group = 0; chan->flags = RIG_CHFLAG_SKIP; strcpy(chan->channel_desc, " "); /* * chanbuf should contain Cn,Sc, Chan #, Data area */ // Do we get chan_len==1 || chan_len==5 on empty memory? // The IC746Pro returns 1a 00 00 01 ff on a blank channel // So this logic should apply to any Icom with chan_len==5 hopefully if (chan_len == 5 && chanbuf[4] == 0xff) { rig_debug(RIG_DEBUG_TRACE, "%s: chan %d is empty\n", __func__, chan->channel_num); return RIG_OK; } if ((chan_len != freq_len * 2 + 40) && (chan_len != 1)) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, chan_len); return -RIG_ERJCTED; } /* do this only if not a blank channel */ if (chan_len != 1) { int band; int sc; unsigned char databuf[32]; mem_buf_t *membuf; membuf = (mem_buf_t *)(chanbuf + 4); chan->split = (membuf->chan_flag & 0x10) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; chan->flags = (membuf->chan_flag & 0x01) ? RIG_CHFLAG_SKIP : RIG_CHFLAG_NONE; rig_debug(RIG_DEBUG_TRACE, "%s: chan->flags=0x%02x\n", __func__, chan->flags); /* data mode on */ rig_debug(RIG_DEBUG_TRACE, "%s: membuf->rx.data=0x%02x\n", __func__, membuf->rx.data); if (membuf->rx.data) { chan->flags |= RIG_CHFLAG_DATA; } /* * from_bcd requires nibble len */ chan->freq = from_bcd(membuf->rx.freq, freq_len * 2); rig_debug(RIG_DEBUG_TRACE, "%s: chan->freq=%f\n", __func__, chan->freq); icom2rig_mode(rig, membuf->rx.mode, membuf->rx.pb, &chan->mode, &chan->width); chan->rptr_shift = (rptr_shift_t)(membuf->rx.dup >> 8); rig_debug(RIG_DEBUG_TRACE, "%s: chan->rptr_shift=%d\n", __func__, chan->rptr_shift); /* offset is default for the band & is not stored in channel memory. The following retrieves the system default for the band */ band = (int) chan->freq / 1000000; /* hf, 2m or 6 m */ if (band < 50) { sc = S_MEM_HF_DUP_OFST; } else if (band < 108) { sc = S_MEM_6M_DUP_OFST; } else { sc = S_MEM_2M_DUP_OFST; } retval = icom_transaction(rig, C_CTL_MEM, sc, NULL, 0, databuf, &data_len); if (retval != RIG_OK) { return retval; } chan->rptr_offs = from_bcd(databuf + 3, 6) * 100; rig_debug(RIG_DEBUG_TRACE, "%s: chan->rptr_offs=%d\n", __func__, (int)chan->rptr_offs); chan->ctcss_tone = from_bcd_be(membuf->rx.tone, 6); rig_debug(RIG_DEBUG_TRACE, "%s: chan->ctcss_tone=%u\n", __func__, chan->ctcss_tone); chan->ctcss_sql = from_bcd_be(membuf->rx.tone_sql, 6); rig_debug(RIG_DEBUG_TRACE, "%s: chan->ctcss_sql=%u\n", __func__, chan->ctcss_sql); chan->dcs_code = from_bcd_be(membuf->rx.dcs.code, 4); rig_debug(RIG_DEBUG_TRACE, "%s: chan->dcs_code=%u\n", __func__, chan->dcs_code); /* The dcs information include in the channel includes polarity information for both tx and receive. Both directions are enabled when in dcs mode */ chan->tx_freq = from_bcd(membuf->tx.freq, freq_len * 2); rig_debug(RIG_DEBUG_TRACE, "%s: chan->tx_freq=%f\n", __func__, chan->tx_freq); icom2rig_mode(rig, membuf->tx.mode, membuf->tx.pb, &chan->tx_mode, &chan->tx_width); strncpy(chan->channel_desc, membuf->name, 9); chan->channel_desc[9] = '\0'; /* add null terminator */ rig_debug(RIG_DEBUG_TRACE, "%s: chan->channel_desc=%s\n", __func__, chan->channel_desc); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * ic746pro_set_channel * Assumes rig!=NULL, STATE(rig)->priv!=NULL, chan!=NULL */ int ic746pro_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct icom_priv_data *priv; struct rig_state *rs; mem_buf_t membuf = {0}; unsigned char chanbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int chan_len, ack_len, freq_len, retval; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; freq_len = priv->civ_731_mode ? 4 : 5; // set memory channel to_bcd_be(chanbuf, chan->channel_num, 4); chan_len = 2; // if good value, we change the memory otherwise clear if (chan->freq != 0 || chan->mode != 0) { if (chan->split == RIG_SPLIT_ON) { membuf.chan_flag |= 0x10; } else { membuf.chan_flag |= (chan->flags & RIG_CHFLAG_SKIP) ? 0x01 : 0x00; } // RX to_bcd(membuf.rx.freq, chan->freq, freq_len * 2); retval = rig2icom_mode(rig, vfo, chan->mode, chan->width, &membuf.rx.mode, &membuf.rx.pb); if (retval != RIG_OK) { return retval; } if (membuf.rx.pb == -1) { membuf.rx.pb = PD_MEDIUM_3; } membuf.rx.data = (chan->flags & RIG_CHFLAG_DATA) ? 1 : 0; membuf.rx.dup = chan->rptr_shift; // not empty otherwise the call fail if (chan->ctcss_tone == 0) { to_bcd_be(membuf.rx.tone, 885, 6); } else { to_bcd_be(membuf.rx.tone, chan->ctcss_tone, 6); } if (chan->ctcss_sql == 0) { to_bcd_be(membuf.rx.tone_sql, 885, 6); } else { to_bcd_be(membuf.rx.tone_sql, chan->ctcss_sql, 6); } if (chan->dcs_code == 0) { to_bcd_be(membuf.rx.dcs.code, 23, 4); } else { to_bcd_be(membuf.rx.dcs.code, chan->dcs_code, 4); } // TX to_bcd(membuf.tx.freq, chan->tx_freq, freq_len * 2); retval = rig2icom_mode(rig, vfo, chan->tx_mode, chan->tx_width, &membuf.tx.mode, &membuf.tx.pb); if (retval != RIG_OK) { return retval; } if (membuf.tx.pb == -1) { membuf.tx.pb = PD_MEDIUM_3; } membuf.tx.data = (chan->flags & RIG_CHFLAG_DATA) ? 1 : 0; membuf.tx.dup = chan->rptr_shift; // not empty otherwise the call fail if (chan->ctcss_tone == 0) { to_bcd_be(membuf.tx.tone, 885, 6); } else { to_bcd_be(membuf.tx.tone, chan->ctcss_tone, 6); } if (chan->ctcss_sql == 0) { to_bcd_be(membuf.tx.tone_sql, 885, 6); } else { to_bcd_be(membuf.tx.tone_sql, chan->ctcss_sql, 6); } if (chan->dcs_code == 0) { to_bcd_be(membuf.tx.dcs.code, 23, 4); } else { to_bcd_be(membuf.tx.dcs.code, chan->dcs_code, 4); } // set description memcpy(membuf.name, chan->channel_desc, sizeof(membuf.name)); memcpy(chanbuf + chan_len, &membuf, sizeof(mem_buf_t)); chan_len += sizeof(mem_buf_t); retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, chanbuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } else { retval = icom_transaction(rig, C_SET_MEM, -1, chanbuf, chan_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } retval = icom_transaction(rig, C_CLR_MEM, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } return RIG_OK; } hamlib-4.6.2/rigs/icom/frame.h0000644000175000017500000000353114752216205013044 00000000000000/* * Hamlib CI-V backend - low level communication header * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FRAME_H #define _FRAME_H 1 #include #include "rig.h" // Has to be big enough for 0xfe sequence to wake up rig #define MAXFRAMELEN 200 /* * helper functions */ int make_cmd_frame(unsigned char frame[], unsigned char re_id, unsigned char ctrl_id, unsigned char cmd, int subcmd, const unsigned char *data, int data_len); int icom_frame_fix_preamble(int frame_len, unsigned char *frame); int icom_transaction (RIG *rig, int cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len); int read_icom_frame(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len); int read_icom_frame_direct(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len); int rig2icom_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd); void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width); #endif /* _FRAME_H */ hamlib-4.6.2/rigs/icom/ic7760.c0000644000175000017500000003722714752216205012675 00000000000000/* * Hamlib CI-V backend - description of IC-7760 and variations * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Stre #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #define IC7760_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PSK|RIG_MODE_PSKR) #define IC7760_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7760_ALL_RX_MODES IC7760_OTHER_TX_MODES | IC7760_AM_TX_MODES #define IC7760_1HZ_TS_MODES IC7760_ALL_RX_MODES #define IC7760_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) #define IC7760_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7760_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7760_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7760_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7760_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7760_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-7760 calibration data based on manual #define IC7760_STR_CAL { 3, \ { \ { 0,-54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7760_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7760_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7760_RFPOWER_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 143, 100.0f }, \ { 212, 200.0f }, \ { 255, 250.0f }, \ } } #define IC7760_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7760_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC7760_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 165, 10.0f }, \ { 241, 15.0f } \ } } struct cmdparams ic7760_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x82}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7760_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_BACKEND_NONE }; /* * IC-7760 rig capabilities. */ static const struct icom_priv_caps ic7760_priv_caps = { 0xb2, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 4, .ant_count = 4, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7760_extcmds, .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7760_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x02; prmbuf[1] = 0x05; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x02; prmbuf[1] = 0x06; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x02; prmbuf[1] = 0x04; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7760_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x58; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x61; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } static int ic7760_rig_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: enter\n", __func__); return icom_rig_open(rig); } struct rig_caps ic7760_caps = { RIG_MODEL(RIG_MODEL_IC7760), .model_name = "IC-7760", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, // the manual does not show serial speeds .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7760_FUNCS, .has_set_func = IC7760_FUNCS, .has_get_level = IC7760_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7760_LEVELS), .has_get_parm = IC7760_PARMS, .has_set_parm = RIG_PARM_SET(IC7760_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ext_tokens = ic7760_ext_tokens, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, // ?? 7700 can have a different mode on VFOB but requires VFO swap .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7760_VFO_OPS, .scan_ops = IC7760_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7760_ALL_RX_MODES, -1, -1, IC7760_VFOS, IC7760_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_6m(1, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_HF(1, IC7760_AM_TX_MODES, W(.25), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7760_AM_TX_MODES, W(.25), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7760_ALL_RX_MODES, -1, -1, IC7760_VFOS, IC7760_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_6m(2, IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS), FRQ_RNG_HF(2, IC7760_AM_TX_MODES, W(.25), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7760_AM_TX_MODES, W(.251), W(50), IC7760_VFOS, IC7760_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7760_OTHER_TX_MODES, W(1), W(200), IC7760_VFOS, IC7760_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7760_1HZ_TS_MODES, 1}, {IC7760_ALL_RX_MODES, Hz(100)}, {IC7760_ALL_RX_MODES, kHz(1)}, {IC7760_ALL_RX_MODES, kHz(5)}, {IC7760_ALL_RX_MODES, kHz(9)}, {IC7760_ALL_RX_MODES, kHz(10)}, {IC7760_ALL_RX_MODES, kHz(12.5)}, {IC7760_ALL_RX_MODES, kHz(20)}, {IC7760_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7760_STR_CAL, .swr_cal = IC7760_SWR_CAL, .alc_cal = IC7760_ALC_CAL, .rfpower_meter_cal = IC7760_RFPOWER_METER_CAL, .comp_meter_cal = IC7760_COMP_METER_CAL, .vd_meter_cal = IC7760_VD_METER_CAL, .id_meter_cal = IC7760_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7760_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = ic7760_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7760_set_clock, .get_clock = ic7760_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic703.c0000644000175000017500000001706214752216205012576 00000000000000/* * Hamlib CI-V backend - description of IC-703 * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "bandplan.h" #include "idx_builtin.h" #include "tones.h" #define IC703_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC703_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC703_AM_TX_MODES (RIG_MODE_AM) #define IC703_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_MON) #define IC703_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_ALC|RIG_LEVEL_SWR|RIG_LEVEL_METER|RIG_LEVEL_COMP|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_NR|RIG_LEVEL_IF|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT) #define IC703_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC703_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC703_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) #define IC703_ANTS (RIG_ANT_1) /* * IC703_REAL_STR_CAL is accurate measurements * IC703_STR_CAL is what the S-meter displays * * FIXME: calibration data cloned from IC706 */ #define IC703_STR_CAL { 17, \ { \ { 45, -60 }, \ { 46, -54 }, /* S0 */ \ { 54, -48 }, \ { 64, -42 }, \ { 76, -36 }, \ { 84, -30 }, \ { 94, -24 }, \ { 104, -18 }, \ { 113, -12 }, \ { 123, -6 }, \ { 133, 0 }, /* S9 */ \ { 144, 10 }, /* +10 */ \ { 156, 20 }, /* +20 */ \ { 170, 30 }, /* +30 */ \ { 181, 40 }, /* +40 */ \ { 192, 50 }, /* +50 */ \ { 204, 60 } /* +60 */ \ } } /* * ic703 rigs capabilities. */ static const struct icom_priv_caps ic703_priv_caps = { 0x68, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list }; struct rig_caps ic703_caps = { RIG_MODEL(RIG_MODEL_IC703), .model_name = "IC-703", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC703_FUNC_ALL, .has_set_func = IC703_FUNC_ALL, .has_get_level = IC703_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC703_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: 2 levels */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC703_VFO_OPS, .scan_ops = IC703_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 105, RIG_MTYPE_EDGE }, /* two by two */ { 106, 107, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC703_ALL_RX_MODES, -1, -1, IC703_VFO_ALL, IC703_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_6m(1, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_HF(1, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ FRQ_RNG_6m(1, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC703_ALL_RX_MODES, -1, -1, IC703_VFO_ALL, IC703_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_6m(2, IC703_OTHER_TX_MODES, W(0.1), W(10), IC703_VFO_ALL, IC703_ANTS), FRQ_RNG_HF(2, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ FRQ_RNG_6m(2, IC703_AM_TX_MODES, W(0.1), W(4), IC703_VFO_ALL, IC703_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC703_ALL_RX_MODES, 10}, {IC703_ALL_RX_MODES, 100}, {IC703_ALL_RX_MODES, kHz(1)}, {IC703_ALL_RX_MODES, kHz(5)}, {IC703_ALL_RX_MODES, kHz(9)}, {IC703_ALL_RX_MODES, kHz(10)}, {IC703_ALL_RX_MODES, 12500}, {IC703_ALL_RX_MODES, kHz(20)}, {IC703_ALL_RX_MODES, kHz(25)}, {IC703_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(9)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(9)}, /* narrow w/ builtin FL-94 */ RIG_FLT_END, }, .str_cal = IC703_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic703_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr30.c0000644000175000017500000002124114752216205012663 00000000000000/* * Hamlib CI-V backend - description of IC-R30 * Copyright (c) 2018 Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "token.h" #include "icom.h" #include "idx_builtin.h" #include "icom_defs.h" #include "frame.h" #include "tones.h" #define ICR30_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_AM|RIG_MODE_AMN|\ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_WFM|\ RIG_MODE_RTTYR|RIG_MODE_SAM|RIG_MODE_SAL|RIG_MODE_SAH|RIG_MODE_P25|\ RIG_MODE_DSTAR|RIG_MODE_DPMR|RIG_MODE_NXDNVN|RIG_MODE_NXDN_N|RIG_MODE_DCR) #define ICR30_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_TSQL|RIG_FUNC_AFC|RIG_FUNC_VSC|\ RIG_FUNC_CSQL|RIG_FUNC_DSQL|RIG_FUNC_ANL|RIG_FUNC_CSQL|RIG_FUNC_SCEN) #define ICR30_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|\ RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define ICR30_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define ICR30_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR30_SCAN_OPS (RIG_SCAN_NONE) #define TOK_ANL TOKEN_BACKEND(001) #define TOK_EAR TOKEN_BACKEND(002) #define TOK_REC TOKEN_BACKEND(003) int icr30_tokens[] = { TOK_ANL, TOK_EAR, TOK_REC, TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_GPS_DATA, TOK_DSTAR_GPS_MESS, TOK_DSTAR_CODE, TOK_DSTAR_TX_DATA, TOK_BACKEND_NONE }; struct confparams icr30_ext[] = { { TOK_ANL, "anl", "Auto noise limiter", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_EAR, "ear", "Earphone mode", "", "", RIG_CONF_CHECKBUTTON, {} }, { TOK_REC, "record", "Recorder on/off", "", "", RIG_CONF_CHECKBUTTON, {} }, { 0 } }; struct cmdparams icr30_extcmds[] = { { {.t = TOK_ANL}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, S_MEM_ANL, SC_MOD_RW, 0, {}, CMD_DAT_BOL, 1 }, { {.t = TOK_EAR}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, S_MEM_EAR, SC_MOD_RW, 0, {}, CMD_DAT_BOL, 1 }, { {.t = TOK_REC}, CMD_PARAM_TYPE_TOKEN, C_CTL_MEM, S_MEM_REC, SC_MOD_WR, 0, {}, CMD_DAT_BOL, 1 }, { {0} } }; #define ICR30_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 255, 60 } /* +60 */ \ } } /* * This function does the special bandwidth coding for IC-R30 * (1 - normal, 2 - narrow) */ static int icr30_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (*pd == PD_NARROW_3) { *pd = PD_NARROW_2; } return err; } /* * This function handles the -N modes for IC-R30 */ int icr30_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { if (mode & (RIG_MODE_AMN | RIG_MODE_FMN)) { return icom_set_mode(rig, vfo, mode, (pbwidth_t)1); } else { return icom_set_mode(rig, vfo, mode, width); } } static struct icom_priv_caps icr30_priv_caps = { 0x9c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list, /* wrong, but don't have set_ts anyway */ .antack_len = 2, .ant_count = 2, .r2i_mode = icr30_r2i_mode, .offs_len = 4, .extcmds = icr30_extcmds /* Custom ext_parm parameters */ }; struct rig_caps icr30_caps = { RIG_MODEL(RIG_MODEL_ICR30), .model_name = "IC-R30", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR30_FUNC_ALL, .has_set_func = ICR30_FUNC_ALL, .has_get_level = ICR30_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR30_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ext_tokens = icr30_tokens, .extfuncs = icr30_ext, .extparms = icom_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 15, 30, 35, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR30_VFO_OPS, .scan_ops = ICR30_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 999, RIG_MTYPE_MEM }, /* TBC */ { 1000, 1199, RIG_MTYPE_MEM }, /* auto-write */ { 1200, 1299, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { /* Other countries but France */ {kHz(100), GHz(3.3049999), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(100), MHz(821.995), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, {MHz(851), MHz(866.995), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, {MHz(896), GHz(3.3049999), ICR30_MODES, -1, -1, ICR30_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR30_MODES, Hz(10)}, {ICR30_MODES, Hz(100)}, {ICR30_MODES, Hz(1000)}, {ICR30_MODES, Hz(3125)}, {ICR30_MODES, Hz(5000)}, {ICR30_MODES, Hz(6250)}, {ICR30_MODES, Hz(8330)}, {ICR30_MODES, Hz(9000)}, {ICR30_MODES, Hz(10000)}, {ICR30_MODES, Hz(12500)}, {ICR30_MODES, kHz(15)}, {ICR30_MODES, kHz(20)}, {ICR30_MODES, kHz(25)}, {ICR30_MODES, kHz(30)}, {ICR30_MODES, kHz(50)}, {ICR30_MODES, kHz(100)}, {ICR30_MODES, kHz(125)}, {ICR30_MODES, kHz(200)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_USB | RIG_MODE_LSB, kHz(1.8)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_AMN | RIG_MODE_FMN, kHz(12)}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_AMN | RIG_MODE_FMN, kHz(6)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR30_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .priv = (void *)& icr30_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icr30_set_mode, .get_mode = icom_get_mode, .vfo_op = icom_vfo_op, .set_vfo = icom_set_vfo, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_bank = icom_set_bank, .set_mem = icom_set_mem, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .get_dcd = icom_get_dcd, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic9100.c0000644000175000017500000002613614752216205012660 00000000000000/* * Hamlib CI-V backend - description of IC-9100 (HF/VHF/UHF All-Mode Transceiver) * Copyright (c) 2000-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "icom.h" #include "icom_defs.h" #include "idx_builtin.h" #include "bandplan.h" #include "tones.h" #define IC9100_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\ RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define IC9100_OTHER_TX_MODES ((IC9100_MODES) & ~RIG_MODE_AM) #define IC9100_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) #define IC9100_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC9100_VFO_OPS (RIG_OP_FROM_VFO| \ RIG_OP_TO_VFO| \ RIG_OP_CPY| \ RIG_OP_MCL| \ RIG_OP_XCHG| \ RIG_OP_TUNE) #define IC9100_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC| \ RIG_FUNC_SATMODE| \ RIG_FUNC_DUAL_WATCH| \ RIG_FUNC_VSC| \ RIG_FUNC_MN| \ RIG_FUNC_LOCK| \ RIG_FUNC_SCOPE) #define IC9100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_NR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_KEYSPD| \ RIG_LEVEL_COMP| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY| \ RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_APF| \ RIG_LEVEL_AGC| \ RIG_LEVEL_PBT_IN| \ RIG_LEVEL_PBT_OUT| \ RIG_LEVEL_NOTCHF_RAW| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP| \ RIG_LEVEL_MONITOR_GAIN| \ RIG_LEVEL_AGC_TIME) #define IC9100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC9100_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ #define IC9100_HF_ANTS (RIG_ANT_1|RIG_ANT_2) struct cmdparams ic9100_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x27}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x02}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; static const struct icom_priv_caps ic9100_priv_caps = { 0x7c, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flicker */ ic910_ts_sc_list, /* FIXME */ .antack_len = 2, .ant_count = 2, .extcmds = ic9100_extcmds, .x25x26_always = 0, .x25x26_possibly = 0, .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // borrow this as they behave the same extern int ic9700_set_vfo(RIG *rig, vfo_t vfo); struct rig_caps ic9100_caps = { RIG_MODEL(RIG_MODEL_IC9100), .model_name = "IC-9100", .mfg_name = "Icom", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC9100_FUNC_ALL, .has_set_func = IC9100_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = IC9100_LEVEL_ALL | RIG_LEVEL_RAWSTR | RIG_LEVEL_SWR, .has_set_level = IC9100_LEVEL_ALL, .has_get_parm = IC9100_PARM_ALL, .has_set_parm = IC9100_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = {20, RIG_DBLST_END, }, .attenuator = {20, RIG_DBLST_END, }, .max_rit = kHz(9.999), .max_xit = kHz(9.999), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC9100_VFO_OPS, .scan_ops = IC9100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 9, /* TODO */ .chan_list = { /* TBC */ { 1, 396, RIG_MTYPE_MEM }, { 397, 400, RIG_MTYPE_CALL }, { 401, 424, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { /* Europe */ {kHz(30), MHz(60), IC9100_MODES, -1, -1, IC9100_VFO_ALL, IC9100_HF_ANTS}, {kHz(136), MHz(174), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(2), W(25), IC9100_VFO_ALL, IC9100_HF_ANTS), /* only HF */ FRQ_RNG_6m(1, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_2m(1, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(1, IC9100_OTHER_TX_MODES, W(2), W(75), IC9100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION1(IC9100_OTHER_TX_MODES, W(1), W(10), IC9100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(30), MHz(60), IC9100_MODES, -1, -1, IC9100_VFO_ALL, IC9100_HF_ANTS}, {kHz(136), MHz(174), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC9100_MODES, -1, -1, IC9100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(2), W(25), IC9100_VFO_ALL, IC9100_HF_ANTS), /* only HF */ /* USA only, TBC: end of range and modes */ {MHz(5.255), MHz(5.405), IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS}, /* USA only */ {MHz(5.255), MHz(5.405), RIG_MODE_AM, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS}, /* USA only */ FRQ_RNG_6m(2, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, IC9100_HF_ANTS), FRQ_RNG_2m(2, IC9100_OTHER_TX_MODES, W(2), W(100), IC9100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(2, IC9100_OTHER_TX_MODES, W(2), W(75), IC9100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION2(IC9100_OTHER_TX_MODES, W(1), W(10), IC9100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(0.1)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_FM, kHz(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.4)}, /* builtin */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_FM, kHz(15)}, /* builtin */ {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* builtin */ RIG_FLT_END, }, .str_cal = IC9100_STR_CAL, .priv = (void *)& ic9100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icom_set_freq, .get_mode = icom_get_mode, .set_mode = icom_set_mode, .set_vfo = ic9700_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = icom_get_func, .set_func = icom_set_func, .get_level = icom_get_level, .set_level = icom_set_level, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_code, .get_dcs_sql = icom_get_dcs_code, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icrx7.c0000644000175000017500000001023214752216205012775 00000000000000/* * Hamlib CI-V backend - description of IC-RX7 * Copyright (c) 2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #define ICRX7_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ICRX7_FUNC_ALL (RIG_FUNC_NONE) #define ICRX7_LEVEL_ALL (RIG_LEVEL_RAWSTR) #define ICRX7_VFO_ALL (RIG_VFO_A) #define ICRX7_VFO_OPS (RIG_OP_NONE) #define ICRX7_SCAN_OPS (RIG_SCAN_NONE) /* * FIXME: S-meter measurement */ #define ICRX7_STR_CAL UNKNOWN_IC_STR_CAL static struct icom_priv_caps icrx7_priv_caps = { 0x78, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list /* wrong, but don't have set_ts anyway */ }; struct rig_caps icrx7_caps = { RIG_MODEL(RIG_MODEL_ICRX7), .model_name = "IC-RX7", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICRX7_FUNC_ALL, .has_set_func = ICRX7_FUNC_ALL, .has_get_level = ICRX7_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICRX7_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICRX7_VFO_OPS, .scan_ops = ICRX7_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* Unfortunately, not accessible through CI-V */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), GHz(1.3), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(821.995), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, {MHz(851), MHz(866.995), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, {MHz(896), GHz(1.3), ICRX7_MODES, -1, -1, ICRX7_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICRX7_MODES, Hz(100)}, RIG_TS_END, }, .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICRX7_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icrx7_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, /* TODO: do not pass bandwidth data */ .get_mode = icom_get_mode, .decode_event = icom_decode_event, .get_level = icom_get_level, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic785x.c0000644000175000017500000004375414752216205013007 00000000000000/* * Hamlib CI-V backend - description of IC-785x and variations * Derived from ic7800.c by W9MDB -- needs testing * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "ic7300.h" #define IC785x_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC785x_1HZ_TS_MODES IC785x_ALL_RX_MODES #define IC785x_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC785x_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC785x_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD) #define IC785x_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_SPECTRUM_ATT|RIG_LEVEL_AGC_TIME) #define IC785x_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC785x_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_KEYERTYPE) #define IC785x_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC785x_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC785x_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-785x S-meter calibration data based on manual #define IC785x_STR_CAL { 3, \ { \ { 0, -54 }, /* S0 */ \ { 120, 0 }, /* S9 */ \ { 241, 60 } /* S9+60 */ \ } } #define IC785x_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC785x_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC785x_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC785x_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC785x_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC785x_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 146, 15.0f }, \ { 241, 25.0f } \ } } extern int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); extern int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int ic785x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ic785x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); struct cmdparams ic785x_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x04}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x76}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x96}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x03, 0x09}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x55}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x87}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x52}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x54}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic785x_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_SCOPE_MSS, TOK_SCOPE_SDS, TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_SCOPE_MKP, TOK_BACKEND_NONE }; /* * IC-785x rig capabilities. */ static struct icom_priv_caps ic785x_priv_caps = { 0x8e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 4, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 689, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 200, .signal_strength_min = -100, .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic785x_extcmds, .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic785x_caps = { RIG_MODEL(RIG_MODEL_IC785x), .model_name = "IC-7850/7851", .mfg_name = "Icom", .version = BACKEND_VER ".8", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC785x_FUNCS, .has_set_func = IC785x_FUNCS, .has_get_level = IC785x_LEVELS, .has_set_level = RIG_LEVEL_SET(IC785x_LEVELS), .has_get_parm = IC785x_PARMS, .has_set_parm = RIG_PARM_SET(IC785x_PARMS), /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic785x_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 12, 20, RIG_DBLST_END, }, .attenuator = { 3, 6, 9, 12, 15, 18, 21, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .vfo_ops = IC785x_VFO_OPS, .scan_ops = IC785x_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC785x_ALL_RX_MODES, -1, -1, IC785x_VFOS, IC785x_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_6m(1, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_HF(1, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ FRQ_RNG_6m(1, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC785x_ALL_RX_MODES, -1, -1, IC785x_VFOS, IC785x_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_6m(2, IC785x_OTHER_TX_MODES, W(5), W(200), IC785x_VFOS, IC785x_ANTS), FRQ_RNG_HF(2, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ FRQ_RNG_6m(2, IC785x_AM_TX_MODES, W(5), W(50), IC785x_VFOS, IC785x_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC785x_OTHER_TX_MODES, W(2), W(100), IC785x_VFOS, IC785x_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC785x_1HZ_TS_MODES, 1}, {IC785x_ALL_RX_MODES, Hz(100)}, {IC785x_ALL_RX_MODES, kHz(1)}, {IC785x_ALL_RX_MODES, kHz(5)}, {IC785x_ALL_RX_MODES, kHz(9)}, {IC785x_ALL_RX_MODES, kHz(10)}, {IC785x_ALL_RX_MODES, kHz(12.5)}, {IC785x_ALL_RX_MODES, kHz(20)}, {IC785x_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC785x_STR_CAL, .swr_cal = IC785x_SWR_CAL, .alc_cal = IC785x_ALC_CAL, .rfpower_meter_cal = IC785x_RFPOWER_METER_CAL, .comp_meter_cal = IC785x_COMP_METER_CAL, .vd_meter_cal = IC785x_VD_METER_CAL, .id_meter_cal = IC785x_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .spectrum_attenuator = { 10, 20, 30, RIG_DBLST_END, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic785x_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = ic785x_set_level, .get_level = ic785x_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7300_set_clock, .get_clock = ic7300_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int ic785x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { return ic7800_set_level(rig, vfo, level, val); } int ic785x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { return ic7800_get_level(rig, vfo, level, val); } hamlib-4.6.2/rigs/icom/Android.mk0000644000175000017500000000152514752216205013513 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ic706.c icr8500.c ic735.c ic775.c ic756.c \ ic275.c ic475.c ic1275.c ic820h.c ic821h.c \ icr7000.c ic910.c ic9100.c ic970.c ic725.c ic737.c ic718.c \ os535.c os456.c omni.c delta2.c ic92d.c \ ic736.c ic738.c ic7410.c ic746.c ic703.c ic726.c ic271.c \ ic765.c ic781.c ic471.c icr9000.c icr9500.c \ icr10.c icr20.c icr6.c icr71.c icr72.c icr75.c icrx7.c \ id1.c id5100.c ic2730.c \ ic707.c ic728.c ic751.c ic761.c \ ic78.c ic7800.c ic7000.c ic7100.c ic7200.c ic7600.c ic7700.c \ icom.c frame.c optoscan.c x108g.c perseus.c id4100.c id51.c \ id31.c icr8600.c ic7300.c ic7610.c icr30.c ic785x.c LOCAL_MODULE := icom LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/icom/perseus.c0000644000175000017500000001270114752216205013432 00000000000000/* * Hamlib CI-V backend - Perseus description * Copyright (c) 2016 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "frame.h" /* TODO: $09 DRM, $0a USER */ #define PERSEUS_MODES (RIG_MODE_AM|RIG_MODE_SAM|RIG_MODE_SSB| \ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY|RIG_MODE_RTTYR| \ RIG_MODE_FM) #define PERSEUS_FUNCS (RIG_FUNC_NONE) /* TODO (not standard) : * RIG_LEVEL_AGC|RIG_LEVEL_NB|RIG_LEVEL_ANR|RIG_LEVEL_ANR|RIG_LEVEL_AF|RIG_LEVEL_ANF */ #define PERSEUS_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define PERSEUS_PARMS (RIG_PARM_NONE) /* S-Meter calibration, according to the Reference Manual */ #define PERSEUS_STR_CAL { 2, \ { \ { 0, -67 }, /* -140 dBm */ \ { 255, 103 }, /* +30 dBm */ \ } } static int perseus_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd); static void perseus_i2r_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width); static struct icom_priv_caps perseus_priv_caps = { 0xE1, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ .r2i_mode = perseus_r2i_mode, .i2r_mode = perseus_i2r_mode, }; /* * PERSEUS rigs capabilities. * * PERSEUS Receiver CAT Interface Reference Manual (Revision EN03) : * http://microtelecom.it/perseus/PERSEUS_CI-V_Interface-EN03.pdf */ struct rig_caps perseus_caps = { RIG_MODEL(RIG_MODEL_PERSEUS), .model_name = "Perseus", .mfg_name = "Microtelecom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = PERSEUS_FUNCS, .has_set_func = PERSEUS_FUNCS, .has_get_level = PERSEUS_LEVELS, .has_set_level = RIG_LEVEL_SET(PERSEUS_LEVELS), .has_get_parm = PERSEUS_PARMS, .has_set_parm = PERSEUS_PARMS, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = RIG_OP_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), MHz(30), PERSEUS_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), MHz(30), PERSEUS_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {PERSEUS_MODES, 100}, /* resolution */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_SAM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = PERSEUS_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& perseus_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_level = icom_set_level, .get_level = icom_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * This function does the special bandwidth coding for the Perseus * * NB: the filter width will be ignored. */ static int perseus_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err == 0 && mode == RIG_MODE_SAM) { *md = 0x06; } return err; } static void perseus_i2r_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width) { icom2rig_mode(rig, md, pd, mode, width); if (md == 0x06) { *mode = RIG_MODE_SAM; } } hamlib-4.6.2/rigs/icom/README.icom0000644000175000017500000000301614752216205013405 00000000000000hamlib - Copyright (C) 2008 The Hamlib Group File: README.icom Notes on Icom backends 2008-03, AA6E: Tested and extended omni.c for Ten-Tec Omni VI and Omni VI Plus It is now at least "beta" level. 2008-07, AA6E: Tests with IC-756PROIII at ARRL. Added AF, RF, SQL levels, COMP, BALANCE. Note: communications do not seem completely reliable for baud rates > 9600. VOX-related commands are implemented for the '910H but are wrong for the '756 and other models. They should be reimplemented in a more general way. 2008-10, DL1JBE: Tested IC-275H and IC-475H at local clubstation. Offered functions do work as expected in most cases. Only problem: Bandwidth in Get_Mode is reported always as 0. Besides this backend seems to be stable -> Changing State to RIG_STATUS_BETA. 2020-02, W9MDB: Antenna count and ack length for existing Icom's with antenna settings Model #Ant ack length 7100 2 2 737 2 2 7410 2 2 746 2 2 746 2 2 756 2 2 756 2 2 756 2 2 756 2 2 7600 2 3 7610 2 3 7700 4 3 7800 4 3 785x 4 3 9100 2 2 icr30 2 2 icr6 2 2 icr75 2 2 icr8600 3 2 icr9000 2 2 icr9500 3 2 2020-09, G0GJV Attempting to support RIT. I asked ICOM technical support "I am doing some work on the Hamlib amateur radio control library, and in particular looking at control of RIT via CI-V on the Icom IC-9100 Is my reading of the manual correct - on this (and most older Icom rigs) - there is no RIT/XIT control available?" and received the answer "Hi Mike, Yes that's right Thanks Virgil" So I've removed the erroneous icom_set_rit function.hamlib-4.6.2/rigs/icom/ic1275.c0000644000175000017500000001020614752216205012654 00000000000000/* * Hamlib CI-V backend - description of IC-1275 and variations * Copyright (c) 2000-2012 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC1275_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC1275_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC1275_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) static const struct icom_priv_caps ic1275_priv_caps = { 0x18, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic1275_caps = { RIG_MODEL(RIG_MODEL_IC1275), .model_name = "IC-1275", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC1275_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(1240), MHz(1300), IC1275_MODES, -1, -1, IC1275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1240), MHz(1300), IC1275_MODES, W(1), W(10), IC1275_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(1240), MHz(1300), IC1275_MODES, -1, -1, IC1275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(1240), MHz(1300), IC1275_MODES, W(1), W(10), IC1275_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC1275_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_CW, Hz(500)}, /* optional FL-83 CW narrow filter */ {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic1275_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr8600.c0000644000175000017500000002700114752216205013036 00000000000000/* * Hamlib CI-V backend - description of IC-R8600 * Copyright (c) 2000-2004 by Stephane Fillod * Copyright (c) 2018 by Ekki Plicht * Copyright (c) 2019 by Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "idx_builtin.h" #include "token.h" #include "tones.h" #include "icom.h" #include "icom_defs.h" #define ICR8600_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_RTTY|\ RIG_MODE_FM|RIG_MODE_WFM|RIG_MODE_CWR|RIG_MODE_RTTYR|RIG_MODE_SAM|RIG_MODE_SAL|\ RIG_MODE_SAH|RIG_MODE_P25|RIG_MODE_DSTAR|RIG_MODE_DPMR|RIG_MODE_NXDNVN|\ RIG_MODE_NXDN_N|RIG_MODE_DCR) #define ICR8600_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_MN|RIG_FUNC_AFC|\ RIG_FUNC_NR|RIG_FUNC_AIP|RIG_FUNC_LOCK|RIG_FUNC_VSC|RIG_FUNC_RESUME|RIG_FUNC_TSQL|\ RIG_FUNC_CSQL|RIG_FUNC_DSQL|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_OVF_STATUS) #define ICR8600_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_PREAMP|\ RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|\ RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|\ RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_USB_AF|RIG_LEVEL_AGC_TIME) #define ICR8600_PARM_ALL (RIG_PARM_BACKLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME|RIG_PARM_KEYLIGHT) #define ICR8600_VFO_ALL (RIG_VFO_VFO|RIG_VFO_MEM) #define ICR8600_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR8600_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|\ RIG_SCAN_PRIO|RIG_SCAN_PRIO|RIG_SCAN_DELTA|RIG_SCAN_STOP) #define ICR8600_ANTS_HF (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define ICR8600_ANTS_VHF (RIG_ANT_1) #define ICR8600_STR_CAL { 2, {\ { 0, -60 }, \ { 255, 60 }, \ } } struct cmdparams icr8600_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x38}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x15}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x16}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x32}, CMD_DAT_TIM, 2 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x92}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x40}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x81}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_NONE} } }; int icr8600_tokens[] = { TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_GPS_DATA, TOK_DSTAR_GPS_MESS, TOK_DSTAR_CODE, TOK_DSTAR_TX_DATA, TOK_SCOPE_CFQ, TOK_SCOPE_VBW, TOK_BACKEND_NONE }; #define ICR8600_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .levels = RIG_LEVEL_ATT|RIG_LEVEL_PREAMP, \ .channel_desc = 1, \ .flags = 1, \ } static struct icom_priv_caps icr8600_priv_caps = { 0x96, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8600_ts_sc_list, /* list of tuning steps */ .antack_len = 2, .ant_count = 3, .offs_len = 4, /* Repeater offset is 4 bytes */ .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -100, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 0, .high_freq = 3000000000, }, }, .extcmds = icr8600_extcmds /* Custom ext_cmd parameters */ }; struct rig_caps icr8600_caps = { RIG_MODEL(RIG_MODEL_ICR8600), .model_name = "IC-R8600", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .has_get_func = ICR8600_FUNC_ALL, .has_set_func = ICR8600_FUNC_ALL, .has_get_level = ICR8600_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR8600_LEVEL_ALL), .has_get_parm = ICR8600_PARM_ALL, .has_set_parm = RIG_PARM_SET(ICR8600_PARM_ALL), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = {.i = 0}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_TIME] = { .min = { .i = 0 }, .max = { .i = 86399} } }, .ext_tokens = icr8600_tokens, .extlevels = icom_ext_levels, .extfuncs = icom_ext_funcs, .extparms = icom_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 20, RIG_DBLST_END, }, /* 20 on HF, 14 on VHF, UHF, same setting */ .attenuator = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = ICR8600_VFO_OPS, .scan_ops = ICR8600_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 100, .chan_desc_sz = 16, .chan_list = { { 0, 99, RIG_MTYPE_MEM, ICR8600_MEM_CAP }, { 0, 99, RIG_MTYPE_EDGE, ICR8600_MEM_CAP }, /* to be extended */ RIG_CHAN_END, }, .rx_range_list1 = { { kHz(10), MHz(3000), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_VHF }, { kHz(10), MHz(30), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_HF }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { kHz(10), MHz(3000), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_VHF }, { kHz(10), MHz(30), ICR8600_MODES, -1, -1, ICR8600_VFO_ALL, ICR8600_ANTS_HF }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR8600_MODES, Hz(100)}, {ICR8600_MODES, kHz(1)}, {ICR8600_MODES, kHz(2.5)}, {ICR8600_MODES, kHz(3.125)}, {ICR8600_MODES, kHz(5)}, {ICR8600_MODES, kHz(6.25)}, {ICR8600_MODES, kHz(8.33)}, {ICR8600_MODES, kHz(9)}, {ICR8600_MODES, kHz(10)}, {ICR8600_MODES, kHz(12.5)}, {ICR8600_MODES, kHz(20)}, {ICR8600_MODES, kHz(25)}, {ICR8600_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(1.9)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(6)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_AMS, kHz(15)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = ICR8600_STR_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .priv = (void *)& icr8600_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_bank = icom_set_bank, .get_rptr_offs = icom_get_rptr_offs, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_shift = icom_set_rptr_shift, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .get_dcd = icom_get_dcd, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic706.c0000644000175000017500000005601514752216205012602 00000000000000/* * Hamlib CI-V backend - description of IC-706 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" #include "tones.h" /* * This function does the special bandwidth coding for IC-706, IC-706MKII * and IC-706MKIIG * (0 - wide, 1 - normal, 2 - narrow) */ static int ic706_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err != RIG_OK) { return err; } if (width != RIG_PASSBAND_NOCHANGE) { if (*pd == -1) { *pd = PD_MEDIUM_2; } else { (*pd)--; } } return RIG_OK; } #define IC706_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_WFM) #define IC706_1MHZ_TS_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define IC706_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) /* tx doesn't have WFM. * 100W in all modes but AM (40W) */ #define IC706_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC706_AM_TX_MODES (RIG_MODE_AM) #define IC706IIG_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) #define IC706IIG_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define IC706_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC706_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC706_SCAN_OPS (RIG_SCAN_MEM) /* * IC706IIG_REAL_STR_CAL is accurate measurements * IC706IIG_STR_CAL is what the S-meter displays * * calibration data was obtained from W8WWV * http://www.seed-solutions.com/gregordy/ */ #define IC706IIG_REAL_STR_CAL { 16, \ { \ { 46, -27 }, /* S0 */ \ { 54, -25 }, \ { 64, -24 }, \ { 76, -23 }, \ { 84, -22 }, \ { 94, -20 }, \ { 104, -16 }, \ { 113, -11 }, \ { 123, -5 }, \ { 133, 0 }, /* S9 */ \ { 144, 5 }, /* +10 */ \ { 156, 10 }, /* +20 */ \ { 170, 16 }, /* +30 */ \ { 181, 21 }, /* +40 */ \ { 192, 26 }, /* +50 */ \ { 204, 35 } /* +60 */ \ } } #define IC706IIG_STR_CAL { 17, \ { \ { 45, -60 }, \ { 46, -54 }, /* S0 */ \ { 54, -48 }, \ { 64, -42 }, \ { 76, -36 }, \ { 84, -30 }, \ { 94, -24 }, \ { 104, -18 }, \ { 113, -12 }, \ { 123, -6 }, \ { 133, 0 }, /* S9 */ \ { 144, 10 }, /* +10 */ \ { 156, 20 }, /* +20 */ \ { 170, 30 }, /* +30 */ \ { 181, 40 }, /* +40 */ \ { 192, 50 }, /* +50 */ \ { 204, 60 } /* +60 */ \ } } /* * ic706 rigs capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! */ static const struct icom_priv_caps ic706_priv_caps = { 0x48, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .r2i_mode = ic706_r2i_mode }; struct rig_caps ic706_caps = { RIG_MODEL(RIG_MODEL_IC706), .model_name = "IC-706", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC706_VFO_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), 199999999, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), 1999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, /* 100W class */ {kHz(1800), 1999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, /* 40W class */ {kHz(3500), 3999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(3500), 3999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(144), MHz(148), IC706_OTHER_TX_MODES, 5000, 20000, IC706_VFO_ALL}, /* not sure.. */ {MHz(144), MHz(148), IC706_AM_TX_MODES, 2000, 8000, IC706_VFO_ALL}, /* anyone? */ RIG_FRNG_END, }, .tuning_steps = {{IC706_1HZ_TS_MODES, 1}, {IC706_ALL_RX_MODES, 10}, {IC706_ALL_RX_MODES, 100}, {IC706_ALL_RX_MODES, kHz(1)}, {IC706_ALL_RX_MODES, kHz(5)}, {IC706_ALL_RX_MODES, kHz(9)}, {IC706_ALL_RX_MODES, kHz(10)}, {IC706_ALL_RX_MODES, 12500}, {IC706_ALL_RX_MODES, kHz(20)}, {IC706_ALL_RX_MODES, kHz(25)}, {IC706_ALL_RX_MODES, kHz(100)}, {IC706_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ {RIG_MODE_WFM, kHz(230)}, /* WideFM, filter FL?? */ RIG_FLT_END, }, .str_cal = IC706IIG_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .priv = (void *)& ic706_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static const struct icom_priv_caps ic706mkii_priv_caps = { 0x4e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .r2i_mode = ic706_r2i_mode }; struct rig_caps ic706mkii_caps = { RIG_MODEL(RIG_MODEL_IC706MKII), .model_name = "IC-706MkII", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC706_VFO_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), 199999999, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), 1999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, /* 100W class */ {kHz(1800), 1999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, /* 40W class */ {kHz(3500), 3999999, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(3500), 3999999, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(144), MHz(148), IC706_OTHER_TX_MODES, 5000, 20000, IC706_VFO_ALL}, /* not sure.. */ {MHz(144), MHz(148), IC706_AM_TX_MODES, 2000, 8000, IC706_VFO_ALL}, /* anyone? */ RIG_FRNG_END, }, .tuning_steps = { {IC706_1HZ_TS_MODES, 1}, {IC706_ALL_RX_MODES, 10}, {IC706_ALL_RX_MODES, 100}, {IC706_ALL_RX_MODES, kHz(1)}, {IC706_ALL_RX_MODES, kHz(5)}, {IC706_ALL_RX_MODES, kHz(9)}, {IC706_ALL_RX_MODES, kHz(10)}, {IC706_ALL_RX_MODES, 12500}, {IC706_ALL_RX_MODES, kHz(20)}, {IC706_ALL_RX_MODES, kHz(25)}, {IC706_ALL_RX_MODES, kHz(100)}, {IC706_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ {RIG_MODE_WFM, kHz(230)}, /* WideFM, filter FL?? */ RIG_FLT_END, }, .str_cal = IC706IIG_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .priv = (void *)& ic706mkii_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC706MkIIG channel caps. */ #define IC706MKIIG_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, /* only set */ \ .funcs = IC706IIG_FUNC_ALL, \ .levels = RIG_LEVEL_SET(IC706IIG_LEVEL_ALL), \ } /* * Basically, the IC706MKIIG is an IC706MKII plus UHF, a DSP * and 50W VHF */ static const struct icom_priv_caps ic706mkiig_priv_caps = { 0x58, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic706_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .r2i_mode = ic706_r2i_mode }; struct rig_caps ic706mkiig_caps = { RIG_MODEL(RIG_MODEL_IC706MKIIG), .model_name = "IC-706MkIIG", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC706IIG_FUNC_ALL, .has_set_func = IC706IIG_FUNC_ALL, .has_get_level = IC706IIG_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC706IIG_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC706_VFO_OPS, .scan_ops = IC706_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC706MKIIG_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, IC706MKIIG_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, IC706MKIIG_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(200) - 1, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, /* this trx also has UHF */ {MHz(400), MHz(470), IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC706_OTHER_TX_MODES, W(5), W(100), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_HF(1, IC706_AM_TX_MODES, W(2), W(40), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC706_OTHER_TX_MODES, W(5), W(100), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_6m(1, IC706_AM_TX_MODES, W(2), W(40), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, IC706_OTHER_TX_MODES, W(5), W(50), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_2m(1, IC706_AM_TX_MODES, W(2), W(20), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ FRQ_RNG_70cm(1, IC706_OTHER_TX_MODES, W(5), W(20), IC706_VFO_ALL, RIG_ANT_1), FRQ_RNG_70cm(1, IC706_AM_TX_MODES, W(2), W(8), IC706_VFO_ALL, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(200) - 1, IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, /* this trx also has UHF */ {MHz(400), MHz(470), IC706_ALL_RX_MODES, -1, -1, IC706_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, /* 100W class */ {kHz(1800), MHz(2) - 1, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, /* 40W class */ {kHz(3500), MHz(4) - 1, IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(3500), MHz(4) - 1, IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(7), kHz(7300), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(10100), kHz(10150), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(14), kHz(14350), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(18068), kHz(18168), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(21), kHz(21450), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {kHz(24890), kHz(24990), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(28), kHz(29700), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_OTHER_TX_MODES, 5000, 100000, IC706_VFO_ALL}, {MHz(50), MHz(54), IC706_AM_TX_MODES, 2000, 40000, IC706_VFO_ALL}, {MHz(144), MHz(148), IC706_OTHER_TX_MODES, 5000, 50000, IC706_VFO_ALL}, /* 50W */ {MHz(144), MHz(148), IC706_AM_TX_MODES, 2000, 20000, IC706_VFO_ALL}, /* AM VHF is 20W */ {MHz(430), MHz(450), IC706_OTHER_TX_MODES, 5000, 20000, IC706_VFO_ALL}, {MHz(430), MHz(450), IC706_AM_TX_MODES, 2000, 8000, IC706_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC706_1HZ_TS_MODES, 1}, {IC706_ALL_RX_MODES, 10}, {IC706_ALL_RX_MODES, 100}, {IC706_ALL_RX_MODES, kHz(1)}, {IC706_ALL_RX_MODES, kHz(5)}, {IC706_ALL_RX_MODES, kHz(9)}, {IC706_ALL_RX_MODES, kHz(10)}, {IC706_ALL_RX_MODES, 12500}, {IC706_ALL_RX_MODES, kHz(20)}, {IC706_ALL_RX_MODES, kHz(25)}, {IC706_ALL_RX_MODES, kHz(100)}, {IC706_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ {RIG_MODE_WFM, kHz(230)}, /* WideFM, filter FL?? */ RIG_FLT_END, }, .str_cal = IC706IIG_STR_CAL, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic706mkiig_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/id51.c0000644000175000017500000001524214752216205012511 00000000000000/* * Hamlib CI-V backend - description of ID-51 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "token.h" #include "icom.h" #include "idx_builtin.h" #include "icom_defs.h" #include "tones.h" /* * Specs and protocol details comes from the chapter 17 of ID-51A_E_PLUS2_CD_0.pdf * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP" for rig control. * */ #define ID51_MODES (RIG_MODE_FM|RIG_MODE_DSTAR) #define ID51_ALL_RX_MODES (RIG_MODE_AM|ID51_MODES) #define ID51_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define ID51_SCAN_OPS RIG_SCAN_NONE #define ID51_VFO_OPS RIG_OP_NONE #define ID51_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_VOX) #define ID51_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID51_PARM_ALL RIG_PARM_NONE int id51_tokens[] = { TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_GPS_DATA, TOK_DSTAR_GPS_MESS, TOK_DSTAR_CODE, TOK_DSTAR_TX_DATA, TOK_DSTAR_MY_CS, TOK_DSTAR_TX_CS, TOK_DSTAR_TX_MESS, TOK_BACKEND_NONE }; /* * FIXME: real measurement */ #define ID51_STR_CAL UNKNOWN_IC_STR_CAL /* */ static struct icom_priv_caps id51_priv_caps = { 0x86, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps id51_caps = { RIG_MODEL(RIG_MODEL_ID51), .model_name = "ID-51", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID51_FUNC_ALL, .has_set_func = ID51_FUNC_ALL, .has_get_level = ID51_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID51_LEVEL_ALL), .has_get_parm = ID51_PARM_ALL, .has_set_parm = ID51_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .ext_tokens = id51_tokens, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID51_VFO_OPS, .scan_ops = ID51_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, {MHz(375), MHz(550), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), ID51_MODES, W(5), W(25), ID51_VFO_ALL}, {MHz(430), MHz(440), ID51_MODES, W(5), W(25), ID51_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, {MHz(375), MHz(550), ID51_ALL_RX_MODES, -1, -1, ID51_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), ID51_MODES, W(5), W(50), ID51_VFO_ALL}, {MHz(430), MHz(450), ID51_MODES, W(5), W(50), ID51_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID51_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id51_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, // not capable .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic775.c0000644000175000017500000001501414752216205012602 00000000000000/* * Hamlib CI-V backend - description of IC-775 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "bandplan.h" #define IC775_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC775_1MHZ_TS_MODES (RIG_MODE_AM|RIG_MODE_FM) #define IC775_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) /* * 100W in all modes but AM (40W) */ #define IC775_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC775_AM_TX_MODES (RIG_MODE_AM) #define IC775_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC775_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC775_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic775_priv_caps = { 0x46, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic775_caps = { RIG_MODEL(RIG_MODEL_IC775), .model_name = "IC-775", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC775_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 10, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 11, 12, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), IC775_ALL_RX_MODES, -1, -1, IC775_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC775_OTHER_TX_MODES, W(10), W(100), IC775_VFO_ALL, IC775_ANTS), FRQ_RNG_HF(1, IC775_AM_TX_MODES, W(10), W(40), IC775_VFO_ALL, IC775_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), IC775_ALL_RX_MODES, -1, -1, IC775_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, /* 100W class */ {kHz(1800), MHz(2) - 1, IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, /* 40W class */ {kHz(3500), MHz(4) - 1, IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(3500), MHz(4) - 1, IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(7), kHz(7300), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(7), kHz(7300), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {kHz(10100), kHz(10150), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(10100), kHz(10150), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(14), kHz(14350), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(14), kHz(14350), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {kHz(18068), kHz(18168), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(18068), kHz(18168), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(21), kHz(21450), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(21), kHz(21450), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {kHz(24890), kHz(24990), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {kHz(24890), kHz(24990), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, {MHz(28), kHz(29700), IC775_OTHER_TX_MODES, 5000, 100000, IC775_VFO_ALL}, {MHz(28), kHz(29700), IC775_AM_TX_MODES, 2000, 40000, IC775_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC775_1HZ_TS_MODES, 1}, {IC775_ALL_RX_MODES, 10}, {IC775_ALL_RX_MODES, 100}, {IC775_ALL_RX_MODES, kHz(1)}, {IC775_ALL_RX_MODES, kHz(5)}, {IC775_ALL_RX_MODES, kHz(9)}, {IC775_ALL_RX_MODES, kHz(10)}, {IC775_ALL_RX_MODES, 12500}, {IC775_ALL_RX_MODES, kHz(20)}, {IC775_ALL_RX_MODES, kHz(25)}, {IC775_ALL_RX_MODES, kHz(100)}, {IC775_1MHZ_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, /* builtin FL-272 */ {RIG_MODE_AM, kHz(8)}, /* mid w/ builtin FL-94 */ {RIG_MODE_AM, kHz(2.4)}, /* narrow w/ builtin FL-272 */ {RIG_MODE_FM, kHz(15)}, /* ?? TBC, mid w/ builtin FL-23+SFPC455E */ {RIG_MODE_FM, kHz(8)}, /* narrow w/ builtin FL-94 */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic775_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic820h.c0000644000175000017500000001317714752216205012751 00000000000000/* * Hamlib CI-V backend - description of IC-820H (VHF/UHF All-Mode Transceiver) * Contributed by Francois Retief * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #define IC820H_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC820H_VFO_ALL (RIG_VFO_A|RIG_VFO_C|RIG_VFO_MEM) /* FIXME: What about MAIN/SUB mode? And satellite mode? */ #define IC820H_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC820H_SCAN_OPS (RIG_SCAN_MEM) /* FIXME: Manual talks about 3 modes: Programmed scan, Memory scan and * Mode select memory scan operation. How do i encode these? */ #define IC820H_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic820h_priv_caps = { 0x42, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic820h_caps = { RIG_MODEL(RIG_MODEL_IC820), .model_name = "IC-820H", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, /* Attanuator 15dB for each band. manual button */ .max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */ .max_xit = Hz(0), .max_ifshift = Hz(0), /* 1.2kHz manual knob */ .targetable_vfo = 0, .vfo_ops = IC820H_VFO_OPS, .scan_ops = IC820H_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* FIXME: Each band has 80 channels (2*80) ?? */ { 1, 80, RIG_MTYPE_MEM }, { 81, 82, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(136), MHz(174), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, {MHz(430), MHz(450), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), RIG_MODE_SSB, W(6), W(35), IC820H_VFO_ALL}, {MHz(144), MHz(146), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC820H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_SSB, W(6), W(30), IC820H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC820H_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(136), MHz(174), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, {MHz(430), MHz(450), IC820H_MODES, -1, -1, IC820H_VFO_ALL}, RIG_FRNG_END, }, /* * From manual: VHF UHF * USA 144.0-148.0 MHz 430.0-450.0 MHz * Europe 144.0-146.0 MHz 430.0-440.0 MHz * Australia 144.0-148.0 MHz 430.0-450.0 MHz * Sweden 144.0-146.0 MHz 432.0-438.0 MHz */ .tx_range_list2 = { {MHz(144), MHz(148), RIG_MODE_SSB, W(6), W(35), IC820H_VFO_ALL}, {MHz(144), MHz(148), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC820H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_SSB, W(6), W(30), IC820H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC820H_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(5)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* builtin */ {RIG_MODE_FM, kHz(15)}, /* builtin */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic820h_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic738.c0000644000175000017500000001307014752216205012601 00000000000000/* * Hamlib CI-V backend - description of IC-738 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "icom.h" /* * IC-738, like the IC-736 but without 6m */ #define IC738_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC738_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC738_AM_TX_MODES (RIG_MODE_AM) #define IC738_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC738_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC738_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_VFO) #define IC738_ANTS 0 /* TODO: declare both antenna connectors? */ #define IC738_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic738_priv_caps = { 0x44, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic738_caps = { RIG_MODEL(RIG_MODEL_IC738), .model_name = "IC-738", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC738_VFO_OPS, .scan_ops = IC738_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 89, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 90, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, /* FIXME: split */ { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, {MHz(50), MHz(54), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC738_OTHER_TX_MODES, W(5), W(100), IC738_VFO_ALL, IC738_ANTS), FRQ_RNG_HF(1, IC738_AM_TX_MODES, W(4), W(40), IC738_VFO_ALL, IC738_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, {MHz(50), MHz(54), IC738_ALL_RX_MODES, -1, -1, IC738_VFO_ALL, IC738_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC738_OTHER_TX_MODES, W(5), W(100), IC738_VFO_ALL, IC738_ANTS), FRQ_RNG_HF(2, IC738_AM_TX_MODES, W(4), W(40), IC738_VFO_ALL, IC738_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { /* TBC */ {IC738_ALL_RX_MODES, 10}, {IC738_ALL_RX_MODES, kHz(1)}, {IC738_ALL_RX_MODES, kHz(2)}, {IC738_ALL_RX_MODES, kHz(3)}, {IC738_ALL_RX_MODES, kHz(4)}, {IC738_ALL_RX_MODES, kHz(5)}, {IC738_ALL_RX_MODES, kHz(6)}, {IC738_ALL_RX_MODES, kHz(7)}, {IC738_ALL_RX_MODES, kHz(8)}, {IC738_ALL_RX_MODES, kHz(9)}, {IC738_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic738_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic756.c0000644000175000017500000011105614752216205012604 00000000000000/* * Hamlib CI-V backend - description of IC-756 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" #include "bandplan.h" #include "tones.h" #define IC756_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756_1HZ_TS_MODES IC756_ALL_RX_MODES #define IC756_FUNC_SET (RIG_FUNC_DUAL_WATCH) /* * 100W in all modes but AM (40W) */ #define IC756_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756_AM_TX_MODES (RIG_MODE_AM) #define IC756PRO_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_RF|RIG_FUNC_ANF) #define IC756PRO_FUNC_SET (IC756PRO_FUNC_ALL|RIG_FUNC_DUAL_WATCH) #define IC756PRO_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_COMP) /* Note that RIG_LEVEL_VOXGAIN and RIG_LEVEL_ANTIVOX are incorrectly handled in icom.c for * this model. */ #define IC756_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC756_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC756_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC756_ANTS (RIG_ANT_1|RIG_ANT_2) struct cmdparams ic756pro_cmdparms[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x20}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x09}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x16}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x60}, CMD_DAT_INT, 1 }, { {0} } }; #define IC756PRO_STR_CAL { 16, \ { \ { 0, -60 }, \ { 14, -52 }, \ { 29, -44 }, \ { 44, -36 }, \ { 60, -28 }, \ { 75, -20 }, \ { 91, -12 }, \ { 107, -4 }, \ { 124, 4 }, \ { 141, 12 }, \ { 158, 20 }, \ { 175, 28 }, \ { 192, 36 }, \ { 210, 44 }, \ { 228, 52 }, \ { 247 ,60 } \ } } /* * This function deals with the older type radios with only 2 filter widths * (0 - normal, 1 - narrow) */ static int r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err != RIG_OK) { return err; } if (PD_WIDE_3 == *pd) { *pd = PD_MEDIUM_2; } else if (*pd > PD_WIDE_3) { (*pd)--; } return RIG_OK; } /* * IC-756 rig capabilities. */ static const struct icom_priv_caps ic756_priv_caps = { 0x50, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756_ts_sc_list, .antack_len = 3, .ant_count = 2, .r2i_mode = r2i_mode, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, }; struct rig_caps ic756_caps = { RIG_MODEL(RIG_MODEL_IC756), .model_name = "IC-756", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = IC756_FUNC_SET, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756_1HZ_TS_MODES, 1}, {IC756_ALL_RX_MODES, kHz(1)}, {IC756_ALL_RX_MODES, kHz(5)}, {IC756_ALL_RX_MODES, kHz(9)}, {IC756_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CWR, kHz(2.4)}, {RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC-756pro rig capabilities. * * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro_priv_caps = { 0x5c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -2 }, }, }; struct rig_caps ic756pro_caps = { RIG_MODEL(RIG_MODEL_IC756PRO), .model_name = "IC-756PRO", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL, .has_set_func = IC756PRO_FUNC_SET, .has_get_level = IC756PRO_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756_1HZ_TS_MODES, 1}, {IC756_ALL_RX_MODES, kHz(1)}, {IC756_ALL_RX_MODES, kHz(5)}, {IC756_ALL_RX_MODES, kHz(9)}, {IC756_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756pro_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC-756proII rig capabilities. * * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro2_priv_caps = { 0x64, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic756pro_cmdparms, /* Custom op parameters */ .data_mode_supported = 1 }; /* * These TOKEN_BACKEND's are on a different name space than conf's */ #define TOK_MEMNAME TOKEN_BACKEND(1) #define TOK_MYCALL TOKEN_BACKEND(2) static const struct confparams ic756pro2_ext_parms[] = { { TOK_SSBBASS, "ssbbass", "SSB Tx Tone (Bass)", "SSB Tx Tone (Bass)", NULL, RIG_CONF_NUMERIC, { .n = { 0, 10, 1 } } }, { TOK_MEMNAME, "showmem", "Show mem name", "Show memory name", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_SQLCTRL, "sqlctrl", "RF/Sql control", "set RF/Squelch control", NULL, RIG_CONF_COMBO, { .c = {{ "Auto", "Sql", "RF+Sql", NULL }} } }, { TOK_MYCALL, "mycall", "Callsign", "My call sign", NULL, RIG_CONF_STRING, { } }, { TOK_RTTY_FLTR, "rttyfltr", "RTTY Fltr Width preset", "Set/Read RTTY preset filter width", "350", RIG_CONF_COMBO, { .c = {{"250", "300", "350", "500", "1000", NULL }} } }, { RIG_CONF_END, NULL, } }; /* * NUMERIC: val.f * COMBO: val.i, starting from 0 * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ /*IC-756Pro Rig parameters Only available in this namespace*/ #define S_MEM_SC_LEN 2 /* 756PRO S_MEM subcmd length */ #define S_MEM_SBASS 0x501 /* SSB TX tone bass level */ #define S_MEM_NAME 0x514 /* send/read memory name */ #define S_MEM_MYCALL 0x515 #define S_MEM_BEEP 0x520 /* Button confirmation */ #define S_MEM_SQL_CTL 0x522 /* RF/SQL ctl set 0=auto; 1 = sql; 2 = RF+SQL */ #define S_MEM_QSPLT 0x524 /* enable quick split mode */ #define S_MEM_TRCV 0x532 /* CI-V trancieve mode */ #define S_MEM_LANG 0x536 /* 0=English 1=Japanese for voice announcer */ #define S_MEM_SCN_SPD 0x556 /* 0 = low; 1 = high */ #define S_MEM_RTTY_FL_PB 0x561 /* 0=250 Hz, 1=300' 2 = 350, 3 = 500, 4 = 1 KHz */ #define S_MEM_RTTY_TWNPK 0x562 /* rtty twin peak filter off/on */ static int ic756pro2_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); static int ic756pro2_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); #define IC756PROII_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROII_1HZ_TS_MODES IC756PROII_ALL_RX_MODES #define IC756PROII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROII_AM_TX_MODES (RIG_MODE_AM) #define IC756PROII_LEVEL_ALL (IC756PRO_LEVEL_ALL|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AGC_TIME) #define IC756PROII_PARMS (RIG_PARM_ANN|RIG_PARM_BEEP|RIG_PARM_BACKLIGHT|RIG_PARM_TIME) struct rig_caps ic756pro2_caps = { RIG_MODEL(RIG_MODEL_IC756PROII), .model_name = "IC-756PROII", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL, .has_set_func = IC756PRO_FUNC_SET, .has_get_level = IC756PROII_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC756PROII_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = {}, .extparms = ic756pro2_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756PROII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756PROII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756PROII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756PROII_AM_TX_MODES, W(2), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756PROII_1HZ_TS_MODES, 1}, {IC756PROII_ALL_RX_MODES, kHz(1)}, {IC756PROII_ALL_RX_MODES, kHz(5)}, {IC756PROII_ALL_RX_MODES, kHz(9)}, {IC756PROII_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756pro2_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .set_ext_parm = ic756pro2_set_ext_parm, .get_ext_parm = ic756pro2_get_ext_parm, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ic756pro2_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { unsigned char epbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int ack_len, ep_len, val_len; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ int icom_val = 0; int retval; ep_len = 0; /* 0 implies BCD data */ val_len = 1; switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; icom_val = val.f; break; case TOK_MEMNAME: ep_sc = S_MEM_NAME; icom_val = val.i ? 1 : 0; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; /* TODO: check range this actually doesn't decode the input type 'string' */ icom_val = val.i; break; case TOK_MYCALL: /* max 10 ASCII char */ ep_len = strlen(val.cs); if (ep_len > 10) { return -RIG_EINVAL; } ep_sc = S_MEM_MYCALL; memcpy(epbuf, val.cs, ep_len); break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 = 250, 300, 350, 500, 1000 */ if (val.i < 0 || val.i > 4) { return -RIG_EINVAL; } ep_sc = S_MEM_RTTY_FL_PB; icom_val = val.i; break; default: return -RIG_EINVAL; } if (ep_len == 0) { to_bcd_be(epbuf, (long long)icom_val, val_len * 2); ep_len += val_len; } retval = icom_transaction(rig, ep_cmd, ep_sc, epbuf, ep_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ static int ic756pro2_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { const struct confparams *cfp; unsigned char resbuf[MAXFRAMELEN]; int res_len, icom_val = 0; int cmdhead; int retval; int ep_cmd = C_CTL_MEM; int ep_sc; /* Subcommand in $1A $05xx */ switch (token) { case TOK_SSBBASS: ep_sc = S_MEM_SBASS ; break; case TOK_MEMNAME: ep_sc = S_MEM_NAME; break; case TOK_SQLCTRL: ep_sc = S_MEM_SQL_CTL; break; case TOK_MYCALL: /* max 10 ASCII char */ ep_sc = S_MEM_MYCALL; break; case TOK_RTTY_FLTR: /* RTTY filter mode 0 - 4 */ ep_sc = S_MEM_RTTY_FL_PB; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_ext_parm %s", rig_strparm(token)); return -RIG_EINVAL; } retval = icom_transaction(rig, ep_cmd, ep_sc, NULL, 0, resbuf, &res_len); if (retval != RIG_OK) { return retval; } /* * strbuf should contain Cn,Sc,Data area */ cmdhead = (ep_sc == -1) ? 1 : S_MEM_SC_LEN + 1; res_len -= cmdhead; /* should echo cmd, subcmd and then data, if you get an ack something is wrong */ if (resbuf[0] != ep_cmd) { if (resbuf[0] == ACK) { rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } } cfp = rig_ext_lookup_tok(rig, token); switch (cfp->type) { case RIG_CONF_STRING: memcpy(val->s, resbuf, res_len); break; case RIG_CONF_CHECKBUTTON: case RIG_CONF_COMBO: val->i = from_bcd_be(resbuf + cmdhead, res_len * 2); break; case RIG_CONF_NUMERIC: val->f = from_bcd_be(resbuf + cmdhead, res_len * 2); break; default: rig_debug(RIG_DEBUG_ERR, "%s: protocol error (%#.2x), " "len=%d\n", __func__, resbuf[0], res_len); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } /* * IC-756proIII rig capabilities. * * TODO: check every parameter, add antenna capabilities */ static const struct icom_priv_caps ic756pro3_priv_caps = { 0x6e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic756pro_cmdparms, /* Custom op parameters */ .data_mode_supported = 1 }; #define IC756PROIII_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROIII_1HZ_TS_MODES IC756PROIII_ALL_RX_MODES #define IC756PROIII_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC756PROIII_AM_TX_MODES (RIG_MODE_AM) #define IC756PROIII_LEVEL_ALL (IC756PROII_LEVEL_ALL|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_NB) /* * TODO: check whether all func and levels are stored in memory * * No memory split support. * .rptr_offs = 1, to be done for FM special mode * * Channel description should be possible through: 0x1a 0x00 * c.f. http://www.plicht.de/ekki/civ/civ-p4305-756pro.html */ #define IC756PROIII_MEM_CAP { \ .ant = 1, \ .tuning_step = 1, \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .funcs = IC756PRO_FUNC_ALL, \ .levels = RIG_LEVEL_SET(IC756PRO_LEVEL_ALL), \ } #define IC756PROIII_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC756PROIII_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC756PROIII_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC756PROIII_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } struct rig_caps ic756pro3_caps = { RIG_MODEL(RIG_MODEL_IC756PROIII), .model_name = "IC-756PROIII", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC756PRO_FUNC_ALL | RIG_FUNC_TUNER, .has_set_func = IC756PRO_FUNC_SET | RIG_FUNC_TUNER, .has_get_level = IC756PROIII_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC756PROIII_LEVEL_ALL), .has_get_parm = IC756PROII_PARMS, .has_set_parm = RIG_PARM_SET(IC756PROII_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .extparms = ic756pro2_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC values */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC756_VFO_OPS | RIG_OP_TUNE, .scan_ops = IC756_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 10, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC756PROIII_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC756PROIII_MEM_CAP }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC756PROIII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL, IC756_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(1, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(1, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(1, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC756PROIII_ALL_RX_MODES, -1, -1, IC756_VFO_ALL, IC756_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_6m(2, IC756PROIII_OTHER_TX_MODES, W(5), W(100), IC756_VFO_ALL, IC756_ANTS), FRQ_RNG_HF(2, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ FRQ_RNG_6m(2, IC756PROIII_AM_TX_MODES, W(5), W(40), IC756_VFO_ALL, IC756_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC756PROIII_1HZ_TS_MODES, 1}, {IC756PROIII_1HZ_TS_MODES, 100}, {IC756PROIII_ALL_RX_MODES, kHz(1)}, {IC756PROIII_ALL_RX_MODES, kHz(5)}, {IC756PROIII_ALL_RX_MODES, kHz(9)}, {IC756PROIII_ALL_RX_MODES, kHz(10)}, {IC756PROIII_ALL_RX_MODES, kHz(12.5)}, {IC756PROIII_ALL_RX_MODES, kHz(20)}, {IC756PROIII_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(3.6)}, /* wide */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(50)}, /* narrow */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, /* almost any filter */ RIG_FLT_END, }, .str_cal = IC756PRO_STR_CAL, .swr_cal = IC756PROIII_SWR_CAL, .alc_cal = IC756PROIII_ALC_CAL, .rfpower_meter_cal = IC756PROIII_RFPOWER_METER_CAL, .comp_meter_cal = IC756PROIII_COMP_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic756pro3_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_freq_mode = icom_set_split_freq_mode, .get_split_freq_mode = icom_get_split_freq_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .set_ext_parm = ic756pro2_set_ext_parm, .get_ext_parm = ic756pro2_get_ext_parm, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/xiegu.c0000644000175000017500000013707214752216205013076 00000000000000/* * Hamlib CI-V backend - description of Xiegu X108G and variations * Adapted from IC-7000 code 2017 by Michael Black W9MDB * As of this date there is no CAT manual for this rig * The X108G is supposed to emulate the IC-7000 but there are a few * differences as of 2017-02-11 in the return data from the rig * It's quite possible they may fix all these eventually * If they do the functions below can go back to the icom routines * #1 the response to PTT * #2 the inability to set_dsp_mode * #3 setting split which impacts 3 routines * * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" #include "tones.h" #include "bandplan.h" #define X108G_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM|RIG_MODE_FMN|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define X108G_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define X108G_NOT_TS_MODES (X108G_ALL_RX_MODES &~X108G_1HZ_TS_MODES) #define X108G_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define X108G_AM_TX_MODES (RIG_MODE_AM) #define X108G_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) #define X108G_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define X108G_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define X108G_PARMS (RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) #define X108G_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define X108G_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define X108G_ANTS (RIG_ANT_1|RIG_ANT_2) /* ant-1 is Hf-6m, ant-2 is 2m-70cm */ /* * Measurement by Mark, WA0TOP * * s/n 0503103. * Preamp off, ATT off, mode AM, f=10 MHz */ #define X108G_STR_CAL { 14, \ { \ { 0, -54 }, /* first one is made up */ \ { 5, -29 }, \ { 15, -27 }, \ { 43, -22 }, \ { 68, -17 }, \ { 92, -12 }, \ { 120, -6 }, \ { 141, 2 }, \ { 162, 13 }, \ { 182, 25 }, \ { 202, 38 }, \ { 222, 47 }, \ { 241, 57 }, \ { 255, 63 } \ } } /* * * X108G channel caps. */ #define X108G_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .funcs = X108G_FUNCS, \ .levels = RIG_LEVEL_SET(X108G_LEVELS), \ } /* * Prototypes */ static int x108g_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int x108g_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int x108g_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int x108g_rig_open(RIG *rig) { int retval; ENTERFUNC; retval = icom_rig_open(rig); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_open failed with %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int xiegu_rig_open(RIG *rig) { int retval; unsigned char id[4]; int id_len = 2; int cmd = 0x19; int subcmd = 0x00; unsigned short iid; retval = icom_rig_open(rig); if (retval != RIG_OK) { return retval; } retval = icom_transaction(rig, cmd, subcmd, NULL, 0, id, &id_len); if (retval == RIG_OK) { dump_hex(id, id_len); iid = (int)id[1]; if (id_len > 2) { iid = (iid << 8) + id[2]; } rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu Radio ID=0x%04x\n", __func__, iid); switch (iid) { case 0x0070: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "G90"); break; case 0x0090: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "G90S"); break; case 0x0106: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "G106/G106C"); break; case 0x6100: case 0x00a4: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "X6100/X6200"); break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Xiegu model %s\n", __func__, "Unknown"); break; } } return retval; } /* * taken from IC-7000 rig capabilities. * * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static struct icom_priv_caps x108g_priv_caps = { 0x70, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, }; struct rig_caps x108g_caps = { RIG_MODEL(RIG_MODEL_X108G), .model_name = "X108G", .mfg_name = "Xiegu", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .targetable_vfo = 0, .vfo_ops = X108G_VFO_OPS, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x108g_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = x108g_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = x108g_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = x108g_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = x108g_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static struct icom_priv_caps x6100_priv_caps = { 0xa4, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 0, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps x6100_caps = { RIG_MODEL(RIG_MODEL_X6100), .model_name = "X6100", .mfg_name = "Xiegu", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 3, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .vfo_ops = X108G_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x6100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, // testing with X6100 showed it rejected the 0x0f 0x01 command .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps x6200_caps = { RIG_MODEL(RIG_MODEL_X6200), .model_name = "X6200", .mfg_name = "Xiegu", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 3, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .vfo_ops = X108G_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x6100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, // testing with X6100 showed it rejected the 0x0f 0x01 command .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static struct icom_priv_caps g90_priv_caps = { 0xa4, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, .x25x26_always = 0, .x25x26_possibly = 1, // Firmware G90 v20240504.8 doesn't work well -- see https://github.com/Hamlib/Hamlib/issues/1547 .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 0, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps g90_caps = { RIG_MODEL(RIG_MODEL_G90), .model_name = "G90", .mfg_name = "Xiegu", .version = BACKEND_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 19200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .vfo_ops = X108G_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& g90_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, //.set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps x5105_caps = { RIG_MODEL(RIG_MODEL_X5105), .model_name = "X5105", .mfg_name = "Xiegu", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = X108G_FUNCS, .has_set_func = X108G_FUNCS, .has_get_level = X108G_LEVELS, .has_set_level = RIG_LEVEL_SET(X108G_LEVELS), .has_get_parm = X108G_PARMS, .has_set_parm = RIG_PARM_SET(X108G_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess*/ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .targetable_vfo = 0, .vfo_ops = X108G_VFO_OPS, .scan_ops = X108G_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, X108G_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, X108G_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, X108G_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, {MHz(400), MHz(470), X108G_ALL_RX_MODES, -1, -1, X108G_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, X108G_OTHER_TX_MODES, W(2), W(100), X108G_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, X108G_OTHER_TX_MODES, W(2), W(50), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(35), X108G_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, X108G_AM_TX_MODES, W(1), W(40), X108G_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, X108G_AM_TX_MODES, W(2), W(20), X108G_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, X108G_OTHER_TX_MODES, W(2), W(14), X108G_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {X108G_1HZ_TS_MODES, 1}, {X108G_NOT_TS_MODES, 10}, {X108G_ALL_RX_MODES, Hz(100)}, {X108G_ALL_RX_MODES, kHz(1)}, {X108G_ALL_RX_MODES, kHz(5)}, {X108G_ALL_RX_MODES, kHz(9)}, {X108G_ALL_RX_MODES, kHz(10)}, {X108G_ALL_RX_MODES, kHz(12.5)}, {X108G_ALL_RX_MODES, kHz(20)}, {X108G_ALL_RX_MODES, kHz(25)}, {X108G_ALL_RX_MODES, kHz(100)}, {X108G_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = X108G_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& x108g_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = xiegu_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = x108g_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = NULL, .get_split_freq = NULL, .set_split_mode = NULL, .get_split_mode = NULL, .set_split_vfo = NULL, .get_split_vfo = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * x108g_set_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL * The response from the x108g isn't quite right at this time * Eventually they may fix their firmware and we can use the icom_set_split_vfo */ int x108g_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char ackbuf[MAXFRAMELEN], pttbuf[1]; int ack_len = sizeof(ackbuf), retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); pttbuf[0] = ptt == RIG_PTT_ON ? 1 : 0; retval = icom_transaction(rig, C_CTL_PTT, S_PTT, pttbuf, 1, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } /* X108G doesn't quite follow ICOM protocol -- returns 0x1c instead of 0xfb */ if (ackbuf[0] != 0xfb && (ack_len != 3 || ackbuf[0] != 0x1c)) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d, ptt=%d\n", __func__, ackbuf[0], ack_len, ptt); return -RIG_ERJCTED; } return RIG_OK; } /* * The response from the x108g isn't quite right at this time * Eventually they may fix their firmware and we can use the icom_set_split_vfo * x108g_set_split * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int x108g_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), rc; int split_sc; struct rig_cache *cachep = CACHE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (split) { case RIG_SPLIT_OFF: split_sc = S_SPLT_OFF; break; case RIG_SPLIT_ON: split_sc = S_SPLT_ON; if (cachep->split == RIG_SPLIT_OFF) { /* ensure VFO A is Rx and VFO B is Tx as we assume that elsewhere */ if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B)) { if (RIG_OK != (rc = icom_set_vfo(rig, RIG_VFO_A))) { return rc; } } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported split %d", __func__, split); return -RIG_EINVAL; } if (RIG_OK != (rc = icom_transaction(rig, C_CTL_SPLT, split_sc, NULL, 0, ackbuf, &ack_len))) { return rc; } if (ack_len != 2 || ackbuf[0] != 0x0f) // instead of len=1 & ACK { rig_debug(RIG_DEBUG_ERR, "x108g_set_split: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } cachep->split = split; return RIG_OK; } /* * x108g_set_split_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, * * Assumes also that the current VFO is the rx VFO. */ static int x108g_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int rc; vfo_t rx_vfo, tx_vfo; struct icom_priv_data *priv; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct icom_priv_data *)rs->priv; /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } if (RIG_OK != (rc = icom_set_freq(rig, RIG_VFO_CURR, tx_freq))) { return rc; } if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } return rc; } /* In the case of rigs with an A/B VFO arrangement we assume the current VFO is VFO A and the split Tx VFO is always VFO B. These assumptions allow us to deal with the lack of VFO and split queries */ /* broken if user changes split on rig :( */ if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } if (ack_len != 2 || ackbuf[0] != 0x0f) { rig_debug(RIG_DEBUG_ERR, "x108g_set_split_freq: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } if (RIG_OK != (rc = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) { return rc; } if (RIG_OK != (rc = rig_set_freq(rig, RIG_VFO_CURR, tx_freq))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; } if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } } return rc; } /* * x108g_set_split_mode * Assumes rig!=NULL, STATE(rig)->priv!=NULL, */ static int x108g_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int rc; vfo_t rx_vfo, tx_vfo; struct icom_priv_data *priv; struct rig_state *rs = STATE(rig); struct rig_cache *cachep = CACHE(rig); unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct icom_priv_data *)rs->priv; /* This method works also in memory mode(RIG_VFO_MEM) */ if (!priv->no_xchg && rig_has_vfo_op(rig, RIG_OP_XCHG)) { if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { return rc; } if (RIG_OK != (rc = icom_vfo_op(rig, vfo, RIG_OP_XCHG))) { return rc; } return rc; } /* In the case of rigs with an A/B VFO arrangement we assume the current VFO is VFO A and the split Tx VFO is always VFO B. These assumptions allow us to deal with the lack of VFO and split queries */ /* broken if user changes split on rig :( */ if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* VFO A/B style rigs swap VFO on split Tx so we need to disable split for certainty */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_OFF, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } if (ack_len != 2 || ackbuf[0] != 0x0f) { rig_debug(RIG_DEBUG_ERR, "x108g_set_split_mode: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } } if (RIG_OK != (rc = icom_get_split_vfos(rig, &rx_vfo, &tx_vfo))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, tx_vfo))) { return rc; } if (RIG_OK != (rc = rig->caps->set_mode(rig, RIG_VFO_CURR, tx_mode, tx_width))) { return rc; } if (RIG_OK != (rc = icom_set_vfo(rig, rx_vfo))) { return rc; } if ((STATE(rig)->vfo_list & (RIG_VFO_A | RIG_VFO_B)) == (RIG_VFO_A | RIG_VFO_B) && cachep->split != RIG_SPLIT_OFF) { /* Re-enable split */ rc = icom_transaction(rig, C_CTL_SPLT, S_SPLT_ON, NULL, 0, ackbuf, &ack_len); if (rc != RIG_OK) { return rc; } } return rc; } hamlib-4.6.2/rigs/icom/ic7410.c0000644000175000017500000002502114752216205012652 00000000000000/* * Hamlib CI-V backend - description of IC-7410 * Copyright (c) 2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "tones.h" #define IC7410_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7410_AM_TX_MODES (RIG_MODE_AM) #define IC7410_ALL_RX_MODES IC7410_OTHER_TX_MODES | IC7410_AM_TX_MODES #define IC7410_1HZ_TS_MODES IC7410_ALL_RX_MODES #define IC7410_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_TUNER) #define IC7410_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_AGC_TIME) #define IC7410_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7410_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7410_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7410_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7410_ANTS (RIG_ANT_1|RIG_ANT_2) /* * Guess from IC7600 */ #define IC7410_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 124, 0 }, /* S9 */ \ { 246, 60 } /* S9+60dB */ \ } } #define IC7410_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7410_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7410_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } struct cmdparams ic7410_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 1, {0x75 }, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x75}, CMD_DAT_INT, 1 }, { {0} } }; /* * IC-7410 rig capabilities. */ static const struct icom_priv_caps ic7410_priv_caps = { 0x80, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_SLOW, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_FAST, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .data_mode_supported = 1, }; struct rig_caps ic7410_caps = { RIG_MODEL(RIG_MODEL_IC7410), .model_name = "IC-7410", .mfg_name = "Icom", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7410_FUNCS, .has_set_func = IC7410_FUNCS, .has_get_level = IC7410_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7410_LEVELS), .has_get_parm = IC7410_PARMS, .has_set_parm = RIG_PARM_SET(IC7410_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC7410_VFO_OPS, .scan_ops = IC7410_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7410_ALL_RX_MODES, -1, -1, IC7410_VFOS, IC7410_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_6m(1, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_HF(1, IC7410_AM_TX_MODES, W(1), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7410_AM_TX_MODES, W(1), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7410_ALL_RX_MODES, -1, -1, IC7410_VFOS, IC7410_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_6m(2, IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS), FRQ_RNG_HF(2, IC7410_AM_TX_MODES, W(2), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7410_AM_TX_MODES, W(2), W(27), IC7410_VFOS, IC7410_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7410_OTHER_TX_MODES, W(2), W(100), IC7410_VFOS, IC7410_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7410_1HZ_TS_MODES, 1}, {IC7410_ALL_RX_MODES, Hz(100)}, {IC7410_ALL_RX_MODES, kHz(1)}, {IC7410_ALL_RX_MODES, kHz(5)}, {IC7410_ALL_RX_MODES, kHz(9)}, {IC7410_ALL_RX_MODES, kHz(10)}, {IC7410_ALL_RX_MODES, kHz(12.5)}, {IC7410_ALL_RX_MODES, kHz(20)}, {IC7410_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(350)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(8)}, /* TBC */ RIG_FLT_END, }, .str_cal = IC7410_STR_CAL, .swr_cal = IC7410_SWR_CAL, .alc_cal = IC7410_ALC_CAL, .rfpower_meter_cal = IC7410_RFPOWER_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7410_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_mem_get_split_vfo, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic781.c0000644000175000017500000001507714752216205012610 00000000000000/* * Hamlib CI-V backend - description of IC-781 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC781_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) /* * IC-781 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic781/specs.htm * * TODO: selected memory scan, delta-f scan, dual watch */ #define IC781_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define IC781_AM_TX_MODES (RIG_MODE_AM) #define IC781_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC781_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL|RIG_OP_XCHG) #define IC781_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC781_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic781_priv_caps = { 0x26, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic781_caps = { RIG_MODEL(RIG_MODEL_IC781), .model_name = "IC-781", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC781_VFO_OPS, .scan_ops = IC781_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC781_ALL_RX_MODES, -1, -1, IC781_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC781_OTHER_TX_MODES, W(10), W(150), IC781_VFO_ALL, IC781_ANTS), FRQ_RNG_HF(1, IC781_AM_TX_MODES, W(10), W(75), IC781_VFO_ALL, IC781_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC781_ALL_RX_MODES, -1, -1, IC781_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {kHz(1800), 1999999, IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, /* 150W class */ {kHz(1800), 1999999, IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, /* 75W class */ {kHz(3400), 4099999, IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {kHz(3400), 4099999, IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(9.9), MHz(1049999), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(9.9), MHz(1049999), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {kHz(17900), kHz(18499.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {kHz(17900), kHz(18499.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {kHz(24400), kHz(25099.99), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {kHz(24400), kHz(25099.99), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, {MHz(27.9), MHz(30), IC781_OTHER_TX_MODES, 5000, 150000, IC781_VFO_ALL}, {MHz(27.9), MHz(30), IC781_AM_TX_MODES, 2000, 75000, IC781_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC781_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, /* narrow */ {RIG_MODE_CW | RIG_MODE_RTTY, Hz(250)}, /* narrow, with [CW250Hz] ON */ {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic781_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, /* TODO: more capabilities */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic7200.c0000644000175000017500000002654014752216205012656 00000000000000/* * Hamlib CI-V backend - description of IC-7200 and variations * Adapted by J.Watson from IC-7000 code (c) 2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * 26Mar09: Corrected tuning steps and added data modes. * 25Mar09: Initial release */ #include #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" /* AM Data mode needs adding - this would require one more mode 'RIG_MODE_PKTAM' to rig.h */ #define IC7200_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define IC7200_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define IC7200_NOT_TS_MODES (IC7200_ALL_RX_MODES &~IC7200_1HZ_TS_MODES) #define IC7200_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7200_AM_TX_MODES (RIG_MODE_AM) #define IC7200_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_ARO|RIG_FUNC_TUNER) #define IC7200_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_NB) #define IC7200_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7200_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) #define IC7200_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7200_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC7200_ANTS (RIG_ANT_1) /* ant-1 is Hf-6m */ #define IC7200_STR_CAL { 3, \ { \ { 0, -54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7200_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7200_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7200_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } int ic7200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ic7200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* * IC-7200 rig capabilities. * * TODO: complete command set (esp. the $1A bunch!) and testing.. */ static const struct icom_priv_caps IC7200_priv_caps = { 0x76, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7200_ts_sc_list, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_SLOW, .icom_level = 2 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .x25x26_always = 0, .x25x26_possibly = 0, .x1cx03_always = 0, .x1cx03_possibly = 0, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic7200_caps = { RIG_MODEL(RIG_MODEL_IC7200), .model_name = "IC-7200", .mfg_name = "Icom", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7200_FUNCS, .has_set_func = IC7200_FUNCS, .has_get_level = IC7200_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7200_LEVELS), .has_get_parm = IC7200_PARMS, .has_set_parm = RIG_PARM_SET(IC7200_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess */ .attenuator = { 20, RIG_DBLST_END, }, /* value taken from p.45 of manual*/ .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC7200_VFO_OPS, .scan_ops = IC7200_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 1, .chan_desc_sz = 0, .chan_list = { { 1, 199, RIG_MTYPE_MEM }, { 200, 201, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7200_ALL_RX_MODES, -1, -1, IC7200_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_HF(1, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7200_ALL_RX_MODES, -1, -1, IC7200_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, IC7200_OTHER_TX_MODES, W(2), W(100), IC7200_VFOS, RIG_ANT_1), FRQ_RNG_HF(2, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, IC7200_AM_TX_MODES, W(1), W(40), IC7200_VFOS, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC7200_1HZ_TS_MODES, 1}, {IC7200_NOT_TS_MODES, 10}, {IC7200_ALL_RX_MODES, Hz(100)}, {IC7200_ALL_RX_MODES, kHz(1)}, {IC7200_ALL_RX_MODES, kHz(5)}, {IC7200_ALL_RX_MODES, kHz(9)}, {IC7200_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC7200_STR_CAL, .swr_cal = IC7200_SWR_CAL, .alc_cal = IC7200_ALC_CAL, .rfpower_meter_cal = IC7200_RFPOWER_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC7200_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = ic7200_set_level, .get_level = ic7200_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = NULL, .get_parm = NULL, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int ic7200_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { unsigned char cmdbuf[MAXFRAMELEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: cmdbuf[0] = 0x55; return icom_set_level_raw(rig, level, C_CTL_MEM, 0x03, 1, cmdbuf, 1, val); default: return icom_set_level(rig, vfo, level, val); } } int ic7200_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmdbuf[MAXFRAMELEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: cmdbuf[0] = 0x55; return icom_get_level_raw(rig, level, C_CTL_MEM, 0x03, 1, cmdbuf, val); default: return icom_get_level(rig, vfo, level, val); } } hamlib-4.6.2/rigs/icom/ic92d.c0000644000175000017500000001645014752216205012663 00000000000000/* * Hamlib CI-V backend - description of IC-E92D/IC-92AD and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "frame.h" #include "icom_defs.h" #include "tones.h" /* TODO: DV (GMSK 4.8 kbps voice) */ #define IC92D_MODES (RIG_MODE_FM) #define IC92D_MODES_TX (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define IC92D_FUNC_ALL (RIG_FUNC_MUTE|RIG_FUNC_MON|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_AFC) #define IC92D_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define IC92D_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define IC92D_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC92D_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC92D_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* * FIXME: real measurement */ #define IC92D_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ #define IC92D_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, \ .funcs = IC92D_FUNC_ALL, \ .levels = RIG_LEVEL_SET(IC92D_LEVEL_ALL), \ } static const char *ic92d_get_info(RIG *rig); /* FIXME: tuning step sub-commands */ const struct ts_sc_list ic92d_ts_sc_list[] = { { kHz(5), 0x00 }, { kHz(6.25), 0x01 }, { kHz(8.33), 0x02 }, { kHz(9), 0x03 }, { kHz(10), 0x04 }, { kHz(12.5), 0x05 }, { kHz(15), 0x06 }, { kHz(20), 0x07 }, { kHz(25), 0x08 }, { kHz(30), 0x09 }, { kHz(50), 0x0a }, { kHz(100), 0x0b }, { kHz(125), 0x0c }, { kHz(200), 0x0d }, { 0, 0 }, }; /* */ static const struct icom_priv_caps ic92d_priv_caps = { 0x01, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic92d_ts_sc_list, .serial_full_duplex = 1 }; struct rig_caps ic92d_caps = { RIG_MODEL(RIG_MODEL_IC92D), .model_name = "IC-92D", /* IC-E92D/IC-92AD */ .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 38400, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC92D_FUNC_ALL, .has_set_func = IC92D_FUNC_ALL, .has_get_level = IC92D_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC92D_LEVEL_ALL), .has_get_parm = IC92D_PARM_ALL, .has_set_parm = IC92D_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC92D_VFO_OPS, .scan_ops = IC92D_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 26, .chan_desc_sz = 8, /* The IC-E92D has a total 1304 memory channels with 26 memory banks. * The VFO A has 800 regular channels, 50 scan edges and 2 call channels, * while the VFO B has 400 regular, 50 scan edges and 2 call channels. */ .chan_list = { { 1, 1200, RIG_MTYPE_MEM, IC92D_MEM_CAP }, { 1201, 1300, RIG_MTYPE_EDGE, IC92D_MEM_CAP }, { 1301, 1304, RIG_MTYPE_CALL, IC92D_MEM_CAP }, RIG_CHAN_END, }, /* IC-E92D */ .rx_range_list1 = { {kHz(495), MHz(999.99), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, RIG_VFO_A}, {MHz(118), MHz(174), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV {MHz(350), MHz(470), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, {MHz(430), MHz(440) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, RIG_FRNG_END, }, /* IC-92AD */ .rx_range_list2 = { {kHz(495), MHz(999.99), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, RIG_VFO_A}, {MHz(118), MHz(174), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV {MHz(350), MHz(470), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_B}, // TODO: MODE_DV RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, {MHz(430), MHz(440) - 1, IC92D_MODES_TX, mW(100), W(5), IC92D_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC92D_MODES, kHz(5)}, {IC92D_MODES, kHz(6.25)}, {IC92D_MODES, kHz(8.33)}, {IC92D_MODES, kHz(9)}, {IC92D_MODES, kHz(10)}, {IC92D_MODES, 12500}, {IC92D_MODES, kHz(15)}, {IC92D_MODES, kHz(20)}, {IC92D_MODES, kHz(25)}, {IC92D_MODES, kHz(50)}, {IC92D_MODES, kHz(100)}, {IC92D_MODES, kHz(125)}, {IC92D_MODES, kHz(200)}, RIG_TS_END, }, /* FIXME: mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(9)}, /* N-FM & AM */ {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .str_cal = IC92D_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic92d_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .get_info = ic92d_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; const char *ic92d_get_info(RIG *rig) { struct icom_priv_data *priv; struct rig_state *rs; unsigned char ackbuf[16]; int ack_len, retval; static char info[64]; rs = STATE(rig); priv = (struct icom_priv_data *)rs->priv; // 018019fd priv->re_civ_addr = 0x01; retval = icom_transaction(rig, C_RD_TRXID, -1, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { return NULL; } if (ack_len <= 3) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), " "len=%d\n", __func__, ackbuf[0], ack_len); return NULL; } SNPRINTF(info, sizeof(info), "ID %02x%02x%02x\n", ackbuf[1], ackbuf[2], ackbuf[3]); return info; } hamlib-4.6.2/rigs/icom/frame.c0000644000175000017500000006276114752216205013051 00000000000000/* * Hamlib CI-V backend - low level communication routines * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "cache.h" /* * Build a CI-V frame. * The whole frame is placed in frame[], * "re_id" is the transceiver's CI-V address, * "cmd" is the Command number, * "subcmd" is the Sub command number, set to -1 if not present in frame, * if the frame has no data, then the "data" pointer must be NULL, * and data_len==0. * "data_len" holds the Data area length pointed by the "data" pointer. * REM: if "data" is NULL, then "data_len" MUST be 0. * * NB: the frame array must be big enough to hold the frame. * The smallest frame is 6 bytes, the biggest is at least 13 bytes. */ int make_cmd_frame(unsigned char frame[], unsigned char re_id, unsigned char ctrl_id, unsigned char cmd, int subcmd, const unsigned char *data, int data_len) { int i = 0; #if 0 frame[i++] = PAD; /* give old rigs a chance to flush their rx buffers */ #endif frame[i++] = PR; /* Preamble code */ frame[i++] = PR; frame[i++] = re_id; frame[i++] = ctrl_id; frame[i++] = cmd; if (subcmd != -1) { #ifdef MULTIB_SUBCMD register int j; if ((j = subcmd & 0xff0000)) /* allows multi-byte subcmd for dsp rigs */ { frame[i++] = j >> 16; frame[i++] = (subcmd & 0xff00) >> 8; } else if ((j = subcmd & 0xff00)) { frame[i++] = j >> 8; } #endif frame[i++] = subcmd & 0xff; } if (data_len != 0) { memcpy(frame + i, data, data_len); i += data_len; } frame[i++] = FI; /* EOM code */ return (i); } int icom_frame_fix_preamble(int frame_len, unsigned char *frame) { if (frame[0] == PR) { // Sometimes the second preamble byte is missing -> TODO: Find out why! if (frame[1] != PR) { memmove(frame + 1, frame, frame_len); frame_len++; } } else { rig_debug(RIG_DEBUG_WARN, "%s: invalid Icom CI-V frame, no preamble found\n", __func__); return (-RIG_EPROTO); } return frame_len; } /* * icom_one_transaction * * We assume that rig!=NULL, STATE(rig)!= NULL, payload!=NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * payload can be NULL if payload_len == 0 * subcmd can be equal to -1 (no subcmd wanted) * if no answer is to be expected, data_len must be set to NULL to tell so * * return RIG_OK if transaction completed, * or a negative value otherwise indicating the error. */ int icom_one_transaction(RIG *rig, unsigned char cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len) { struct icom_priv_data *priv; const struct icom_priv_caps *priv_caps; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct timeval start_time, current_time, elapsed_time; // this buf needs to be large enough for 0xfe strings for power up // at 115,200 this is now at least 150 unsigned char buf[200]; unsigned char sendbuf[MAXFRAMELEN]; int frm_len, frm_data_len, retval; unsigned char ctrl_id; int collision_retry = 0; ENTERFUNC; memset(buf, 0, 200); memset(sendbuf, 0, MAXFRAMELEN); priv = (struct icom_priv_data *)rs->priv; priv_caps = (struct icom_priv_caps *)rig->caps->priv; ctrl_id = priv_caps->serial_full_duplex == 0 ? CTRLID : 0x80; // Should check return code and that write wrote cmd_len chars! set_transaction_active(rig); collision_retry: // The IC7100 cannot separate the CI-V port from the USB CI-V // We see async packets coming in so we'll try and do the flush // This also means the IC7100 will not support async packets anymore if (rig->caps->rig_model == RIG_MODEL_IC7100) { rig_flush(rp); } frm_len = make_cmd_frame(sendbuf, priv->re_civ_addr, ctrl_id, cmd, subcmd, payload, payload_len); if (data_len) { *data_len = 0; } retval = write_block(rp, sendbuf, frm_len); if (retval != RIG_OK) { set_transaction_inactive(rig); RETURNFUNC(retval); } if (!priv_caps->serial_full_duplex && !priv->serial_USB_echo_off) { /* * read what we just sent, because TX and RX are looped, * and discard it... * - if what we read is not what we sent, then it means * a collision on the CI-V bus occurred! * - if we get a timeout, then retry to send the frame, * up to rs->retry times. */ again1: retval = read_icom_frame(rp, buf, sizeof(buf)); if (retval == -RIG_ETIMEOUT || retval == 0) { /* Nothing received, CI-V interface is not echoing */ set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSERROR); } if (retval < 0) { set_transaction_inactive(rig); // Other error, return it RETURNFUNC(retval); } if (retval < 1) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } if (icom_is_async_frame(rig, frm_len, buf)) { icom_process_async_frame(rig, frm_len, buf); goto again1; } // if we get a reply that is not our cmd/subcmd we should just ignore it and retry the read. // this should somewhat allow splitting the COM port between two controllers if (cmd != buf[4]) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd x%02x != buf x%02x so retry read\n", __func__, cmd, buf[4]); goto again1; } if (subcmd != -1 && subcmd != buf[5]) { rig_debug(RIG_DEBUG_VERBOSE, "%s: subcmd x%02x != buf x%02x so retry read\n", __func__, subcmd, buf[5]); goto again1; } // we might have 0xfe string during rig wakeup rig_debug(RIG_DEBUG_TRACE, "%s: DEBUG retval=%d, frm_len=%d, cmd=0x%02x\n", __func__, retval, frm_len, cmd); if (retval != frm_len && cmd == C_SET_PWR) { rig_debug(RIG_DEBUG_TRACE, "%s: removing 0xfe power up echo, len=%d", __func__, frm_len); while (buf[2] == 0xfe) { memmove(buf, &buf[1], frm_len--); } dump_hex(buf, frm_len); } switch (buf[retval - 1]) { case COL: /* Collision */ // IC746 for example responds 0xfc when tuning is active so we will retry if (collision_retry++ < 20) { rig_debug(RIG_DEBUG_VERBOSE, "%s: collision retry#%d\n", __func__, collision_retry); hl_usleep(500 * 1000); // 500ms 20 times for ~15 second max before we back out for a retry if needed goto collision_retry; } set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSBUSY); case FI: /* Ok, normal frame */ break; default: /* Timeout after reading at least one character */ /* Problem on ci-v bus? */ set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSERROR); } if (retval != frm_len) { /* Not the same length??? */ /* Problem on ci-v bus? */ /* Someone else got a packet in? */ set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } // first 2 bytes of everything are 0xfe so we won't test those // this allows some corruptin of the 0xfe bytes which has been seen in the wild if (memcmp(&buf[2], &sendbuf[2], frm_len - 2) != 0) { /* Frames are different? */ /* Problem on ci-v bus? */ /* Someone else got a packet in? */ set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } } /* * expect an answer? */ if (data_len == NULL) { set_transaction_inactive(rig); RETURNFUNC(RIG_OK); } gettimeofday(&start_time, NULL); read_another_frame: /* * wait for ACK ... * FIXME: handle padding/collisions * ACKFRMLEN is the smallest frame we can expect from the rig */ priv->serial_USB_echo_off = 1; again2: buf[0] = 0; frm_len = read_icom_frame(rp, buf, sizeof(buf)); if (frm_len <= 0) { set_transaction_inactive(rig); RETURNFUNC(frm_len); } if (frm_len > 4 && memcmp(buf, sendbuf, frm_len) == 0) { priv->serial_USB_echo_off = 0; goto again2; } // https://github.com/Hamlib/Hamlib/issues/1575 // these types of async can interrupt the cmd we sent // if our host number changes must not be for us if (icom_is_async_frame(rig, frm_len, buf)) { icom_process_async_frame(rig, frm_len, buf); goto again2; } // IC-PW2 was sending fe fe 94 aa 1c 03 if (buf[3] == 0xaa || buf[2] == 0xaa) { goto again2; } if (sendbuf[3] != buf[2]) { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown async? read again\n", __func__); hl_usleep(100); rig_flush(rp); collision_retry++; if (collision_retry < 2) { goto collision_retry; } } #if 0 // this was causing rigctld to fail on IC706 and WSJT-X // This dynamic detection is therefore disabled for now if (memcmp(buf, sendbuf, frm_len) == 0 && priv->serial_USB_echo_off) { // Hmmm -- got an echo back when not expected so let's change priv->serial_USB_echo_off = 0; // And try again frm_len = read_icom_frame(rp, buf, sizeof(buf)); } #endif if (frm_len < 0) { set_transaction_inactive(rig); if (priv_caps->re_civ_addr != priv->re_civ_addr) { rig_debug(RIG_DEBUG_ERR, "%s: Icom timeout civ expected=%02x, used=%02x\n", __func__, priv_caps->re_civ_addr, priv->re_civ_addr); } // RIG_TIMEOUT: timeout getting response, return timeout // other error: return it RETURNFUNC(frm_len); } if (frm_len < 1) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } retval = icom_frame_fix_preamble(frm_len, buf); if (retval < 0) { set_transaction_inactive(rig); RETURNFUNC(retval); } frm_len = retval; if (frm_len < 1) { rig_debug(RIG_DEBUG_ERR, "Unexpected frame len=%d\n", frm_len); RETURNFUNC(-RIG_EPROTO); } switch (buf[frm_len - 1]) { case COL: set_transaction_inactive(rig); /* Collision */ RETURNFUNC(-RIG_BUSBUSY); case FI: /* Ok, normal frame */ break; case NAK: set_transaction_inactive(rig); RETURNFUNC(-RIG_ERJCTED); default: set_transaction_inactive(rig); /* Timeout after reading at least one character */ /* Problem on ci-v bus? */ RETURNFUNC(-RIG_EPROTO); } if (frm_len < ACKFRMLEN) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } // if we send a bad command we will get back a NAK packet // e.g. fe fe e0 50 fa fd if (frm_len == 6 && NAK == buf[frm_len - 2]) { set_transaction_inactive(rig); RETURNFUNC(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_TRACE, "%s: frm_len=%d, frm_len-1=%02x, frm_len-2=%02x\n", __func__, frm_len, buf[frm_len - 1], buf[frm_len - 2]); // has to be one of these two now or frame is corrupt if (FI != buf[frm_len - 1] && ACK != buf[frm_len - 1]) { set_transaction_inactive(rig); RETURNFUNC(-RIG_BUSBUSY); } frm_data_len = frm_len - (ACKFRMLEN - 1); if (frm_data_len <= 0) { set_transaction_inactive(rig); RETURNFUNC(-RIG_EPROTO); } // TODO: Does ctrlid (detected by icom_is_async_frame) vary (seeing some code above using 0x80 for non-full-duplex)? if (icom_is_async_frame(rig, frm_len, buf)) { int elapsedms; icom_process_async_frame(rig, frm_len, buf); gettimeofday(¤t_time, NULL); timersub(¤t_time, &start_time, &elapsed_time); elapsedms = (int)(elapsed_time.tv_sec * 1000 + elapsed_time.tv_usec / 1000); if (elapsedms > rp->timeout) { set_transaction_inactive(rig); RETURNFUNC(-RIG_ETIMEOUT); } goto read_another_frame; } set_transaction_inactive(rig); *data_len = frm_data_len; if (data != NULL) { memcpy(data, buf + 4, *data_len); } /* * TODO: check addresses in reply frame */ RETURNFUNC(RIG_OK); } /* * icom_transaction * * This function honors rigport.retry count. * * We assume that rig!=NULL, STATE(rig)!= NULL, payload!=NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * payload can be NULL if payload_len == 0 * subcmd can be equal to -1 (no subcmd wanted) * * return RIG_OK if transaction completed, * or a negative value otherwise indicating the error. */ int icom_transaction(RIG *rig, int cmd, int subcmd, const unsigned char *payload, int payload_len, unsigned char *data, int *data_len) { int retval, retry; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=0x%02x, subcmd=0x%02x, payload_len=%d\n", __func__, cmd, subcmd, payload_len); retry = RIGPORT(rig)->retry; do { retval = icom_one_transaction(rig, cmd, subcmd, payload, payload_len, data, data_len); // codes that make us return immediately if (retval == RIG_OK || retval == -RIG_ERJCTED || retval == -RIG_BUSERROR) { break; } rig_debug(RIG_DEBUG_WARN, "%s: retry=%d: %s\n", __func__, retry, rigerror(retval)); // On some serial errors we may need a bit of time hl_usleep(100 * 1000); // pause just a bit } while (retry-- > 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: failed: %s\n", __func__, rigerror(retval)); } RETURNFUNC(retval); } /* used in read_icom_frame as end of block */ static const char icom_block_end[2] = { FI, COL}; #define icom_block_end_length 2 /* * Read a whole CI-V frame (until 0xfd is encountered). * * TODO: strips padding/collisions * FIXME: check return codes/bytes read */ static int read_icom_frame_generic(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len, int direct) { int read = 0; int retries = 10; unsigned char *rx_ptr = (unsigned char *) rxbuffer; // zeroize the buffer so we can still check contents after timeouts memset(rx_ptr, 0, rxbuffer_len); /* * OK, now sometimes we may time out, e.g. the IC7000 can time out * during a PTT operation. So, we will ensure that the last thing we * read was a proper end marker - if not, we will try again. */ do { int i; if (direct) { i = read_string_direct(p, rx_ptr, MAXFRAMELEN - read, icom_block_end, icom_block_end_length, 0, 1); } else { i = read_string(p, rx_ptr, MAXFRAMELEN - read, icom_block_end, icom_block_end_length, 0, 1); } if (i < 0 && i != -RIG_BUSBUSY) /* die on errors */ { return (i); } if (i == 0) /* nothing read?*/ { if (--retries <= 0) /* Tried enough times? */ { return (read); } } /* OK, we got something. add it in and continue */ if (i > 0) { read += i; rx_ptr += i; } } while ((read < rxbuffer_len) && (rxbuffer[read - 1] != FI) && (rxbuffer[read - 1] != COL)); // Check that we have a valid frame preamble (which might be just a single preable character) // Or an error code if (rxbuffer[0] != PR && rxbuffer[0] != COL) { return -RIG_EPROTO; } return (read); } int read_icom_frame(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len) { return read_icom_frame_generic(p, rxbuffer, rxbuffer_len, 0); } int read_icom_frame_direct(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len) { return read_icom_frame_generic(p, rxbuffer, rxbuffer_len, 1); } /* * convert mode and width as expressed by Hamlib frontend * to mode and passband data understandable by a CI-V rig * * if pd == -1, no passband data is to be sent * * return RIG_OK if everything's fine, negative value otherwise * * TODO: be more exhaustive * assumes rig!=NULL */ int rig2icom_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { unsigned char icmode; signed char icmode_ext; pbwidth_t width_tmp = width; const struct icom_priv_data *priv_data = (struct icom_priv_data *) STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: mode=%d, width=%d\n", __func__, (int)mode, (int)width); icmode_ext = -1; if (width == RIG_PASSBAND_NOCHANGE) // then we read width so we can reuse it { rig_debug(RIG_DEBUG_TRACE, "%s: width==RIG_PASSBAND_NOCHANGE\n", __func__); rmode_t tmode; int ret = rig_get_mode(rig, vfo, &tmode, &width); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: Failed to get width for passband nochange err=%s\n", __func__, rigerror(ret)); } } switch (mode) { case RIG_MODE_AM: icmode = S_AM; break; case RIG_MODE_PKTAM: icmode = S_AM; break; case RIG_MODE_AMN: icmode = S_AMN; break; case RIG_MODE_AMS: icmode = S_AMS; break; case RIG_MODE_CW: icmode = S_CW; break; case RIG_MODE_CWR: icmode = S_CWR; break; case RIG_MODE_USB: icmode = S_USB; break; case RIG_MODE_PKTUSB: icmode = S_USB; if (rig->caps->rig_model == RIG_MODEL_IC7800) { icmode = S_PSK; } break; case RIG_MODE_LSB: icmode = S_LSB; break; case RIG_MODE_PKTLSB: icmode = S_LSB; if (rig->caps->rig_model == RIG_MODEL_IC7800) { icmode = S_PSKR; } break; case RIG_MODE_RTTY: icmode = S_RTTY; break; case RIG_MODE_RTTYR: icmode = S_RTTYR; break; case RIG_MODE_PSK: icmode = S_PSK; break; case RIG_MODE_PSKR: icmode = S_PSKR; break; case RIG_MODE_FM: icmode = S_FM; break; case RIG_MODE_PKTFM: icmode = S_FM; break; case RIG_MODE_FMN: icmode = S_FMN; break; case RIG_MODE_PKTFMN: icmode = S_FMN; break; case RIG_MODE_WFM: icmode = S_WFM; break; case RIG_MODE_P25: icmode = S_P25; break; case RIG_MODE_DSTAR: icmode = S_DSTAR; break; case RIG_MODE_DPMR: icmode = S_DPMR; break; case RIG_MODE_NXDNVN: icmode = S_NXDNVN; break; case RIG_MODE_NXDN_N: icmode = S_NXDN_N; break; case RIG_MODE_DCR: icmode = S_DCR; break; case RIG_MODE_DD: icmode = S_DD; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Hamlib mode %s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } if (width_tmp != RIG_PASSBAND_NOCHANGE) { rig_debug(RIG_DEBUG_TRACE, "%s: width_tmp=%ld\n", __func__, width_tmp); pbwidth_t medium_width = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL) { // Use rig default for "normal" passband icmode_ext = -1; } else if (width < medium_width) { icmode_ext = PD_NARROW_3; } else if (width == medium_width) { icmode_ext = PD_MEDIUM_3; } else { icmode_ext = PD_WIDE_3; } if (rig->caps->rig_model == RIG_MODEL_ICR7000) { if (mode == RIG_MODE_USB || mode == RIG_MODE_LSB) { icmode = S_R7000_SSB; icmode_ext = 0x00; } else if (mode == RIG_MODE_AM && icmode_ext == -1) { icmode_ext = PD_WIDE_3; /* default to Wide */ } } *pd = icmode_ext; } else { // filter should already be set elsewhere *pd = priv_data->filter; } *md = icmode; RETURNFUNC(RIG_OK); } /* * assumes rig!=NULL, mode!=NULL, width!=NULL */ void icom2rig_mode(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_TRACE, "%s: mode=0x%02x, pd=%d\n", __func__, md, pd); // Some rigs return fixed with for FM mode if ((RIG_IS_IC7300 || RIG_IS_IC9700) && (md == S_FM || md == S_WFM)) { *mode = RIG_MODE_FM; if (*width == 1) { *width = 15000; } else if (*width == 2) { *width = 10000; } else { *width = 7000; } return; } *width = RIG_PASSBAND_NORMAL; switch (md) { case S_AM: if (rig->caps->rig_model == RIG_MODEL_ICR30 && pd == 0x02) { *mode = RIG_MODE_AMN; } else { *mode = RIG_MODE_AM; } break; case S_AMS: *mode = RIG_MODE_AMS; break; case S_CW: *mode = RIG_MODE_CW; break; case S_CWR: *mode = RIG_MODE_CWR; break; case S_FM: if (rig->caps->rig_model == RIG_MODEL_ICR7000 && pd == 0x00) { *mode = RIG_MODE_USB; *width = rig_passband_normal(rig, RIG_MODE_USB); return; } else if (rig->caps->rig_model == RIG_MODEL_ICR30 && pd == 0x02) { *mode = RIG_MODE_FMN; } else { *mode = RIG_MODE_FM; } break; case S_WFM: *mode = RIG_MODE_WFM; break; case S_USB: *mode = RIG_MODE_USB; break; case S_LSB: *mode = RIG_MODE_LSB; break; case S_RTTY: *mode = RIG_MODE_RTTY; break; case S_RTTYR: *mode = RIG_MODE_RTTYR; break; case S_PSK: *mode = RIG_MODE_PSK; if (rig->caps->rig_model == RIG_MODEL_IC7800) { *mode = RIG_MODE_PKTUSB; } break; case S_PSKR: *mode = RIG_MODE_PSKR; if (rig->caps->rig_model == RIG_MODEL_IC7800) { *mode = RIG_MODE_PKTLSB; } break; case S_DSTAR: *mode = RIG_MODE_DSTAR; break; case S_P25: *mode = RIG_MODE_P25; break; case S_DPMR: *mode = RIG_MODE_DPMR; break; case S_NXDNVN: *mode = RIG_MODE_NXDNVN; break; case S_NXDN_N: *mode = RIG_MODE_NXDN_N; break; case S_DCR: *mode = RIG_MODE_DCR; break; case 0xff: *mode = RIG_MODE_NONE; break; /* blank mem channel */ default: rig_debug(RIG_DEBUG_ERR, "icom: Unsupported Icom mode %#.2x\n", md); *mode = RIG_MODE_NONE; } /* Most rigs return 1-wide, 2-narrow; or if it has 3 filters: 1-wide, 2-middle, 3-narrow. (Except for the 706 mkIIg 0-wide, 1-middle, 2-narrow.) For DSP rigs these are presets, which can be programmed for 30 - 41 bandwidths, depending on mode */ if (pd >= 0 && (rig->caps->rig_model == RIG_MODEL_IC706MKIIG || rig->caps->rig_model == RIG_MODEL_IC706 || rig->caps->rig_model == RIG_MODEL_IC706MKII)) { pd++; } switch (pd) { case 0x01: /* if no wide filter defined it's the default */ if (!(*width = rig_passband_wide(rig, *mode))) { *width = rig_passband_normal(rig, *mode); } break; case 0x02: if ((*width = rig_passband_wide(rig, *mode))) { *width = rig_passband_normal(rig, *mode); } else /* This really just depends on how you program the table. */ { *width = rig_passband_narrow(rig, *mode); } break; case 0x03: *width = rig_passband_narrow(rig, *mode); break; case -1: break; /* no passband data */ default: rig_debug(RIG_DEBUG_ERR, "icom: Unsupported Icom mode width %#.2x\n", pd); } } hamlib-4.6.2/rigs/icom/ic7600.c0000644000175000017500000004172714752216205012666 00000000000000/* * Hamlib CI-V backend - description of IC-7600 * Copyright (c) 2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "token.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #include "tones.h" #define IC7600_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7600_1HZ_TS_MODES IC7600_ALL_RX_MODES #define IC7600_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7600_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7600_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH) #define IC7600_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7600_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7600_PARMS (RIG_PARM_ANN|RIG_PARM_BEEP|RIG_PARM_TIME|RIG_PARM_BACKLIGHT|RIG_PARM_KEYLIGHT) #define IC7600_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7600_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7600_ANTS (RIG_ANT_1|RIG_ANT_2) /* * Measurement by Roeland, PA3MET */ #define IC7600_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 11, -48 }, \ { 21, -42 }, \ { 34, -36 }, \ { 50, -30 }, \ { 59, -24 }, \ { 75, -18 }, \ { 93, -12 }, \ { 103, -6 }, \ { 124, 0 }, /* S9 */ \ { 145, 10 }, \ { 160, 20 }, \ { 183, 30 }, \ { 204, 40 }, \ { 222, 50 }, \ { 246, 60 } /* S9+60dB */ \ } } #define IC7600_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7600_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7600_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7600_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7600_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 152, 10.0f }, \ { 181, 13.0f }, \ { 212, 16.0f } \ } } #define IC7600_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 241, 25.0f } \ } } struct cmdparams ic7600_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x59}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x38}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x54}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x67}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x37}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7600_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_BACKEND_NONE }; /* * IC-7600 rig capabilities. */ static const struct icom_priv_caps ic7600_priv_caps = { 0x7a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 3, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7600_extcmds, /* Custom op parameters */ .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7600_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x53; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x54; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x56; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7600_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x53; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x54; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x56; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } struct rig_caps ic7600_caps = { RIG_MODEL(RIG_MODEL_IC7600), .model_name = "IC-7600", .mfg_name = "Icom", .version = BACKEND_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7600_FUNCS, .has_set_func = IC7600_FUNCS, .has_get_level = IC7600_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7600_LEVELS), .has_get_parm = IC7600_PARMS, .has_set_parm = RIG_PARM_SET(IC7600_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_KEYLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic7600_ext_tokens, .extfuncs = icom_ext_funcs, .extlevels = icom_ext_levels, .extparms = icom_ext_parms, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 16, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7600_VFO_OPS, .scan_ops = IC7600_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7600_ALL_RX_MODES, -1, -1, IC7600_VFOS, IC7600_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_6m(1, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_HF(1, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7600_ALL_RX_MODES, -1, -1, IC7600_VFOS, IC7600_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_6m(2, IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS), FRQ_RNG_HF(2, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7600_AM_TX_MODES, W(1), W(30), IC7600_VFOS, IC7600_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7600_OTHER_TX_MODES, W(2), W(100), IC7600_VFOS, IC7600_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7600_1HZ_TS_MODES, 1}, {IC7600_ALL_RX_MODES, Hz(100)}, {IC7600_ALL_RX_MODES, kHz(1)}, {IC7600_ALL_RX_MODES, kHz(5)}, {IC7600_ALL_RX_MODES, kHz(9)}, {IC7600_ALL_RX_MODES, kHz(10)}, {IC7600_ALL_RX_MODES, kHz(12.5)}, {IC7600_ALL_RX_MODES, kHz(20)}, {IC7600_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7600_STR_CAL, .swr_cal = IC7600_SWR_CAL, .alc_cal = IC7600_ALC_CAL, .rfpower_meter_cal = IC7600_RFPOWER_METER_CAL, .comp_meter_cal = IC7600_COMP_METER_CAL, .vd_meter_cal = IC7600_VD_METER_CAL, .id_meter_cal = IC7600_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7600_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .wait_morse = rig_wait_morse, .set_clock = ic7600_set_clock, .get_clock = ic7600_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic737.c0000644000175000017500000001240514752216205012601 00000000000000/* * Hamlib CI-V backend - description of IC-737 * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "icom.h" /* * IC-737 */ #define IC737_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC737_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC737_AM_TX_MODES (RIG_MODE_AM) #define IC737_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC737_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC737_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_VFO) #define IC737_ANTS (RIG_ANT_1|RIG_ANT_2) static const struct icom_priv_caps ic737_priv_caps = { 0x3c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list, .antack_len = 2, .ant_count = 2 }; struct rig_caps ic737_caps = { RIG_MODEL(RIG_MODEL_IC737), .model_name = "IC-737", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC737_VFO_OPS, .scan_ops = IC737_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 100, RIG_MTYPE_MEM }, { 101, 101, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), IC737_ALL_RX_MODES, -1, -1, IC737_VFO_ALL, IC737_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC737_OTHER_TX_MODES, W(10), W(100), IC737_VFO_ALL, IC737_ANTS), FRQ_RNG_HF(1, IC737_AM_TX_MODES, W(10), W(40), IC737_VFO_ALL, IC737_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), IC737_ALL_RX_MODES, -1, -1, IC737_VFO_ALL, IC737_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC737_OTHER_TX_MODES, W(10), W(100), IC737_VFO_ALL, IC737_ANTS), FRQ_RNG_HF(2, IC737_AM_TX_MODES, W(10), W(40), IC737_VFO_ALL, IC737_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC737_ALL_RX_MODES, 10}, {IC737_ALL_RX_MODES, kHz(1)}, {IC737_ALL_RX_MODES, kHz(2)}, {IC737_ALL_RX_MODES, kHz(3)}, {IC737_ALL_RX_MODES, kHz(4)}, {IC737_ALL_RX_MODES, kHz(5)}, {IC737_ALL_RX_MODES, kHz(6)}, {IC737_ALL_RX_MODES, kHz(7)}, {IC737_ALL_RX_MODES, kHz(8)}, {IC737_ALL_RX_MODES, kHz(9)}, {IC737_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic737_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr71.c0000644000175000017500000001000714752216205012666 00000000000000/* * Hamlib CI-V backend - description of IC-R71 * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" /* FM optional */ #define ICR71_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define ICR71_FUNC_ALL (RIG_FUNC_NONE) #define ICR71_LEVEL_ALL (RIG_LEVEL_NONE) #define ICR71_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define ICR71_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define ICR71_SCAN_OPS (RIG_SCAN_NONE) static struct icom_priv_caps icr71_priv_caps = { 0x1a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list /* none actually */ }; struct rig_caps icr71_caps = { RIG_MODEL(RIG_MODEL_ICR71), .model_name = "IC-R71", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR71_FUNC_ALL, .has_set_func = ICR71_FUNC_ALL, .has_get_level = ICR71_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR71_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR71_VFO_OPS, .scan_ops = ICR71_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), ICR71_MODES, -1, -1, ICR71_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), ICR71_MODES, -1, -1, ICR71_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR71_MODES, Hz(10)}, /* resolution */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, /* optional w/ IC-EX257 unit */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr71_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic7800.c0000644000175000017500000004347314752216205012670 00000000000000/* * Hamlib CI-V backend - description of IC-7800 and variations * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "frame.h" #include "misc.h" #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "ic7300.h" int ic7800_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int ic7800_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); #define IC7800_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7800_1HZ_TS_MODES IC7800_ALL_RX_MODES #define IC7800_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7800_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7800_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH) #define IC7800_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7800_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7800_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7800_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7800_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7800_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-7800 S-meter calibration data based on manual #define IC7800_STR_CAL { 3, \ { \ { 0, -54 }, /* S0 */ \ { 120, 0 }, /* S9 */ \ { 241, 60 } /* S9+60 */ \ } } #define IC7800_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7800_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7800_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7800_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7800_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC7800_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 165, 10.0f }, \ { 241, 15.0f } \ } } int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); struct cmdparams ic7800_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x83}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7800_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_BACKEND_NONE }; /* * IC-7800 rig capabilities. */ static const struct icom_priv_caps ic7800_priv_caps = { 0x6a, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 4, .ant_count = 3, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7800_extcmds, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic7800_caps = { RIG_MODEL(RIG_MODEL_IC7800), .model_name = "IC-7800", .mfg_name = "Icom", .version = BACKEND_VER ".8", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7800_FUNCS, .has_set_func = IC7800_FUNCS, .has_get_level = IC7800_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7800_LEVELS), .has_get_parm = IC7800_PARMS, .has_set_parm = RIG_PARM_SET(IC7800_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ext_tokens = ic7800_ext_tokens, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 16, RIG_DBLST_END, }, .attenuator = { 3, 6, 9, 12, 15, 18, 21, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7800_VFO_OPS, .scan_ops = IC7800_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7800_ALL_RX_MODES, -1, -1, IC7800_VFOS, IC7800_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_6m(1, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_HF(1, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7800_ALL_RX_MODES, -1, -1, IC7800_VFOS, IC7800_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_6m(2, IC7800_OTHER_TX_MODES, W(5), W(200), IC7800_VFOS, IC7800_ANTS), FRQ_RNG_HF(2, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7800_AM_TX_MODES, W(5), W(50), IC7800_VFOS, IC7800_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7800_OTHER_TX_MODES, W(2), W(100), IC7800_VFOS, IC7800_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7800_1HZ_TS_MODES, 1}, {IC7800_ALL_RX_MODES, Hz(100)}, {IC7800_ALL_RX_MODES, kHz(1)}, {IC7800_ALL_RX_MODES, kHz(5)}, {IC7800_ALL_RX_MODES, kHz(9)}, {IC7800_ALL_RX_MODES, kHz(10)}, {IC7800_ALL_RX_MODES, kHz(12.5)}, {IC7800_ALL_RX_MODES, kHz(20)}, {IC7800_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7800_STR_CAL, .swr_cal = IC7800_SWR_CAL, .alc_cal = IC7800_ALC_CAL, .rfpower_meter_cal = IC7800_RFPOWER_METER_CAL, .comp_meter_cal = IC7800_COMP_METER_CAL, .vd_meter_cal = IC7800_VD_METER_CAL, .id_meter_cal = IC7800_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7800_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = ic7800_set_level, .get_level = ic7800_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7800_set_clock, .get_clock = ic7800_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * IC-7800 has 0x11 command using index instead of backend's real dB value * * c.f. http://www.plicht.de/ekki/civ/civ-p42.html */ int ic7800_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: if (val.i != 0) { /* Convert dB to index */ int i; for (i = 0; i < 7; i++) { if (val.i == STATE(rig)->attenuator[i]) { val.i = i + 1; break; } } /* TODO: Should fail when not found? */ } return icom_set_level(rig, vfo, level, val); default: return icom_set_level(rig, vfo, level, val); } } /* * IC-7800 has 0x11 command using index instead of backend's real dB value */ int ic7800_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: retval = icom_get_level(rig, vfo, level, val); if (retval != RIG_OK) { return retval; } /* Convert index to dB * Rem: ATT index 0 means attenuator Off */ if (val->i > 0 && val->i <= 7) { val->i = STATE(rig)->attenuator[val->i - 1]; } break; default: return icom_get_level(rig, vfo, level, val); } return RIG_OK; } // if hour < 0 then only date will be set int ic7800_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x60; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x62; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7800_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x59; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x60; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x62; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } hamlib-4.6.2/rigs/icom/ic7000.c0000644000175000017500000003270514752216205012654 00000000000000/* * Hamlib CI-V backend - description of IC-7000 and variations * Adapted from IC-7800 code 2006 by Kent Hill * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "bandplan.h" #include "tones.h" #define IC7000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_WFM) #define IC7000_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7000_NOT_TS_MODES (IC7000_ALL_RX_MODES &~IC7000_1HZ_TS_MODES) #define IC7000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM) #define IC7000_AM_TX_MODES (RIG_MODE_AM) #define IC7000_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_ARO) #define IC7000_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7000_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7000_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_APO|RIG_PARM_TIME|RIG_PARM_BEEP) #define IC7000_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7000_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC7000_ANTS (RIG_ANT_1|RIG_ANT_2) /* ant-1 is Hf-6m, ant-2 is 2m-70cm */ /* * Measurement by Mark, WA0TOP * * s/n 0503103. * Preamp off, ATT off, mode AM, f=10 MHz */ #define IC7000_STR_CAL { 14, \ { \ { 0, -54 }, /* first one is made up */ \ { 5, -29 }, \ { 15, -27 }, \ { 43, -22 }, \ { 68, -17 }, \ { 92, -12 }, \ { 120, -6 }, \ { 141, 2 }, \ { 162, 13 }, \ { 182, 25 }, \ { 202, 38 }, \ { 222, 47 }, \ { 241, 57 }, \ { 255, 63 } \ } } #define IC7000_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7000_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7000_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7000_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } /* * * IC7000 channel caps. */ #define IC7000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ .rptr_shift = 1, \ .ctcss_tone = 1, \ .ctcss_sql = 1, \ .funcs = IC7000_FUNCS, \ .levels = RIG_LEVEL_SET(IC7000_LEVELS), \ } struct cmdparams ic7000_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x17}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x41}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_NONE} } }; /* * This function does the special bandwidth coding for IC-7000 */ static int ic7000_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (err != RIG_OK) { return err; } // CAT section of manual says: nn = 0 -40 > bw = 50Hz > 3600Hz // Tested by Ian G3VPX 20201029 // 0 - 9 > bw 50Hz to 500Hz in 50Hz steps // 10 - 40 > bw 600Hz to 3600Hz in 100Hz steps if (width != RIG_PASSBAND_NOCHANGE) { if (width <= 500) { *pd = width / 50 - 1; } else if (width <= 3600) { *pd = width / 100 + 4; } else { *pd = 40; } } return RIG_OK; } /* * IC-7000 rig capabilities. */ static const struct icom_priv_caps IC7000_priv_caps = { 0x70, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7000_ts_sc_list, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7000_extcmds, .r2i_mode = ic7000_r2i_mode }; struct rig_caps ic7000_caps = { RIG_MODEL(RIG_MODEL_IC7000), .model_name = "IC-7000", .mfg_name = "Icom", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7000_FUNCS, .has_set_func = IC7000_FUNCS, .has_get_level = IC7000_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7000_LEVELS), .has_get_parm = IC7000_PARMS, .has_set_parm = RIG_PARM_SET(IC7000_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_APO] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, RIG_DBLST_END, }, /* FIXME: TBC it's a guess */ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), /* TODO */ .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = 0, .vfo_ops = IC7000_VFO_OPS, .scan_ops = IC7000_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, /* TODO */ .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC7000_MEM_CAP }, { 100, 105, RIG_MTYPE_EDGE, IC7000_MEM_CAP }, /* two by two */ { 106, 107, RIG_MTYPE_CALL, IC7000_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, {MHz(400), MHz(470), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_2m(1, IC7000_OTHER_TX_MODES, W(2), W(50), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, IC7000_OTHER_TX_MODES, W(2), W(35), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_HF(1, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(1, IC7000_AM_TX_MODES, W(2), W(20), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(1, IC7000_OTHER_TX_MODES, W(2), W(14), IC7000_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, {MHz(400), MHz(470), IC7000_ALL_RX_MODES, -1, -1, IC7000_VFOS}, RIG_FRNG_END, }, .tx_range_list2 = { /* needs the 5 mhz channels added */ FRQ_RNG_HF(2, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_6m(2, IC7000_OTHER_TX_MODES, W(2), W(100), IC7000_VFOS, RIG_ANT_1), FRQ_RNG_2m(2, IC7000_OTHER_TX_MODES, W(2), W(50), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, IC7000_OTHER_TX_MODES, W(2), W(35), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_HF(2, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(2, IC7000_AM_TX_MODES, W(1), W(40), IC7000_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_2m(2, IC7000_AM_TX_MODES, W(2), W(20), IC7000_VFOS, RIG_ANT_2), FRQ_RNG_70cm(2, IC7000_OTHER_TX_MODES, W(2), W(14), IC7000_VFOS, RIG_ANT_2), RIG_FRNG_END, }, .tuning_steps = { {IC7000_1HZ_TS_MODES, 1}, {IC7000_NOT_TS_MODES, 10}, {IC7000_ALL_RX_MODES, Hz(100)}, {IC7000_ALL_RX_MODES, kHz(1)}, {IC7000_ALL_RX_MODES, kHz(5)}, {IC7000_ALL_RX_MODES, kHz(9)}, {IC7000_ALL_RX_MODES, kHz(10)}, {IC7000_ALL_RX_MODES, kHz(12.5)}, {IC7000_ALL_RX_MODES, kHz(20)}, {IC7000_ALL_RX_MODES, kHz(25)}, {IC7000_ALL_RX_MODES, kHz(100)}, {IC7000_NOT_TS_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(280)}, RIG_FLT_END, }, .str_cal = IC7000_STR_CAL, .swr_cal = IC7000_SWR_CAL, .alc_cal = IC7000_ALC_CAL, .rfpower_meter_cal = IC7000_RFPOWER_METER_CAL, .comp_meter_cal = IC7000_COMP_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC7000_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, /*automatically set by rig depending band */ .get_ant = NULL, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = NULL, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = NULL, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic736.c0000644000175000017500000001360614752216205012604 00000000000000/* * Hamlib CI-V backend - description of IC-736 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "icom.h" /* * IC-736 */ #define IC736_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC736_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC736_AM_TX_MODES (RIG_MODE_AM) #define IC736_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC736_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY) #define IC736_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_VFO) #define IC736_ANTS 0 /* FIXME: declare both antenna connectors */ #define IC736_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic736_priv_caps = { 0x40, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic736_caps = { RIG_MODEL(RIG_MODEL_IC736), .model_name = "IC-736", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC736_VFO_OPS, .scan_ops = IC736_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 89, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 90, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, /* FIXME: split */ { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, {MHz(50), MHz(54), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_6m(1, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_HF(1, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ FRQ_RNG_6m(1, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, {MHz(50), MHz(54), IC736_ALL_RX_MODES, -1, -1, IC736_VFO_ALL, IC736_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_6m(2, IC736_OTHER_TX_MODES, W(5), W(100), IC736_VFO_ALL, IC736_ANTS), FRQ_RNG_HF(2, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ FRQ_RNG_6m(2, IC736_AM_TX_MODES, W(4), W(40), IC736_VFO_ALL, IC736_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { /* TBC */ {IC736_ALL_RX_MODES, 10}, {IC736_ALL_RX_MODES, kHz(1)}, {IC736_ALL_RX_MODES, kHz(2)}, {IC736_ALL_RX_MODES, kHz(3)}, {IC736_ALL_RX_MODES, kHz(4)}, {IC736_ALL_RX_MODES, kHz(5)}, {IC736_ALL_RX_MODES, kHz(6)}, {IC736_ALL_RX_MODES, kHz(7)}, {IC736_ALL_RX_MODES, kHz(8)}, {IC736_ALL_RX_MODES, kHz(9)}, {IC736_ALL_RX_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.1)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic736_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ts = icom_set_ts, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/os456.c0000644000175000017500000001305014752216205012622 00000000000000/* * Hamlib CI-V backend - description of the OptoScan456 * Copyright (c) 2000-2004 by Stephane Fillod and Michael Smith * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * This backend is currently being maintained by Michael Smith, KE4RJQ. * Email: james (dot) m (dot) smith (at) earthlink (dot) net */ #include #include #include "idx_builtin.h" #include "icom.h" #include "tones.h" #include "optoscan.h" extern struct confparams opto_ext_parms[]; #define OS456_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define OS456_VFO_ALL (RIG_VFO_A) #define OS456_LEVELS (RIG_LEVEL_RAWSTR|RIG_LEVEL_AF) #define OS456_SCAN_OPS (RIG_SCAN_PLT) /* * The signal strength data is in the form of two bytes, each consisting * of two BCD digits. The signal strength is reported in units of absolute * dBm as measured at the antenna connector. The reported signal strength * ranges from a maximum signal of 0 dBm to a minimum signal of - 125 dBm. * A minus sign is implied. */ #define OS456_STR_CAL { 2, { \ { 0, 60 }, \ { 125, -60 }, \ } } /* TBC */ /* * The OptoScan is not actually a rig. This is an add-in circuit board * for the Realistic PRO-2006 and PRO-2005 Scanning VHF-UHF Receivers. * http://www.optoelectronics.com/tech/pdf/os535/os535_ci5_spec_v10.pdf * * TODO: srch_dcs, srch_ctcss, rcv_dtmf, and make icom_probe opto aware */ static struct icom_priv_caps os456_priv_caps = { 0x80, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ NULL, .settle_time = 20, }; struct rig_caps os456_caps = { RIG_MODEL(RIG_MODEL_OS456), .model_name = "OptoScan456", .mfg_name = "Optoelectronics", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_SCANNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_SERIAL_CAR, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = OS456_LEVELS, .has_set_level = RIG_LEVEL_AF, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = full_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = RIG_OP_NONE, .scan_ops = OS456_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { { MHz(25), MHz(520), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(760), MHz(1300), OS456_MODES, -1, -1, OS456_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* this is a scanner */ .rx_range_list2 = { { MHz(25), MHz(520), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(760), MHz(823.995), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(849), MHz(868.995), OS456_MODES, -1, -1, OS456_VFO_ALL}, { MHz(894), MHz(1300), OS456_MODES, -1, -1, OS456_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* this is a scanner */ .tuning_steps = { {OS456_MODES, kHz(5)}, {OS456_MODES, kHz(12.5)}, {OS456_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, kHz(15)}, /* TBC */ RIG_FLT_END, }, .str_cal = OS456_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& os456_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = optoscan_open, .rig_close = optoscan_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .get_info = optoscan_get_info, .get_ctcss_tone = optoscan_get_ctcss_tone, .get_dcs_code = optoscan_get_dcs_code, .recv_dtmf = optoscan_recv_dtmf, .extparms = opto_ext_parms, .set_ext_parm = optoscan_set_ext_parm, .get_ext_parm = optoscan_get_ext_parm, .set_level = optoscan_set_level, .get_level = optoscan_get_level, .scan = optoscan_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic471.c0000644000175000017500000001027714752216205012601 00000000000000/* * Hamlib CI-V backend - description of IC-471 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC471_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC471_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC471_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC471_STR_CAL { 0, { } } /* * IC-471 A/E * IC-471 H is high power (75W) * specs: http://www.qsl.net/sm7vhs/radio/icom/ic471/specs.htm * * Please report testing / patches. Some capabilities may be missing too. --sf */ static const struct icom_priv_caps ic471_priv_caps = { 0x22, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic471_caps = { RIG_MODEL(RIG_MODEL_IC471), .model_name = "IC-471", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC471_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 38, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(450), IC471_MODES, -1, -1, IC471_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), IC471_MODES, W(2.5), W(25), IC471_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(430), MHz(450), IC471_MODES, -1, -1, IC471_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(430), MHz(450), IC471_MODES, W(2.5), W(25), IC471_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC471_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic471_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr72.c0000644000175000017500000001134014752216205012670 00000000000000/* * Hamlib CI-V backend - description of IC-R72 * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define ICR72_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define ICR72_FUNC_ALL (RIG_FUNC_NONE) #define ICR72_LEVEL_ALL (RIG_LEVEL_NONE) #define ICR72_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_MCL) #define ICR72_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define ICR71_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ICR72_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_SLCT|RIG_SCAN_PRIO) static struct icom_priv_caps icr72_priv_caps = { 0x32, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps icr72_caps = { RIG_MODEL(RIG_MODEL_ICR72), .model_name = "IC-R72", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR72_FUNC_ALL, .has_set_func = ICR72_FUNC_ALL, .has_get_level = ICR72_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR72_LEVEL_ALL), .has_get_parm = RIG_PARM_ANN, .has_set_parm = RIG_PARM_ANN, .level_gran = {}, /* granularity */ .parm_gran = { [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR72_VFO_OPS, .scan_ops = ICR72_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), ICR72_MODES, -1, -1, ICR72_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), ICR72_MODES, -1, -1, ICR72_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR72_MODES, Hz(10)}, {ICR72_MODES, kHz(1)}, {ICR72_MODES, kHz(2)}, {ICR72_MODES, kHz(3)}, {ICR72_MODES, kHz(4)}, {ICR72_MODES, kHz(5)}, {ICR72_MODES, kHz(6)}, {ICR72_MODES, kHz(7)}, {ICR72_MODES, kHz(8)}, {ICR72_MODES, kHz(9)}, {ICR72_MODES, kHz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr72_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .get_level = icom_get_level, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .scan = icom_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icom.h0000644000175000017500000007157114752216205012712 00000000000000/* * Hamlib CI-V backend - main header * Copyright (c) 2000-2016 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICOM_H #define _ICOM_H 1 #include #include #include "hamlib/rig.h" #include "cal.h" #include "tones.h" #include "idx_builtin.h" #ifdef HAVE_SYS_TIME_H #include #endif #define BACKEND_VER "20250107" #define ICOM_IS_ID31 rig_is_model(rig, RIG_MODEL_ID31) #define ICOM_IS_ID51 rig_is_model(rig, RIG_MODEL_ID51) #define ICOM_IS_ID4100 rig_is_model(rig, RIG_MODEL_ID4100) #define ICOM_IS_ID5100 rig_is_model(rig, RIG_MODEL_ID5100) #define ICOM_IS_SECONDARY_VFO(vfo) ((vfo) & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B)) #define ICOM_GET_VFO_NUMBER(vfo) (ICOM_IS_SECONDARY_VFO(vfo) ? 0x01 : 0x00) #define ICOM_MAX_SPECTRUM_FREQ_RANGES 20 /* * defines used by comp_cal_str in rig.c * STR_CAL_LENGTH is the length of the S Meter calibration table * STR_CAL_S0 is the value in dB of the lowest value (not even in table) * MULTIB_SUBCMD allows the dsp rigs ie pro models to use multibyte subcommands for all the extra * parameters and levels. */ #define STR_CAL_LENGTH 16 #define STR_CAL_S0 (-54) #define MULTIB_SUBCMD /* * minimal channel caps. * If your rig has better/lesser, don't modify this define but clone it, * so you don't change other rigs. */ #define IC_MIN_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } /* * common channel caps. * If your rig has better/lesser, don't modify this define but clone it, * so you don't change other rigs. */ #define IC_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .rptr_offs = 1, \ } /* * S-Meter data for uncalibrated rigs */ #define UNKNOWN_IC_STR_CAL { 2, {{ 0, -60}, { 255, 60}} } struct ts_sc_list { shortfreq_t ts; /* tuning step */ unsigned char sc; /* sub command */ }; /** * \brief Pipelined tuning state data structure. */ typedef struct rig_pltstate { freq_t freq; freq_t next_freq; rmode_t mode; rmode_t next_mode; pbwidth_t width; pbwidth_t next_width; struct timeval timer_start; struct timeval timer_current; int usleep_time; /* dependent on radio module & serial data rate */ } pltstate_t; /** * \brief Mappings between Hamlib and Icom AGC levels */ struct icom_agc_level { enum agc_level_e level; /*!< Hamlib AGC level from agc_level_e enum, the last entry should have level -1 */ unsigned char icom_level; /*!< Icom AGC level for C_CTL_FUNC (0x16), S_FUNC_AGC (0x12) command */ }; typedef enum { CMD_PARAM_TYPE_NONE, CMD_PARAM_TYPE_LEVEL, CMD_PARAM_TYPE_PARM, CMD_PARAM_TYPE_TOKEN, CMD_PARAM_TYPE_FUNC, } cmd_param_t; /** * \brief Lookup table item for Icom levels & parms */ struct cmdparams { union { setting_t s; /*!< Level or parm */ hamlib_token_t t; /*!< TOKEN_BACKEND */ } id; cmd_param_t cmdparamtype; /*!< CMD_PARAM_TYPE_LEVEL or CMD_PARAM_TYPE_PARM */ int command; /*!< CI-V command */ int subcmd; /*!< CI-V Subcommand */ int submod; /*!< Subcommand modifier */ int sublen; /*!< Number of bytes for subcommand extension */ unsigned char subext[4]; /*!< Subcommand extension bytes */ int dattyp; /*!< Data type conversion */ int datlen; /*!< Number of data bytes in frame */ }; /** * \brief Icom-specific spectrum scope capabilities, if supported by the rig. */ struct icom_spectrum_scope_caps { int spectrum_line_length; /*!< Number of bytes in a complete spectrum scope line */ int single_frame_data_length; /*!< Number of bytes of specrtum data in a single CI-V frame when the data split to multiple frames */ int data_level_min; /*!< */ int data_level_max; double signal_strength_min; double signal_strength_max; }; /** * \brief Icom spectrum scope edge frequencies, if supported by the rig. * * Last entry should have zeros in all fields. */ struct icom_spectrum_edge_frequency_range { int range_id; /*!< ID of the range, as specified in the Icom CI-V manuals. First range ID is 1. */ freq_t low_freq; /*!< The low edge frequency if the range in Hz */ freq_t high_freq; /*!< The high edge frequency if the range in Hz */ }; /** * \brief Cached Icom spectrum scope data. * * This data is used to store data for current line of spectrum data as it is being received from the rig. * Caching the data is necessary for handling spectrum scope data split in multiple CI-V frames. */ struct icom_spectrum_scope_cache { int id; /*!< Numeric ID of the spectrum scope data stream identifying the VFO/receiver. First ID is zero. Icom rigs with multiple scopes have IDs: 0 = Main, 1 = Sub. */ int spectrum_metadata_valid; /*!< Boolean value to track validity of the cached data for spectrum scope. */ enum rig_spectrum_mode_e spectrum_mode; /*!< The spectrum mode of the current spectrum scope line being received. */ freq_t spectrum_center_freq; /*!< The center frequency of the current spectrum scope line being received */ freq_t spectrum_span_freq; /*!< The frequency span of the current spectrum scope line being received */ freq_t spectrum_low_edge_freq; /*!< The low edge frequency of the current spectrum scope line being received */ freq_t spectrum_high_edge_freq; /*!< The high edge frequency of the current spectrum scope line being received */ size_t spectrum_data_length; /*!< Number of bytes of 8-bit spectrum data in the data buffer. The amount of data may vary if the rig has multiple spectrum scopes, depending on the scope. */ unsigned char *spectrum_data; /*!< Dynamically allocated buffer for raw spectrum data */ }; struct icom_priv_caps { unsigned char re_civ_addr; /*!< The remote equipment's default CI-V address */ int civ_731_mode; /*!< Off: freqs on 10 digits, On: freqs on 8 digits plus passband setting */ // According to the CI-V+ manual the IC-781, IC-R9000, and IC-R7000 can select pas$ // The other rigs listed apparently cannot and may need the civ_731_mode=1 which are // 1-706 // 2-706MKII // 3-706MKIIG // 4-707 // 5-718 // 6-746 // 7-746PRO // 8-756 // 9-756PRO // 10-756PROII // 11-820H // 12-821H // 13-910H // 14-R10 // 15-R8500 // 16-703 // 17-7800 int no_xchg; /*!< Off: use VFO XCHG to set other VFO, On: use set VFO to set other VFO */ const struct ts_sc_list *ts_sc_list; // the 4 elements above are mandatory // everything below here is optional in the backends int settle_time; /*!< Receiver settle time, in ms */ int (*r2i_mode)(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd); /*!< backend specific code to convert bandwidth and mode to cmd tokens */ void (*i2r_mode)(RIG *rig, unsigned char md, int pd, rmode_t *mode, pbwidth_t *width); /*!< backend specific code to convert response tokens to bandwidth and mode */ int antack_len; /*!< Length of 0x12 cmd may be 3 or 4 bytes as of 2020-01-22 e.g. 7851 */ int ant_count; /*!< Number of antennas */ int serial_full_duplex; /*!< Whether RXD&TXD are not tied together */ int offs_len; /*!< Number of bytes in offset frequency field. 0 defaults to 3 */ int serial_USB_echo_check; /*!< Flag to test USB echo state */ int agc_levels_present; /*!< Flag to indicate that agc_levels array is populated */ struct icom_agc_level agc_levels[HAMLIB_MAX_AGC_LEVELS + 1]; /*!< Icom rig-specific AGC levels, the last entry should have level -1 */ struct icom_spectrum_scope_caps spectrum_scope_caps; /*!< Icom spectrum scope capabilities, if supported by the rig. Main/Sub scopes in Icom rigs have the same caps. */ struct icom_spectrum_edge_frequency_range spectrum_edge_frequency_ranges[ICOM_MAX_SPECTRUM_FREQ_RANGES]; /*!< Icom spectrum scope edge frequencies, if supported by the rig. Last entry should have zeros in all fields. */ struct cmdparams *extcmds; /*!< Pointer to extended operations array */ int dualwatch_split; /*!< Rig supports dual watch for split ops -- e.g. ID-5100 */ int x25x26_always; /*!< Rig should use 0x25 and 0x26 commands always */ int x25x26_possibly; /*!< Rig might support 0x25 and 0x26 commands if the firmware is upgraded */ int x1cx03_always; /*!< Rig should use 0x1C 0x03 command for getting TX frequency */ int x1cx03_possibly; /*!< Rig might support 0x1C 0x03 command if the firmware is upgraded TODO: is this added by FW upgrade ever? */ int x1ax03_supported; /*!< Rig supports setting/getting filter width */ int mode_with_filter; /*!< Rig mode commands include filter selection */ int data_mode_supported; /*!< Rig supports data mode flag */ int fm_filters[3]; /*!< For models with FIL1/2/3 for FM low-to-high fixed filters -- IC7300/9700 */ }; struct icom_priv_data { unsigned char re_civ_addr; /*!< The remote equipment's CI-V address */ int civ_731_mode; /*!< Off: freqs on 10 digits, On: freqs on 8 digits */ int no_xchg; /*!< Off: use VFO XCHG to set other VFO, On: use set VFO to set other VFO */ int no_1a_03_cmd; /*!< Rig does not support setting/getting filter width */ int split_on_deprecated; /*!< @deprecated Use rig_cache.split - Record split state */ pltstate_t *pltstate; /*!< Only on optoscan */ int serial_USB_echo_off; /*!< USB is not set to echo */ /** * Icom backends track VFOs internally for use with different functions like split. * This allows queries using CURR_VFO and Main/Sub to work correctly. * * The fields in this struct are no longer used, because rig_state and rig_cache structs provide * the same functionality for all rigs globally. */ vfo_t rx_vfo_deprecated; /*!< @deprecated Use rig_state.rx_vfo */ vfo_t tx_vfo_deprecated; /*!< @deprecated Use rig_state.tx_vfo */ freq_t curr_freq_deprecated; /*!< @deprecated Use rig_cache.freqCurr - Our current freq depending on which vfo is selected */ freq_t main_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA - Track last setting of main -- not being used yet */ freq_t sub_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubA - Track last setting of sub -- not being used yet */ freq_t maina_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA */ freq_t mainb_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainB */ freq_t suba_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubA */ freq_t subb_freq_deprecated; /*!< @deprecated Use rig_cache.freqSubB */ freq_t vfoa_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainA - Track last setting of vfoa -- used to return last freq when ptt is asserted */ freq_t vfob_freq_deprecated; /*!< @deprecated Use rig_cache.freqMainB - Track last setting of vfob -- used to return last freq when ptt is asserted */ int x25cmdfails; /*!< This will get set if the 0x25 command fails so we try just once */ int x26cmdfails; /*!< This will get set if the 0x26 command fails so we try just once */ int x1cx03cmdfails; /*!< This will get set if the 0x1c 0x03 command fails so we try just once */ int poweron; /*!< To prevent powering on more than once */ unsigned char filter; /*!< Current filter selected */ unsigned char datamode; /*!< Current datamode */ int spectrum_scope_count; /*!< Number of spectrum scopes, calculated from caps */ struct icom_spectrum_scope_cache spectrum_scope_cache[HAMLIB_MAX_SPECTRUM_SCOPES]; /*!< Cached Icom spectrum scope data used during reception of the data. The array index must match the scope ID. */ freq_t other_freq_deprecated; /*!< @deprecated Use rig_cache.freqOther - Our other freq depending on which vfo is selected */ int vfo_flag; // used to skip vfo check when frequencies are equal int dual_watch_main_sub; // 0=main, 1=sub int tone_enable; /*!< Re-enable tone after freq change -- IC-705 bug with gpredict */ int filter_usbd; /*!< Filter number to use for USBD/LSBD when setting mode */ int filter_usb; /*!< Filter number to use for USB/LSB when setting mode */ int filter_cw; /*!< Filter number to use for CW/CWR when setting mode */ int filter_fm; /*!< Filter number to use for CW/CWR when setting mode */ }; extern const struct ts_sc_list r8500_ts_sc_list[]; extern const struct ts_sc_list r8600_ts_sc_list[]; extern const struct ts_sc_list ic737_ts_sc_list[]; extern const struct ts_sc_list r75_ts_sc_list[]; extern const struct ts_sc_list r7100_ts_sc_list[]; extern const struct ts_sc_list r9000_ts_sc_list[]; extern const struct ts_sc_list r9500_ts_sc_list[]; extern const struct ts_sc_list ic756_ts_sc_list[]; extern const struct ts_sc_list ic756pro_ts_sc_list[]; extern const struct ts_sc_list ic705_ts_sc_list[]; extern const struct ts_sc_list ic706_ts_sc_list[]; extern const struct ts_sc_list ic7000_ts_sc_list[]; extern const struct ts_sc_list ic7100_ts_sc_list[]; extern const struct ts_sc_list ic7200_ts_sc_list[]; extern const struct ts_sc_list ic7300_ts_sc_list[]; extern const struct ts_sc_list ic9700_ts_sc_list[]; extern const struct ts_sc_list ic910_ts_sc_list[]; extern const struct ts_sc_list ic718_ts_sc_list[]; extern const struct ts_sc_list x108g_ts_sc_list[]; extern const pbwidth_t rtty_fil[]; /* rtty filter passband width; available on 746pro and 756pro rigs */ pbwidth_t icom_get_dsp_flt(RIG *rig, rmode_t mode); int icom_init(RIG *rig); int icom_rig_open(RIG *rig); int icom_rig_close(RIG *rig); int icom_cleanup(RIG *rig); int icom_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icom_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *ts); int icom_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t ts); int icom_set_xit_new(RIG *rig, vfo_t vfo, shortfreq_t ts); int icom_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int icom_get_vfo(RIG *rig, vfo_t *vfo); int icom_set_vfo(RIG *rig, vfo_t vfo); int icom_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); int icom_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); int icom_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs); int icom_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs); int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t tx_mode, pbwidth_t tx_width); int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *tx_mode, pbwidth_t *tx_width); int icom_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo); int icom_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo); int icom_mem_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int icom_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); int icom_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); int icom_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int icom_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int icom_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int icom_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int icom_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int icom_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int icom_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int icom_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); int icom_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code); int icom_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); int icom_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); int icom_set_bank(RIG *rig, vfo_t vfo, int bank); int icom_set_mem(RIG *rig, vfo_t vfo, int ch); int icom_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int icom_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int icom_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int icom_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int icom_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int icom_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int icom_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status); int icom_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status); int icom_set_parm(RIG *rig, setting_t parm, value_t val); int icom_get_parm(RIG *rig, setting_t parm, value_t *val); int icom_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int icom_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int icom_set_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int icom_get_ext_cmd(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int icom_set_conf(RIG *rig, hamlib_token_t token, const char *val); int icom_get_conf(RIG *rig, hamlib_token_t token, char *val); int icom_set_powerstat(RIG *rig, powerstat_t status); int icom_get_powerstat(RIG *rig, powerstat_t *status); int icom_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int icom_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int icom_decode_event(RIG *rig); int icom_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); int icom_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); int icom_send_morse(RIG *rig, vfo_t vfo, const char *msg); int icom_stop_morse(RIG *rig, vfo_t vfo); int icom_send_voice_mem(RIG *rig, vfo_t vfo, int bank); int icom_stop_voice_mem(RIG *rig, vfo_t vfo); /* Exposed routines */ int icom_get_split_vfos(RIG *rig, vfo_t *rx_vfo, vfo_t *tx_vfo); int icom_set_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, int val); int icom_get_raw_buf(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *reslen, unsigned char *res); int icom_get_raw(RIG *rig, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int *val); int icom_set_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, int val_bytes, value_t val); int icom_get_level_raw(RIG *rig, setting_t level, int cmd, int subcmd, int subcmdbuflen, unsigned char *subcmdbuf, value_t *val); int icom_set_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int val_bytes, int value); int icom_get_custom_parm(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *value); int icom_set_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int seconds); int icom_get_custom_parm_time(RIG *rig, int parmbuflen, unsigned char *parmbuf, int *seconds); int icom_get_freq_range(RIG *rig); int icom_is_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame); int icom_process_async_frame(RIG *rig, size_t frame_length, const unsigned char *frame); int icom_read_frame_direct(RIG *rig, size_t buffer_length, const unsigned char *buffer); extern const struct confparams icom_cfg_params[]; extern const struct confparams icom_ext_levels[]; extern const struct confparams icom_ext_funcs[]; extern const struct confparams icom_ext_parms[]; extern const struct cmdparams icom_ext_cmds[]; extern struct rig_caps ic703_caps; extern struct rig_caps ic705_caps; extern struct rig_caps ic706_caps; extern struct rig_caps ic706mkii_caps; extern struct rig_caps ic706mkiig_caps; extern struct rig_caps ic707_caps; extern struct rig_caps ic718_caps; extern struct rig_caps ic725_caps; extern struct rig_caps ic726_caps; extern struct rig_caps ic728_caps; extern struct rig_caps ic729_caps; extern struct rig_caps ic735_caps; extern struct rig_caps ic736_caps; extern struct rig_caps ic737_caps; extern struct rig_caps ic738_caps; extern struct rig_caps ic746_caps; extern struct rig_caps ic7410_caps; extern struct rig_caps ic746pro_caps; extern struct rig_caps ic756_caps; extern struct rig_caps ic756pro_caps; extern struct rig_caps ic756pro2_caps; extern struct rig_caps ic756pro3_caps; extern struct rig_caps ic751_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 struct rig_caps ic761_caps; extern struct rig_caps ic765_caps; extern struct rig_caps ic7700_caps; extern struct rig_caps ic775_caps; extern struct rig_caps ic78_caps; extern struct rig_caps ic7800_caps; extern struct rig_caps ic785x_caps; extern struct rig_caps ic7000_caps; extern struct rig_caps ic7100_caps; extern struct rig_caps ic7200_caps; extern struct rig_caps ic7300_caps; extern struct rig_caps ic781_caps; extern struct rig_caps ic820h_caps; extern struct rig_caps ic821h_caps; extern struct rig_caps ic905_caps; extern struct rig_caps ic910_caps; extern struct rig_caps ic9100_caps; extern struct rig_caps ic970_caps; extern struct rig_caps ic9700_caps; extern struct rig_caps icrx7_caps; extern struct rig_caps icr10_caps; extern struct rig_caps icr20_caps; extern struct rig_caps icr6_caps; extern struct rig_caps icr71_caps; extern struct rig_caps icr72_caps; extern struct rig_caps icr75_caps; extern struct rig_caps icr7000_caps; extern struct rig_caps icr7100_caps; extern struct rig_caps icr8500_caps; extern struct rig_caps icr9000_caps; extern struct rig_caps icr9500_caps; extern struct rig_caps ic271_caps; extern struct rig_caps ic275_caps; extern struct rig_caps ic375_caps; extern struct rig_caps ic471_caps; extern struct rig_caps ic475_caps; extern struct rig_caps ic575_caps; extern struct rig_caps ic1275_caps; extern struct rig_caps icf8101_caps; extern struct rig_caps ic7760_caps; extern struct rig_caps omnivip_caps; extern struct rig_caps delta2_caps; extern struct rig_caps os456_caps; extern struct rig_caps os535_caps; extern struct rig_caps ic92d_caps; extern struct rig_caps id1_caps; extern struct rig_caps id31_caps; extern struct rig_caps id51_caps; extern struct rig_caps id4100_caps; extern struct rig_caps id5100_caps; extern struct rig_caps ic2730_caps; extern struct rig_caps perseus_caps; extern struct rig_caps x108g_caps; extern struct rig_caps x6100_caps; extern struct rig_caps g90_caps; extern struct rig_caps x5105_caps; extern struct rig_caps x6200_caps; extern struct rig_caps icr8600_caps; extern struct rig_caps icr30_caps; #define RIG_IS_IC1271 (STATE(rig)->rig_model == RIG_MODEL_IC1271) #define RIG_IS_IC1275 (STATE(rig)->rig_model == RIG_MODEL_IC1275) #define RIG_IS_IC271 (STATE(rig)->rig_model == RIG_MODEL_IC271) #define RIG_IS_IC2730 (STATE(rig)->rig_model == RIG_MODEL_IC2730) #define RIG_IS_IC275 (STATE(rig)->rig_model == RIG_MODEL_IC275) #define RIG_IS_IC375 (STATE(rig)->rig_model == RIG_MODEL_IC375) #define RIG_IS_IC471 (STATE(rig)->rig_model == RIG_MODEL_IC471) #define RIG_IS_IC475 (STATE(rig)->rig_model == RIG_MODEL_IC475) #define RIG_IS_IC575 (STATE(rig)->rig_model == RIG_MODEL_IC575) #define RIG_IS_IC7000 (STATE(rig)->rig_model == RIG_MODEL_IC7000) #define RIG_IS_IC703 (STATE(rig)->rig_model == RIG_MODEL_IC703) #define RIG_IS_IC705 (STATE(rig)->rig_model == RIG_MODEL_IC705) #define RIG_IS_IC706 (STATE(rig)->rig_model == RIG_MODEL_IC706) #define RIG_IS_IC706MKII (STATE(rig)->rig_model == RIG_MODEL_IC706MKII) #define RIG_IS_IC706MKIIG (STATE(rig)->rig_model == RIG_MODEL_IC706MKIIG) #define RIG_IS_IC707 (STATE(rig)->rig_model == RIG_MODEL_IC707) #define RIG_IS_IC7100 (STATE(rig)->rig_model == RIG_MODEL_IC7100) #define RIG_IS_IC718 (STATE(rig)->rig_model == RIG_MODEL_IC718) #define RIG_IS_IC7200 (STATE(rig)->rig_model == RIG_MODEL_IC7200) #define RIG_IS_IC725 (STATE(rig)->rig_model == RIG_MODEL_IC725) #define RIG_IS_IC726 (STATE(rig)->rig_model == RIG_MODEL_IC726) #define RIG_IS_IC728 (STATE(rig)->rig_model == RIG_MODEL_IC728) #define RIG_IS_IC729 (STATE(rig)->rig_model == RIG_MODEL_IC729) #define RIG_IS_IC7300 (STATE(rig)->rig_model == RIG_MODEL_IC7300) #define RIG_IS_IC731 (STATE(rig)->rig_model == RIG_MODEL_IC731) #define RIG_IS_IC735 (STATE(rig)->rig_model == RIG_MODEL_IC735) #define RIG_IS_IC736 (STATE(rig)->rig_model == RIG_MODEL_IC736) #define RIG_IS_IC737 (STATE(rig)->rig_model == RIG_MODEL_IC737) #define RIG_IS_IC738 (STATE(rig)->rig_model == RIG_MODEL_IC738) #define RIG_IS_IC7410 (STATE(rig)->rig_model == RIG_MODEL_IC7410) #define RIG_IS_IC746 (STATE(rig)->rig_model == RIG_MODEL_IC746) #define RIG_IS_IC746PRO (STATE(rig)->rig_model == RIG_MODEL_IC746PRO) #define RIG_IS_IC751 (STATE(rig)->rig_model == RIG_MODEL_IC751) #define RIG_IS_IC751A (STATE(rig)->rig_model == RIG_MODEL_IC751A) #define RIG_IS_IC756 (STATE(rig)->rig_model == RIG_MODEL_IC756) #define RIG_IS_IC756PRO (STATE(rig)->rig_model == RIG_MODEL_IC756PRO) #define RIG_IS_IC756PROII (STATE(rig)->rig_model == RIG_MODEL_IC756PROII) #define RIG_IS_IC756PROIII (STATE(rig)->rig_model == RIG_MODEL_IC756PROIII) #define RIG_IS_IC7600 (STATE(rig)->rig_model == RIG_MODEL_IC7600) #define RIG_IS_IC761 (STATE(rig)->rig_model == RIG_MODEL_IC761) #define RIG_IS_IC7610 (STATE(rig)->rig_model == RIG_MODEL_IC7610) #define RIG_IS_IC765 (STATE(rig)->rig_model == RIG_MODEL_IC765) #define RIG_IS_IC7700 (STATE(rig)->rig_model == RIG_MODEL_IC7700) #define RIG_IS_IC775 (STATE(rig)->rig_model == RIG_MODEL_IC775) #define RIG_IS_IC78 (STATE(rig)->rig_model == RIG_MODEL_IC78) #define RIG_IS_IC7800 (STATE(rig)->rig_model == RIG_MODEL_IC7800) #define RIG_IS_IC781 (STATE(rig)->rig_model == RIG_MODEL_IC781) #define RIG_IS_IC785X (STATE(rig)->rig_model == RIG_MODEL_IC785x) #define RIG_IS_IC820 (STATE(rig)->rig_model == RIG_MODEL_IC820) #define RIG_IS_IC821 (STATE(rig)->rig_model == RIG_MODEL_IC821) #define RIG_IS_IC821H (STATE(rig)->rig_model == RIG_MODEL_IC821H) #define RIG_IS_IC905 (STATE(rig)->rig_model == RIG_MODEL_IC905) #define RIG_IS_IC910 (STATE(rig)->rig_model == RIG_MODEL_IC910) #define RIG_IS_IC9100 (STATE(rig)->rig_model == RIG_MODEL_IC9100) #define RIG_IS_IC92D (STATE(rig)->rig_model == RIG_MODEL_IC92D) #define RIG_IS_IC970 (STATE(rig)->rig_model == RIG_MODEL_IC970) #define RIG_IS_IC9700 (STATE(rig)->rig_model == RIG_MODEL_IC9700) #define RIG_IS_IC8101 (STATE(rig)->rig_model == RIG_MODEL_ICF8101) #define RIG_IS_ICID1 (STATE(rig)->rig_model == RIG_MODEL_ICID1) #define RIG_IS_ICM700PRO (STATE(rig)->rig_model == RIG_MODEL_IC_M700PRO) #define RIG_IS_ICM710 (STATE(rig)->rig_model == RIG_MODEL_IC_M710) #define RIG_IS_ICM802 (STATE(rig)->rig_model == RIG_MODEL_IC_M802) #define RIG_IS_ICM803 (STATE(rig)->rig_model == RIG_MODEL_IC_M803) #define RIG_IS_ICR10 (STATE(rig)->rig_model == RIG_MODEL_ICR10) #define RIG_IS_ICR20 (STATE(rig)->rig_model == RIG_MODEL_ICR20) #define RIG_IS_ICR30 (STATE(rig)->rig_model == RIG_MODEL_ICR30) #define RIG_IS_ICR6 (STATE(rig)->rig_model == RIG_MODEL_ICR6) #define RIG_IS_ICR7000 (STATE(rig)->rig_model == RIG_MODEL_ICR7000) #define RIG_IS_ICR71 (STATE(rig)->rig_model == RIG_MODEL_ICR71) #define RIG_IS_ICR7100 (STATE(rig)->rig_model == RIG_MODEL_ICR7100) #define RIG_IS_ICR72 (STATE(rig)->rig_model == RIG_MODEL_ICR72) #define RIG_IS_ICR75 (STATE(rig)->rig_model == RIG_MODEL_ICR75) #define RIG_IS_ICR8500 (STATE(rig)->rig_model == RIG_MODEL_ICR8500) #define RIG_IS_ICR8600 (STATE(rig)->rig_model == RIG_MODEL_ICR8600) #define RIG_IS_ICR9000 (STATE(rig)->rig_model == RIG_MODEL_ICR9000) #define RIG_IS_ICR9500 (STATE(rig)->rig_model == RIG_MODEL_ICR9500) #define RIG_IS_ICRX7 (STATE(rig)->rig_model == RIG_MODEL_ICRX7) #define RIG_IS_ID5100 (STATE(rig)->rig_model == RIG_MODEL_ID5100) #define RIG_IS_OMNIVIP (STATE(rig)->rig_model == RIG_MODEL_OMNIVIP) #define RIG_IS_OS456 (STATE(rig)->rig_model == RIG_MODEL_OS456) #define RIG_IS_X5105 (STATE(rig)->rig_model == RIG_MODEL_X5105) #define RIG_IS_X6100 (STATE(rig)->rig_model == RIG_MODEL_X6100) #endif /* _ICOM_H */ hamlib-4.6.2/rigs/icom/ic7610.c0000644000175000017500000005237314752216205012666 00000000000000/* * Hamlib CI-V backend - description of IC-7610 * Stolen from IC7610.c by Michael Black W9MDB * Copyright (c) 2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #define IC7610_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM) #define IC7610_1HZ_TS_MODES IC7610_ALL_RX_MODES #define IC7610_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define IC7610_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7610_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|RIG_FUNC_DUAL_WATCH|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_OVF_STATUS) #define IC7610_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_AGC_TIME) #define IC7610_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) #define IC7610_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP) #define IC7610_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7610_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7610_ANTS (RIG_ANT_1|RIG_ANT_2) /* * Measurement by Roeland, PA3MET */ #define IC7610_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 11, -48 }, \ { 21, -42 }, \ { 34, -36 }, \ { 50, -30 }, \ { 59, -24 }, \ { 75, -18 }, \ { 93, -12 }, \ { 103, -6 }, \ { 124, 0 }, /* S9 */ \ { 145, 10 }, \ { 160, 20 }, \ { 183, 30 }, \ { 204, 40 }, \ { 222, 50 }, \ { 246, 60 } /* S9+60dB */ \ } } #define IC7610_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7610_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7610_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7610_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7610_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 10.0f }, \ { 211, 16.0f } \ } } #define IC7610_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 77, 10.0f }, \ { 165, 20.0f }, \ { 241, 30.0f } \ } } struct cmdparams ic7610_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x24}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x41}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x59}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x92}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x12}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x70}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x82}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x31}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7610_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_SCOPE_MSS, TOK_SCOPE_SDS, TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_SCOPE_RBW, TOK_SCOPE_MKP, TOK_IPP_FUNC, TOK_TX_INHIBIT_FUNC, TOK_DPP_FUNC, TOK_ICPW2_FUNC, TOK_BACKEND_NONE }; /* * IC-7610 rig capabilities. */ static const struct icom_priv_caps ic7610_priv_caps = { 0x98, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 2, .ant_count = 2, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 689, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 200, .signal_strength_min = -100, .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic7610_extcmds, .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7610_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x58; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x62; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7610_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x58; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x62; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } struct rig_caps ic7610_caps = { RIG_MODEL(RIG_MODEL_IC7610), .model_name = "IC-7610", .mfg_name = "Icom", .version = BACKEND_VER ".15", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7610_FUNCS, .has_set_func = IC7610_FUNCS, .has_get_level = IC7610_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7610_LEVELS), .has_get_parm = IC7610_PARMS, .has_set_parm = RIG_PARM_SET(IC7610_PARMS), /* FIXME: parms */ .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -30.0f}, .max = {.f = 10.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic7610_ext_tokens, .extfuncs = icom_ext_funcs, .extlevels = icom_ext_levels, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 12, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .vfo_ops = IC7610_VFO_OPS, .scan_ops = IC7610_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7610_ALL_RX_MODES, -1, -1, IC7610_VFOS, IC7610_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_6m(1, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_HF(1, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7610_ALL_RX_MODES, -1, -1, IC7610_VFOS, IC7610_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_6m(2, IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS), FRQ_RNG_HF(2, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7610_AM_TX_MODES, W(1), W(30), IC7610_VFOS, IC7610_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7610_OTHER_TX_MODES, W(2), W(100), IC7610_VFOS, IC7610_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7610_1HZ_TS_MODES, 1}, {IC7610_ALL_RX_MODES, Hz(100)}, {IC7610_ALL_RX_MODES, kHz(1)}, {IC7610_ALL_RX_MODES, kHz(5)}, {IC7610_ALL_RX_MODES, kHz(9)}, {IC7610_ALL_RX_MODES, kHz(10)}, {IC7610_ALL_RX_MODES, kHz(12.5)}, {IC7610_ALL_RX_MODES, kHz(20)}, {IC7610_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7610_STR_CAL, .swr_cal = IC7610_SWR_CAL, .alc_cal = IC7610_ALC_CAL, .rfpower_meter_cal = IC7610_RFPOWER_METER_CAL, .comp_meter_cal = IC7610_COMP_METER_CAL, .vd_meter_cal = IC7610_VD_METER_CAL, .id_meter_cal = IC7610_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7610_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .set_clock = ic7610_set_clock, .get_clock = ic7610_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic7300.c0000644000175000017500000024661114752216205012662 00000000000000/* * Hamlib CI-V backend - description of IC-7300 and variations * Adapted by J.Watson from IC-7000 code (c) 2004 by Stephane Fillod * Adapted from IC-7200 (c) 2016 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "token.h" #include "frame.h" #include "icom.h" #include "icom_defs.h" #include "misc.h" #include "bandplan.h" #include "tones.h" #include "ic7300.h" static int ic7300_set_parm(RIG *rig, setting_t parm, value_t val); static int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val); int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int ic9700_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int ic9700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int ic9700_set_vfo(RIG *rig, vfo_t vfo); #define IC7300_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM) #define IC7300_1HZ_TS_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM) #define IC7300_NOT_TS_MODES (IC7300_ALL_RX_MODES &~IC7300_1HZ_TS_MODES) #define IC7300_OTHER_TX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define IC7300_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7300_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_SCOPE|RIG_FUNC_TUNER|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_SEND_MORSE|RIG_FUNC_SEND_VOICE_MEM|RIG_FUNC_OVF_STATUS) #define IC7300_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_USB_AF|RIG_LEVEL_AGC_TIME) #define IC7300_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) // RIG_PARM_BANDSELECT disabled until Icom can describe the return from 0x1a 0x01 //#define IC7300_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_BANDSELECT) #define IC7300_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_SCREENSAVER|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_KEYERTYPE|RIG_PARM_AFIF) #define IC7300_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7300_SCAN_OPS (RIG_SCAN_STOP|RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT|RIG_SCAN_VFO) #define IC7300_ANTS (RIG_ANT_1) /* ant-1 is Hf-6m */ /* * IC-7300 S-meter levels measured from live signals on multiple bands. Provides a good approximation. */ #define IC7300_STR_CAL { 7, \ { \ { 0, -54 }, \ { 10, -48 }, \ { 30, -36 }, \ { 60, -24 }, \ { 90, -12 }, \ { 120, 0 }, \ { 241, 64 } \ } } #define IC7300_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7300_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7300_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7300_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7300_VD_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 13, 10.0f }, \ { 241, 16.0f } \ } } #define IC7300_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 146, 15.0f }, \ { 241, 25.0f } \ } } /* * IC905 items that differ from IC7300 */ #define IC905_VFO_OPS (RIG_OP_CPY|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) /* * IC705 items that differ from IC7300 */ #define IC705_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_SCREENSAVER|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_KEYERTYPE|RIG_PARM_AFIF|RIG_PARM_AFIF_WLAN) #define IC705_ALL_TX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR) #define IC705_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM|RIG_MODE_DSTAR) #define IC705_OTHER_TX_MODES (RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR) #define IC705_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH) #define IC705_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 0.50f }, \ { 43, 1.00f }, \ { 65, 1.50f }, \ { 83, 2.00f }, \ { 95, 2.50f }, \ { 105, 3.00f }, \ { 114, 3.50f }, \ { 124, 4.00f }, \ { 143, 5.00f }, \ { 183, 7.50f }, \ { 213, 10.0f }, \ { 255, 12.0f } \ } } /* * IC9700 items that differ from IC7300 */ #define IC9700_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM|RIG_VFO_MAIN_A|RIG_VFO_MAIN_B|RIG_VFO_SUB_A|RIG_VFO_SUB_B) // RIG_PARM_BANDSELECT disabled until Icom can describe the return from 0x1a 0x01 //#define IC9700_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_SCREENSAVER|RIG_PARM_BANDSELECT) #define IC9700_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_TIME|RIG_PARM_BEEP|RIG_PARM_SCREENSAVER|RIG_PARM_KEYERTYPE|RIG_PARM_AFIF|RIG_PARM_AFIF_LAN|RIG_PARM_AFIF_ACC) #define IC9700_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_SCOPE|RIG_FUNC_SATMODE|RIG_FUNC_DUAL_WATCH|RIG_FUNC_AFC|RIG_FUNC_TRANSCEIVE|RIG_FUNC_SPECTRUM|RIG_FUNC_SPECTRUM_HOLD|RIG_FUNC_SEND_MORSE|RIG_FUNC_SEND_VOICE_MEM|RIG_FUNC_OVF_STATUS) #define IC9700_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_SPECTRUM_MODE|RIG_LEVEL_SPECTRUM_SPAN|RIG_LEVEL_SPECTRUM_SPEED|RIG_LEVEL_SPECTRUM_REF|RIG_LEVEL_SPECTRUM_AVG|RIG_LEVEL_SPECTRUM_EDGE_LOW|RIG_LEVEL_SPECTRUM_EDGE_HIGH|RIG_LEVEL_USB_AF|RIG_LEVEL_AGC_TIME) #define IC9700_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define IC9700_SCAN_OPS (RIG_SCAN_STOP|RIG_SCAN_MEM|RIG_SCAN_PROG|RIG_SCAN_SLCT) #define IC9700_ALL_TX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR|RIG_MODE_DD) #define IC9700_ALL_RX_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_DSTAR|RIG_MODE_DD) #define IC9700_STR_CAL { 7, \ { \ { 0, -54 }, \ { 10, -48 }, \ { 30, -36 }, \ { 60, -24 }, \ { 90, -12 }, \ { 120, 0 }, \ { 241, 64 } \ } } #define IC9700_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC9700_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC9700_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC9700_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 210, 25.5f } \ } } #define IC9700_VD_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 13, 10.0f }, \ { 241, 16.0f } \ } } #define IC9700_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 121, 10.0f }, \ { 241, 20.0f } \ } } struct cmdparams ic7300_extcmds[] = { { {.s = RIG_PARM_ANN}, CMD_PARAM_TYPE_PARM, C_CTL_ANN, 0, SC_MOD_WR, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x23}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x81}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_SCREENSAVER}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x89}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x95}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_AFIF}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x59}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x59}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x71}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x02}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x60}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_BANDSELECT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_BAND_REG, SC_MOD_RW, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x64}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; struct cmdparams ic9700_extcmds[] = { { {.s = RIG_PARM_ANN}, CMD_PARAM_TYPE_PARM, C_CTL_ANN, 0, SC_MOD_WR, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x29}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x52}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_SCREENSAVER}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x67}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x80}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_AFIF}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x05}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_AFIF_ACC}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x00}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_AFIF_LAN}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x10}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x03, 0x30}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x27}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x92}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x06}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x27}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; struct cmdparams ic705_extcmds[] = { { {.s = RIG_PARM_ANN}, CMD_PARAM_TYPE_PARM, C_CTL_ANN, 0, SC_MOD_WR, 0, {0x00}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x31}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x36}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_SCREENSAVER}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x38}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x66}, CMD_DAT_TIM, 2 }, { {.s = RIG_PARM_AFIF}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x09}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_AFIF_WLAN}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x14}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x03, 0x59}, CMD_DAT_INT, 1 }, { {.s = RIG_FUNC_TRANSCEIVE}, CMD_PARAM_TYPE_FUNC, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x31}, CMD_DAT_BOL, 1 }, { {.s = RIG_LEVEL_SPECTRUM_AVG}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x78}, CMD_DAT_INT, 1 }, { {.s = RIG_LEVEL_USB_AF}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x13}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYERTYPE}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x02, 0x55}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; int ic7300_ext_tokens[] = { TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_BACKEND_NONE, }; int ic9700_ext_tokens[] = { TOK_SCOPE_MSS, TOK_SCOPE_SDS, TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_SCOPE_MKP, TOK_BACKEND_NONE, }; int ic705_ext_tokens[] = { TOK_SCOPE_STX, TOK_SCOPE_CFQ, TOK_SCOPE_EDG, TOK_SCOPE_VBW, TOK_BACKEND_NONE, }; /* * IC-7300 rig capabilities. */ static const struct icom_priv_caps IC7300_priv_caps = { 0x94, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic7300_ts_sc_list, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, // note this is handled by AGC time constant instead { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic7300_extcmds, /* Custom op parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1, .fm_filters = { 7000, 10000, 15000 } }; static const struct icom_priv_caps IC9700_priv_caps = { 0xA2, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic9700_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, // note this is handled by AGC time constant instead { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 144000000, .high_freq = 148000000, }, { .range_id = 2, .low_freq = 430000000, .high_freq = 450000000, }, { .range_id = 3, .low_freq = 1240000000, .high_freq = 1300000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic9700_extcmds, /* Custom op parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1, }; static const struct icom_priv_caps IC705_priv_caps = { 0xA4, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic705_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 14, .low_freq = 74800000, .high_freq = 108000000, }, { .range_id = 15, .low_freq = 108000000, .high_freq = 137000000, }, { .range_id = 16, .low_freq = 137000000, .high_freq = 200000000, }, { .range_id = 17, .low_freq = 400000000, .high_freq = 470000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic705_extcmds, /* Custom parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; static const struct icom_priv_caps IC905_priv_caps = { 0xAC, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flickering */ ic705_ts_sc_list, .serial_USB_echo_check = 1, /* USB CI-V may not echo */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .spectrum_scope_caps = { .spectrum_line_length = 475, .single_frame_data_length = 50, .data_level_min = 0, .data_level_max = 160, .signal_strength_min = -80, // TODO: signal strength to be confirmed .signal_strength_max = 0, }, .spectrum_edge_frequency_ranges = { { .range_id = 1, .low_freq = 30000, .high_freq = 1600000, }, { .range_id = 2, .low_freq = 1600000, .high_freq = 2000000, }, { .range_id = 3, .low_freq = 2000000, .high_freq = 6000000, }, { .range_id = 4, .low_freq = 6000000, .high_freq = 8000000, }, { .range_id = 5, .low_freq = 8000000, .high_freq = 11000000, }, { .range_id = 6, .low_freq = 11000000, .high_freq = 15000000, }, { .range_id = 7, .low_freq = 15000000, .high_freq = 20000000, }, { .range_id = 8, .low_freq = 20000000, .high_freq = 22000000, }, { .range_id = 9, .low_freq = 22000000, .high_freq = 26000000, }, { .range_id = 10, .low_freq = 26000000, .high_freq = 30000000, }, { .range_id = 11, .low_freq = 30000000, .high_freq = 45000000, }, { .range_id = 12, .low_freq = 45000000, .high_freq = 60000000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 13, .low_freq = 60000000, .high_freq = 74800000, }, { .range_id = 14, .low_freq = 74800000, .high_freq = 108000000, }, { .range_id = 15, .low_freq = 108000000, .high_freq = 137000000, }, { .range_id = 16, .low_freq = 137000000, .high_freq = 200000000, }, { .range_id = 17, .low_freq = 400000000, .high_freq = 470000000, }, { .range_id = 0, .low_freq = 0, .high_freq = 0, }, }, .extcmds = ic705_extcmds, /* Custom parameters */ .x25x26_always = 1, .x25x26_possibly = 1, .x1cx03_always = 1, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; struct rig_caps ic7300_caps = { RIG_MODEL(RIG_MODEL_IC7300), .model_name = "IC-7300", .mfg_name = "Icom", .version = BACKEND_VER ".14", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7300_FUNCS, .has_set_func = IC7300_FUNCS, .has_get_level = IC7300_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7300_LEVELS), .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC7300_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic7300_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7300_VFO_OPS, .scan_ops = IC7300_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 1, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(74.8), IC7300_ALL_RX_MODES, -1, -1, IC7300_VFOS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7300_OTHER_TX_MODES, W(2), W(100), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_60m(1, IC7300_OTHER_TX_MODES, W(2), W(100), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_6m(1, IC7300_OTHER_TX_MODES, W(2), W(100), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_4m(1, IC7300_OTHER_TX_MODES, W(2), W(50), IC7300_VFOS, RIG_ANT_1), FRQ_RNG_HF(1, IC7300_AM_TX_MODES, W(1), W(25), IC7300_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_60m(1, IC7300_AM_TX_MODES, W(1), W(25), IC7300_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_6m(1, IC7300_AM_TX_MODES, W(1), W(25), IC7300_VFOS, RIG_ANT_1), /* AM class */ FRQ_RNG_4m(1, IC7300_AM_TX_MODES, W(1), W(12.5), IC7300_VFOS, RIG_ANT_1), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC7300_ALL_RX_MODES, Hz(1)}, {IC7300_ALL_RX_MODES, kHz(1)}, {IC7300_ALL_RX_MODES, kHz(5)}, {IC7300_ALL_RX_MODES, kHz(9)}, {IC7300_ALL_RX_MODES, kHz(10)}, {IC7300_ALL_RX_MODES, kHz(12.5)}, {IC7300_ALL_RX_MODES, kHz(20)}, {IC7300_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7300_STR_CAL, .swr_cal = IC7300_SWR_CAL, .alc_cal = IC7300_ALC_CAL, .rfpower_meter_cal = IC7300_RFPOWER_METER_CAL, .comp_meter_cal = IC7300_COMP_METER_CAL, .vd_meter_cal = IC7300_VD_METER_CAL, .id_meter_cal = IC7300_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC7300_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = ic7300_set_parm, .get_parm = ic7300_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .set_clock = ic7300_set_clock, .get_clock = ic7300_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic9700_caps = { RIG_MODEL(RIG_MODEL_IC9700), .model_name = "IC-9700", .mfg_name = "Icom", .version = BACKEND_VER ".20", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC9700_FUNCS, .has_set_func = IC9700_FUNCS, .has_get_level = IC9700_LEVELS, .has_set_level = RIG_LEVEL_SET(IC9700_LEVELS), .has_get_parm = IC9700_PARMS, .has_set_parm = RIG_PARM_SET(IC9700_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic9700_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_SPECTRUM, .vfo_ops = IC9700_VFO_OPS, .scan_ops = IC9700_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 3, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, // Hopefully any future changes in bandplans can be fixed with firmware updates // So we use the global REGION2 macros in here .rx_range_list1 = { // USA Version -- United States {MHz(144), MHz(148), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(430), MHz(450), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(1240), MHz(1300), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(148), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(430), MHz(450), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(1240), MHz(1300), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(144), MHz(148), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(430), MHz(450), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "USA"}, {MHz(1240), MHz(1300), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "USA"}, RIG_FRNG_END, }, .rx_range_list2 = { // EUR Version -- Europe {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(430), MHz(440), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(1240), MHz(1300), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(430), MHz(440), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(1240), MHz(1300), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(430), MHz(440), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, {MHz(1240), MHz(1300), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "EUR"}, RIG_FRNG_END, }, .rx_range_list3 = { // ITR Version -- Italy {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(430), MHz(434), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(435), MHz(438), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1240), MHz(1245), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1270), MHz(1298), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "ITR"}, RIG_FRNG_END, }, .tx_range_list3 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(430), MHz(434), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(435), MHz(438), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1240), MHz(1245), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1270), MHz(1298), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(430), MHz(434), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(435), MHz(438), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1240), MHz(1245), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, {MHz(1270), MHz(1298), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "ITR"}, RIG_FRNG_END, }, .rx_range_list4 = { // TPE Version -- Taiwan ?? {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(430), MHz(432), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(1260), MHz(1265), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "TPE"}, RIG_FRNG_END, }, .tx_range_list4 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(430), MHz(432), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(1260), MHz(1265), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(430), MHz(432), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, {MHz(1260), MHz(1265), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "TPE"}, RIG_FRNG_END, }, .rx_range_list5 = { // KOR Version -- Republic of Korea {MHz(144), MHz(146), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(430), MHz(440), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(1260), MHz(1300), IC9700_ALL_RX_MODES, -1, -1, IC9700_VFOS, RIG_ANT_CURR, "KOR"}, RIG_FRNG_END, }, .tx_range_list5 = { {MHz(144), MHz(146), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(100), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(430), MHz(440), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.5), W(75), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(1260), MHz(1300), IC9700_ALL_TX_MODES ^ RIG_MODE_AM, W(0.1), W(10), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(144), MHz(146), RIG_MODE_AM, W(0.125), W(25), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(430), MHz(440), RIG_MODE_AM, W(0.125), W(18.75), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, {MHz(1260), MHz(1300), RIG_MODE_AM, W(0.025), W(2.5), IC9700_VFOS, RIG_ANT_CURR, "KOR"}, RIG_FRNG_END, }, .tuning_steps = { {IC9700_ALL_RX_MODES, Hz(1)}, {IC9700_ALL_RX_MODES, Hz(10)}, {IC9700_ALL_RX_MODES, Hz(100)}, {IC9700_ALL_RX_MODES, Hz(500)}, {IC9700_ALL_RX_MODES, kHz(1)}, {IC9700_ALL_RX_MODES, kHz(5)}, {IC9700_ALL_RX_MODES, kHz(6.25)}, {IC9700_ALL_RX_MODES, kHz(10)}, {IC9700_ALL_RX_MODES, kHz(12.5)}, {IC9700_ALL_RX_MODES, kHz(20)}, {IC9700_ALL_RX_MODES, kHz(25)}, {IC9700_ALL_RX_MODES, kHz(50)}, {IC9700_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, RIG_FLT_END, }, .str_cal = IC9700_STR_CAL, .swr_cal = IC9700_SWR_CAL, .alc_cal = IC9700_ALC_CAL, .rfpower_meter_cal = IC9700_RFPOWER_METER_CAL, .comp_meter_cal = IC9700_COMP_METER_CAL, .vd_meter_cal = IC9700_VD_METER_CAL, .id_meter_cal = IC9700_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = 1, .name = "Sub", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC9700_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // IC-9700 can indicate Main/Sub band selection, but not VFO A/B, so leave get_vfo not implemented // .get_vfo = icom_get_vfo, .set_vfo = ic9700_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .get_powerstat = icom_get_powerstat, .set_powerstat = icom_set_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .set_clock = ic9700_set_clock, .get_clock = ic9700_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic705_caps = { RIG_MODEL(RIG_MODEL_IC705), .model_name = "IC-705", .mfg_name = "Icom", .version = BACKEND_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7300_FUNCS, .has_set_func = IC7300_FUNCS, .has_get_level = IC705_LEVELS, .has_set_level = RIG_LEVEL_SET(IC705_LEVELS), .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC7300_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDWFM,BANDAIR,BAND70CM,BAND33CM,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, }, .ext_tokens = ic705_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7300_VFO_OPS, .scan_ops = IC7300_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(199.999999), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(400), MHz(470), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(1800), MHz(1.999999), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(3.5), MHz(3.999999), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(5.255), MHz(5.405), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(7.0), MHz(7.3), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(10.1), MHz(10.15), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(14.0), MHz(14.35), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(18.068), MHz(18.168), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(21.00), MHz(21.45), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(24.89), MHz(24.99), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(28.00), MHz(29.70), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(50.00), MHz(54.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(144.00), MHz(148.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(430.00), MHz(450.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(199.999999), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(400), MHz(470), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { { kHz(1810), MHz(1.999999), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(3.5), MHz(3.8), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(7.0), MHz(7.2), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(10.1), MHz(10.15), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(14.0), MHz(14.35), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(18.068), MHz(18.168), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(21.00), MHz(21.45), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(24.89), MHz(24.99), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(28.00), MHz(29.70), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(50.00), MHz(52.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(144.00), MHz(146.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(430.00), MHz(440.00), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, RIG_FRNG_END, }, .tuning_steps = { {IC7300_ALL_RX_MODES, Hz(100)}, {IC7300_ALL_RX_MODES, kHz(.5)}, {IC7300_ALL_RX_MODES, kHz(1)}, {IC7300_ALL_RX_MODES, kHz(5)}, {IC7300_ALL_RX_MODES, kHz(6.25)}, {IC7300_ALL_RX_MODES, kHz(8.33)}, {IC7300_ALL_RX_MODES, kHz(9)}, {IC7300_ALL_RX_MODES, kHz(10)}, {IC7300_ALL_RX_MODES, kHz(12.5)}, {IC7300_ALL_RX_MODES, kHz(20)}, {IC7300_ALL_RX_MODES, kHz(25)}, {IC7300_ALL_RX_MODES, kHz(50)}, {IC7300_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7300_STR_CAL, .swr_cal = IC7300_SWR_CAL, .alc_cal = IC7300_ALC_CAL, .rfpower_meter_cal = IC705_RFPOWER_METER_CAL, .comp_meter_cal = IC7300_COMP_METER_CAL, .vd_meter_cal = IC7300_VD_METER_CAL, .id_meter_cal = IC7300_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC705_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, // powerstat is write only .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic905_caps = { RIG_MODEL(RIG_MODEL_IC905), .model_name = "IC-905", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 230400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7300_FUNCS, .has_set_func = IC7300_FUNCS, .has_get_level = IC705_LEVELS, .has_set_level = RIG_LEVEL_SET(IC705_LEVELS), .has_get_parm = IC7300_PARMS, .has_set_parm = RIG_PARM_SET(IC705_PARMS), .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_USB_AF #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_USB_AF [LVL_KEYSPD] = {.min = {.i = 6}, .max = {.i = 48}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 300}, .max = {.i = 900}, .step = {.i = 1}}, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND70CM,BAND33CM,BAND23CM,BAND23CM,BAND13CM,BAND3CM"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_KEYERTYPE] = {.step = {.s = "STRAIGHT,BUG,PADDLE"}}, }, .ext_tokens = ic705_ext_tokens, .extlevels = icom_ext_levels, .ctcss_list = full_ctcss_list, .dcs_list = NULL, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC905_VFO_OPS, .scan_ops = IC7300_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 1, 8, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(148), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(430), MHz(450), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(1240), MHz(1300), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(2300), MHz(2309.999999), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(5650), MHz(5925), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, {MHz(10000), MHz(10500), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { { MHz(144), MHz(148), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(430), MHz(450), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(1240), MHz(1300), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(2300), MHz(2309.999999), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(2390.000001), MHz(2450), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(5650), MHz(5925), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, { MHz(10000), MHz(10500), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "USA" }, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(146), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(430), MHz(440), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(1240), MHz(1300), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(2300), MHz(2450), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(5650), MHz(5850), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "EUR"}, {MHz(10000), MHz(10500), IC705_ALL_RX_MODES, -1, -1, IC7300_VFOS, RIG_ANT_1, "USA"}, RIG_FRNG_END, }, .tx_range_list2 = { { MHz(144), MHz(148), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(430), MHz(450), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(1240), MHz(1300), IC705_ALL_TX_MODES, W(0.1), W(10), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(2300), MHz(2309.999999), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(2390), MHz(2450), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(5650), MHz(5925), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, { MHz(10000), MHz(10500), IC705_ALL_TX_MODES, W(0.1), W(2), IC7300_VFOS, RIG_ANT_1, "EUR" }, RIG_FRNG_END, }, .tuning_steps = { {IC7300_ALL_RX_MODES, Hz(100)}, {IC7300_ALL_RX_MODES, kHz(.5)}, {IC7300_ALL_RX_MODES, kHz(1)}, {IC7300_ALL_RX_MODES, kHz(5)}, {IC7300_ALL_RX_MODES, kHz(6.25)}, {IC7300_ALL_RX_MODES, kHz(8.33)}, {IC7300_ALL_RX_MODES, kHz(9)}, {IC7300_ALL_RX_MODES, kHz(10)}, {IC7300_ALL_RX_MODES, kHz(12.5)}, {IC7300_ALL_RX_MODES, kHz(20)}, {IC7300_ALL_RX_MODES, kHz(25)}, {IC7300_ALL_RX_MODES, kHz(50)}, {IC7300_ALL_RX_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! But duplication may speed up search. Put the most commonly used modes first! Remember these are defaults, with dsp rigs you can change them to anything you want except FM and WFM which are fixed */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7300_STR_CAL, .swr_cal = IC7300_SWR_CAL, .alc_cal = IC7300_ALC_CAL, .rfpower_meter_cal = IC705_RFPOWER_METER_CAL, .comp_meter_cal = IC7300_COMP_METER_CAL, .vd_meter_cal = IC7300_VD_METER_CAL, .id_meter_cal = IC7300_ID_METER_CAL, .spectrum_scopes = { { .id = 0, .name = "Main", }, { .id = -1, .name = NULL, }, }, .spectrum_modes = { RIG_SPECTRUM_MODE_CENTER, RIG_SPECTRUM_MODE_FIXED, RIG_SPECTRUM_MODE_CENTER_SCROLL, RIG_SPECTRUM_MODE_FIXED_SCROLL, RIG_SPECTRUM_MODE_NONE, }, .spectrum_spans = { 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 0, }, .spectrum_avg_modes = { { .id = 0, .name = "OFF", }, { .id = 1, .name = "2", }, { .id = 2, .name = "3", }, { .id = 3, .name = "4", }, }, .async_data_supported = 1, .read_frame_direct = icom_read_frame_direct, .is_async_frame = icom_is_async_frame, .process_async_frame = icom_process_async_frame, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& IC905_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = NULL, .get_ant = NULL, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .power2mW = icom_power2mW, .mW2power = icom_mW2power, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = icom_send_voice_mem, .stop_voice_mem = icom_stop_voice_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS, }; int ic7300_set_parm(RIG *rig, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_ANN: { int ann_mode = -1; int ann_lang = -1; switch (val.i) { case RIG_ANN_OFF: ann_mode = S_ANN_ALL; break; case RIG_ANN_FREQ: ann_mode = S_ANN_FREQ; break; case RIG_ANN_RXMODE: ann_mode = S_ANN_MODE; break; case RIG_ANN_ENG: case RIG_ANN_JAP: ann_lang = (val.i == RIG_ANN_ENG) ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } if (ann_mode >= 0) { return icom_set_raw(rig, C_CTL_ANN, ann_mode, 0, NULL, 0, 0); } else if (ann_lang >= 0) { unsigned char prmbuf[MAXFRAMELEN]; prmbuf[0] = 0x1a; prmbuf[1] = 0x05; switch (rig->caps->rig_model) { case RIG_MODEL_IC7300: prmbuf[2] = 0x00; prmbuf[3] = 0x39; break; case RIG_MODEL_IC9700: prmbuf[2] = 0x01; prmbuf[3] = 0x77; break; case RIG_MODEL_IC705: prmbuf[2] = 0x00; prmbuf[3] = 0x53; break; default: return -RIG_ENIMPL; } prmbuf[4] = ann_lang; return icom_set_raw(rig, C_CTL_MEM, S_MEM_MODE_SLCT, 5, prmbuf, 0, 0); } rig_debug(RIG_DEBUG_ERR, "Unsupported RIG_PARM_ANN %d\n", val.i); return -RIG_EINVAL; } default: return icom_set_parm(rig, parm, val); } } int ic7300_get_parm(RIG *rig, setting_t parm, value_t *val) { const unsigned char prmbuf[MAXFRAMELEN]; unsigned char resbuf[MAXFRAMELEN]; int prm_len = 0, res_len; int prm_cn = 0, prm_sc = 0; int icom_val = 0; int cmdhead; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { #if 0 case RIG_PARM_ANN: return -RIG_ENIMPL; // How can we implement this? #endif default: rig_debug(RIG_DEBUG_TRACE, "%s: using icom routine for PARM=%s\n", __func__, rig_strparm(parm)); return icom_get_parm(rig, parm, val); } retval = icom_transaction(rig, prm_cn, prm_sc, prmbuf, prm_len, resbuf, &res_len); if (retval != RIG_OK) { return retval; } cmdhead = 3; res_len -= cmdhead; if (resbuf[0] != ACK && resbuf[0] != prm_cn) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, resbuf[0], res_len); return -RIG_ERJCTED; } switch (parm) { #if 0 case RIG_PARM_ANN: rig_debug(RIG_DEBUG_WARN, "%s: not implemented\n", __func__); return -RIG_ENIMPL; #endif default: return icom_get_parm(rig, parm, val); } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %d %f\n", __func__, res_len, icom_val, val->i, val->f); return RIG_OK; } // if hour < 0 then only date will be set int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x94; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x95; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x96; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x94; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x95; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x96; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } // if hour < 0 then only date will be set int ic9700_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x79; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x80; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x01; prmbuf[1] = 0x84; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic9700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x01; prmbuf[1] = 0x79; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x01; prmbuf[1] = 0x80; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x01; prmbuf[1] = 0x84; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } int ic9700_set_vfo(RIG *rig, vfo_t vfo) { unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf); int retval; int vfo_is_main_or_sub = (vfo == RIG_VFO_MAIN) || (vfo == RIG_VFO_SUB); struct rig_cache *cachep = CACHE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (cachep->satmode && !vfo_is_main_or_sub) { // Translate VFO A/B to Main/Sub in satellite mode if (vfo == RIG_VFO_A) { vfo = RIG_VFO_MAIN; } else if (vfo == RIG_VFO_B) { vfo = RIG_VFO_SUB; } else { rig_debug(RIG_DEBUG_ERR, "%s: Invalid VFO %s in satellite mode\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } } if (vfo == RIG_VFO_A) { retval = icom_transaction(rig, C_SET_VFO, S_VFOA, NULL, 0, ackbuf, &ack_len); } else if (vfo == RIG_VFO_B) { if (cachep->satmode) { rig_debug(RIG_DEBUG_WARN, "%s: cannot switch to VFOB when in satmode\n", __func__); // we return RIG_OK anyways as this should just be a bad request RETURNFUNC(RIG_OK); } retval = icom_transaction(rig, C_SET_VFO, S_VFOB, NULL, 0, ackbuf, &ack_len); } else if (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_MAIN_A || vfo == RIG_VFO_MAIN_B) { // First switch to Main receiver retval = icom_transaction(rig, C_SET_VFO, S_MAIN, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (cachep->satmode && vfo == RIG_VFO_MAIN_B) { rig_debug(RIG_DEBUG_WARN, "%s: cannot switch to VFOB when in satmode\n", __func__); // we return RIG_OK anyways as this should just be a bad request RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_MAIN_A || vfo == RIG_VFO_MAIN_B) { int subcmd = vfo == RIG_VFO_MAIN_A ? S_VFOA : S_VFOB; retval = icom_transaction(rig, C_SET_VFO, subcmd, NULL, 0, ackbuf, &ack_len); } } else if (vfo == RIG_VFO_SUB || vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B) { // First switch to Sub receiver retval = icom_transaction(rig, C_SET_VFO, S_SUB, NULL, 0, ackbuf, &ack_len); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } if (cachep->satmode && vfo == RIG_VFO_SUB_B) { rig_debug(RIG_DEBUG_WARN, "%s: cannot switch to VFOB when in satmode\n", __func__); // we return RIG_OK anyways as this should just be a bad request RETURNFUNC(RIG_OK); } if (vfo == RIG_VFO_SUB_A || vfo == RIG_VFO_SUB_B) { HAMLIB_TRACE; int subcmd = vfo == RIG_VFO_SUB_A ? S_VFOA : S_VFOB; retval = icom_transaction(rig, C_SET_VFO, subcmd, NULL, 0, ackbuf, &ack_len); } } else if (vfo == RIG_VFO_MEM) { RETURNFUNC(icom_set_vfo(rig, vfo)); } else { // Unsupported VFO RETURNFUNC(-RIG_EINVAL); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } RETURNFUNC(retval); } hamlib-4.6.2/rigs/icom/icr10.c0000644000175000017500000001043414752216205012663 00000000000000/* * Hamlib CI-V backend - description of IC-R10 * Copyright (c) 2000-2004 by Stephane Fillod * Copyright (c) 2017 Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #define ICR10_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define ICR10_FUNC_ALL (RIG_FUNC_NONE) #define ICR10_LEVEL_ALL (RIG_LEVEL_RAWSTR) #define ICR10_VFO_ALL (RIG_VFO_A) #define ICR10_VFO_OPS (RIG_OP_NONE) #define ICR10_SCAN_OPS (RIG_SCAN_NONE) #define ICR10_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 160, 60 } /* +60 */ \ } } static struct icom_priv_caps icr10_priv_caps = { 0x52, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list /* wrong, but don't have set_ts anyway */ }; struct rig_caps icr10_caps = { RIG_MODEL(RIG_MODEL_ICR10), .model_name = "IC-R10", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR10_FUNC_ALL, .has_set_func = ICR10_FUNC_ALL, .has_get_level = ICR10_LEVEL_ALL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR10_VFO_OPS, .scan_ops = ICR10_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), GHz(1.3), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(823.9999), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, {MHz(849), MHz(868.9999), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, {MHz(894), GHz(1.3), ICR10_MODES, -1, -1, ICR10_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR10_MODES, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(4)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR10_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr10_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, /* TODO: do not pass bandwidth data */ .get_mode = icom_get_mode, .decode_event = icom_decode_event, .get_level = icom_get_level, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/id5100.c0000644000175000017500000004520514752216205012653 00000000000000/* * Hamlib CI-V backend - description of ID-5100 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "misc.h" enum { MAIN_ON_LEFT, MAIN_ON_RIGHT }; /* * Specs and protocol details comes from the chapter 13 of ID-5100_Full-Inst_Manual.pdf * * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP2" for rig control. * * TODO: * - DV mode * - GPS support * - Single/dual watch (RIG_LEVEL_BALANCE) */ #define ID5100_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_DSTAR) #define ID5100_ALL_RX_MODES (RIG_MODE_AM|ID5100_MODES) #define ID5100_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MAIN|RIG_VFO_SUB) #define ID5100_SCAN_OPS RIG_SCAN_NONE #define ID5100_VFO_OPS RIG_OP_NONE #define ID5100_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_DUAL_WATCH| \ RIG_FUNC_VOX) #define ID5100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID5100_PARM_ALL RIG_PARM_NONE int id5100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int id5100_set_vfo(RIG *rig, vfo_t vfo) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } // if user requests VFOA/B we automatically turn of dual watch mode // if user requests Main/Sub we automatically turn on dual watch mode // hopefully this is a good idea and just prevents users/clients from having set the mode themselves #if 0 if (vfo == RIG_VFO_A || vfo == RIG_VFO_B) { // and 0x25 works in this mode priv->x25cmdfails = 1; if (priv->dual_watch) { // then we need to turn off dual watch if (RIG_OK != (retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, 0))) { RETURNFUNC(retval); } priv->dual_watch = 0; } } else if (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB) { // x25 does not work in DUAL_WATCH mode priv->x25cmdfails = 1; if (priv->dual_watch == 0) { if (RIG_OK != (retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, 1))) { RETURNFUNC(retval); } priv->dual_watch = 1; } } #endif int myvfo = S_MAIN; priv->dual_watch_main_sub = MAIN_ON_LEFT; rs->current_vfo = RIG_VFO_A; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { myvfo = S_SUB; priv->dual_watch_main_sub = MAIN_ON_RIGHT; rs->current_vfo = vfo; } if (RIG_OK != (retval = icom_transaction(rig, C_SET_VFO, myvfo, NULL, 0, ackbuf, &ack_len))) { RETURNFUNC(retval); } RETURNFUNC(retval); } int id5100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int cmd = C_SET_FREQ; int subcmd = -1; unsigned char freqbuf[MAXFRAMELEN]; int freq_len = 5; int retval; struct rig_state *rs = STATE(rig); //struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; vfo_t currvfo = rs->current_vfo; if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } if (rs->dual_watch == 0 && (vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB)) { id5100_set_split_vfo(rig, RIG_VFO_SUB, 1, RIG_VFO_MAIN); } if (rs->dual_watch == 1 && (vfo == RIG_VFO_A || vfo == RIG_VFO_B)) { id5100_set_split_vfo(rig, RIG_VFO_A, 0, RIG_VFO_A); } if (vfo != currvfo) { id5100_set_vfo(rig, vfo); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); to_bcd(freqbuf, freq, freq_len * 2); retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, NULL, NULL); if (vfo != currvfo) { id5100_set_vfo(rig, currvfo); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: set_freq failed: %s\n", __func__, rigerror(retval)); return retval; } return RIG_OK; } static int id5100_get_freq2(RIG *rig, vfo_t vfo, freq_t *freq) { unsigned char freqbuf[MAXFRAMELEN]; int freq_len = 5; int retval; int freqbuf_offset = 1; int cmd = 0x03; int subcmd = -1; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); retval = icom_transaction(rig, cmd, subcmd, NULL, 0, freqbuf, &freq_len); if (retval != RIG_OK) { return -retval; } *freq = from_bcd(freqbuf + freqbuf_offset, freq_len * 2); return RIG_OK; } int id5100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; int retval; vfo_t currvfo = rs->current_vfo; if (rs->dual_watch == 1 && rs->current_vfo != RIG_VFO_SUB) { id5100_set_split_vfo(rig, RIG_VFO_SUB, 0, RIG_VFO_MAIN); } if (rs->dual_watch) // dual watch is different { rig_debug(RIG_DEBUG_VERBOSE, "%s: Dual watch is on\n", __func__); if (priv->dual_watch_main_sub == MAIN_ON_LEFT || currvfo == RIG_VFO_A) // Then Main is on left { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Main on left\n", __func__, __LINE__); if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { rig_debug(RIG_DEBUG_ERR, "%s: Method#1\n", __func__); id5100_set_vfo(rig, RIG_VFO_A); retval = id5100_get_freq2(rig, vfo, freq); id5100_set_vfo(rig, RIG_VFO_B); return retval; } else // Sub read -- don't need to do anything as it's on the left side { rig_debug(RIG_DEBUG_ERR, "%s: Method#2\n", __func__); retval = id5100_get_freq2(rig, vfo, freq); return retval; } } else // { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Sub on left\n", __func__, __LINE__); if ((currvfo == RIG_VFO_B || currvfo == RIG_VFO_SUB) && (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB)) { rig_debug(RIG_DEBUG_ERR, "%s: Method#3\n", __func__); id5100_set_vfo(rig, RIG_VFO_MAIN); retval = id5100_get_freq2(rig, vfo, freq); id5100_set_vfo(rig, RIG_VFO_SUB); return retval; } else { rig_debug(RIG_DEBUG_ERR, "%s: Method#4\n", __func__); retval = id5100_get_freq2(rig, vfo, freq); return retval; } } } else // not dual watch { if (currvfo != vfo) { id5100_set_vfo(rig, vfo); } retval = id5100_get_freq2(rig, vfo, freq); if (currvfo != vfo) { id5100_set_vfo(rig, currvfo); } return retval; } #if 0 else if ((vfo == RIG_VFOvfo == RIG_VFO_SUB && rs->dual_watch_main_sub == MAIN_ON_RIGHT) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Sub/A vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); *freq = CACHE(rig)->freqSubA; int cache_ms_freq, cache_ms_mode, cache_ms_width; pbwidth_t width; freq_t tfreq; rmode_t mode; retval = rig_get_cache(rig, RIG_VFO_SUB, &tfreq, &cache_ms_freq, &mode, &cache_ms_mode, } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: Dual watch is off\n", __func__); } if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } if (vfo == RIG_VFO_MAIN && priv->dual_watch_main_sub == MAIN_ON_LEFT) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Main/A vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); } if (priv->dual_watch_main_sub == MAIN_ON_LEFT || currvfo == RIG_VFO_A || currvfo == RIG_VFO_MAIN) // Then Main is on left { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Main on left\n", __func__, __LINE__); if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { return id5100_get_freq2(rig, vfo, freq); } else { id5100_set_vfo(rig, RIG_VFO_B); hl_usleep(50 * 1000); retval = id5100_get_freq2(rig, vfo, freq); id5100_set_vfo(rig, RIG_VFO_A); return retval; } } else // MAIN_ON_RIGHT { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Sub on left\n", __func__, __LINE__); if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { if (rs->dual_watch) { id5100_set_vfo(rig, RIG_VFO_A); } id5100_get_freq2(rig, vfo, freq); if (rs->dual_watch) { id5100_set_vfo(rig, RIG_VFO_B); } } else { retval = id5100_get_freq2(rig, vfo, freq); return retval; } } #endif return RIG_OK; } /* * FIXME: real measurement */ #define ID5100_STR_CAL UNKNOWN_IC_STR_CAL int id5100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; unsigned char modebuf; unsigned char ackbuf[MAXFRAMELEN]; int icmode = 2; int ack_len = sizeof(ackbuf); switch (mode) { case RIG_MODE_AM: icmode = 2; modebuf = 1; break; case RIG_MODE_AMN: icmode = 2; modebuf = 2; break; case RIG_MODE_FM: icmode = 5; modebuf = 1; break; case RIG_MODE_FMN: icmode = 5; modebuf = 2; break; case RIG_MODE_DSTAR: icmode = 0x17; modebuf = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode=%s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: mode=%d, modebuf=%c\n", __func__, icmode, modebuf); retval = icom_transaction(rig, C_SET_MODE, icmode, &modebuf, 1, ackbuf, &ack_len); return retval; } int id5100_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int mode_len; unsigned char modebuf[4]; retval = icom_transaction(rig, C_RD_MODE, -1, NULL, 0, modebuf, &mode_len); if (retval != RIG_OK) { return retval; } switch (modebuf[1]) { case 2: *mode = modebuf[2] == 1 ? RIG_MODE_AM : RIG_MODE_AMN; *width = modebuf[2] == 1 ? 12000 : 6000; break; case 5: *mode = modebuf[2] == 1 ? RIG_MODE_FM : RIG_MODE_FMN; *width = modebuf[2] == 1 ? 10000 : 5000; break; case 0x17: *mode = RIG_MODE_DSTAR; *width = 6000; break; } return RIG_OK; } int id5100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct rig_state *rs = STATE(rig); struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); if (tx_vfo != RIG_VFO_MAIN) { rig_debug(RIG_DEBUG_ERR, "%s Split VFO must be Main\n", __func__); return -RIG_EINVAL; } if (rs->dual_watch == 0 || split == RIG_SPLIT_OFF) { if (RIG_OK != (retval = icom_set_func(rig, RIG_VFO_CURR, RIG_FUNC_DUAL_WATCH, split))) { RETURNFUNC2(retval); } rs->dual_watch = split; // if (split == RIG_SPLIT_OFF) { rig_set_vfo(rig, RIG_VFO_A); } return RIG_OK; } priv->dual_watch_main_sub = MAIN_ON_LEFT; // ID5100 puts tx on Main and rx on Left side // So we put Main on right side to match gpredict positions // we must set RX vfo to SUB retval = id5100_set_vfo(rig, RIG_VFO_SUB); rs->current_vfo = RIG_VFO_SUB; priv->dual_watch_main_sub = MAIN_ON_RIGHT; return retval; } int id5100_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int freq_len = 5; int retval; int cmd; int subcmd; unsigned char freqbuf[MAXFRAMELEN]; ENTERFUNC; to_bcd(freqbuf, tx_freq, freq_len * 2); cmd = 0x0; subcmd = -1; // Main is always TX retval = icom_transaction(rig, cmd, subcmd, freqbuf, freq_len, NULL, NULL); RETURNFUNC(retval); } int id5100_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; //struct rig_state *rs = STATE(rig); //struct icom_priv_data *priv = (struct icom_priv_data *) rs->priv; //vfo_t currvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): vfo=%s\n", __func__, __LINE__, rig_strvfo(vfo)); #if 0 currvfo = rs->current_vfo; if (priv->dual_watch_main_sub == MAIN_ON_LEFT && (currvfo == RIG_VFO_MAIN || currvfo == RIG_VFO_A) && vfo == RIG_VFO_TX) { rig_set_vfo(rig, RIG_VFO_SUB); retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq); rig_set_vfo(rig, RIG_VFO_MAIN); } else #endif { retval = rig_get_freq(rig, RIG_VFO_CURR, tx_freq); } return retval; } /* */ static struct icom_priv_caps id5100_priv_caps = { 0x8C, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ .dualwatch_split = 1 }; struct rig_caps id5100_caps = { RIG_MODEL(RIG_MODEL_ID5100), .model_name = "ID-5100", .mfg_name = "Icom", .version = BACKEND_VER ".9", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = ID5100_FUNC_ALL, .has_set_func = ID5100_FUNC_ALL, .has_get_level = ID5100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID5100_LEVEL_ALL), .has_get_parm = ID5100_PARM_ALL, .has_set_parm = ID5100_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID5100_VFO_OPS, .scan_ops = ID5100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, {MHz(375), MHz(550), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), ID5100_MODES, W(5), W(25), ID5100_VFO_ALL}, {MHz(430), MHz(440), ID5100_MODES, W(5), W(25), ID5100_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, {MHz(375), MHz(550), ID5100_ALL_RX_MODES, -1, -1, ID5100_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), ID5100_MODES, W(5), W(50), ID5100_VFO_ALL}, {MHz(430), MHz(450), ID5100_MODES, W(5), W(50), ID5100_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID5100_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id5100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = id5100_set_freq, .get_freq = id5100_get_freq, .get_split_freq = id5100_get_split_freq, .set_split_freq = id5100_set_split_freq, .set_mode = id5100_set_mode, .get_mode = id5100_get_mode, .set_vfo = id5100_set_vfo, .set_split_vfo = id5100_set_split_vfo, .set_powerstat = icom_set_powerstat, //.get_powerstat = icom_get_powerstat, // ID-5100 cannot get power status .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic7100.c0000644000175000017500000004614614752216205012661 00000000000000/* * Hamlib CI-V backend - description of IC-9100 (HF/VHF/UHF All-Mode Transceiver) * Copyright (c) 2000-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "idx_builtin.h" #include "bandplan.h" #include "token.h" #include "tones.h" #include "misc.h" #define IC7100_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_CWR|\ RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTAM|RIG_MODE_PKTFM|\ RIG_MODE_DSTAR) #define IC7100_OTHER_TX_MODES ((IC7100_MODES) & ~(RIG_MODE_AM|RIG_MODE_PKTAM)) #define IC7100_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7100_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM|RIG_SCAN_SLCT|RIG_SCAN_PRIO) #define IC7100_VFO_OPS (RIG_OP_FROM_VFO| \ RIG_OP_TO_VFO| \ RIG_OP_CPY| \ RIG_OP_MCL| \ RIG_OP_XCHG| \ RIG_OP_TUNE) #define IC7100_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC| \ RIG_FUNC_VSC| \ RIG_FUNC_MN| \ RIG_FUNC_LOCK| \ RIG_FUNC_SCOPE| \ RIG_FUNC_TUNER) #define IC7100_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_IF| \ RIG_LEVEL_NR| \ RIG_LEVEL_CWPITCH| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_KEYSPD| \ RIG_LEVEL_COMP| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY| \ RIG_LEVEL_ANTIVOX| \ RIG_LEVEL_APF| \ RIG_LEVEL_AGC| \ RIG_LEVEL_PBT_IN| \ RIG_LEVEL_PBT_OUT| \ RIG_LEVEL_NOTCHF_RAW| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SWR| \ RIG_LEVEL_ALC| \ RIG_LEVEL_RFPOWER_METER| \ RIG_LEVEL_RFPOWER_METER_WATTS| \ RIG_LEVEL_COMP_METER| \ RIG_LEVEL_VD_METER| \ RIG_LEVEL_ID_METER| \ RIG_LEVEL_MONITOR_GAIN| \ RIG_LEVEL_NB | \ RIG_LEVEL_AGC_TIME) //#define IC7100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_KEYLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME|RIG_PARM_BANDSELECT) // BANDSELECT disabled unti we figure out Icom's ability #define IC7100_PARM_ALL (RIG_PARM_ANN|RIG_PARM_BACKLIGHT|RIG_PARM_KEYLIGHT|RIG_PARM_BEEP|RIG_PARM_TIME) int ic7100_tokens[] = { TOK_DSTAR_CODE, TOK_DSTAR_DSQL, TOK_DSTAR_CALL_SIGN, TOK_DSTAR_MESSAGE, TOK_DSTAR_STATUS, TOK_DSTAR_MY_CS, TOK_DSTAR_TX_CS, TOK_DSTAR_TX_MESS, TOK_BACKEND_NONE }; struct cmdparams ic7100_extcmds[] = { { {.s = RIG_PARM_BEEP}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x00, 0x03}, CMD_DAT_BOL, 1 }, { {.s = RIG_PARM_BACKLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x04}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_KEYLIGHT}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x05}, CMD_DAT_LVL, 2 }, { {.s = RIG_PARM_TIME}, CMD_PARAM_TYPE_PARM, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x21}, CMD_DAT_TIM, 2 }, { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x65}, CMD_DAT_INT, 1 }, { {.s = RIG_PARM_NONE} } }; // IC-7100 S-meter calibration data based on manual #define IC7100_STR_CAL { 14, \ { \ { 0, -54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7100_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7100_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7100_RFPOWER_METER_CAL { 13, \ { \ { 0, 0.0f }, \ { 21, 5.0f }, \ { 43, 10.0f }, \ { 65, 15.0f }, \ { 83, 20.0f }, \ { 95, 25.0f }, \ { 105, 30.0f }, \ { 114, 35.0f }, \ { 124, 40.0f }, \ { 143, 50.0f }, \ { 183, 75.0f }, \ { 213, 100.0f }, \ { 255, 120.0f } \ } } #define IC7100_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7100_VD_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 13, 10.0f }, \ { 241, 16.0f } \ } } #define IC7100_ID_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 97, 10.0f }, \ { 146, 15.0f }, \ { 241, 25.0f } \ } } #define IC7100_HF_ANTS (RIG_ANT_1|RIG_ANT_2) /* * IC-7100 rig capabilities. */ static const struct icom_priv_caps ic7100_priv_caps = { 0x88, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic7100_ts_sc_list, /* FIXME */ .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7100_extcmds, .antack_len = 2, .ant_count = 2, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7100_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x20; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x01; prmbuf[1] = 0x21; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x01; prmbuf[1] = 0x23; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7100_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x01; prmbuf[1] = 0x20; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x01; prmbuf[1] = 0x21; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x01; prmbuf[1] = 0x23; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } struct rig_caps ic7100_caps = { RIG_MODEL(RIG_MODEL_IC7100), .model_name = "IC-7100", .mfg_name = "Icom", .version = BACKEND_VER ".8", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 700, .retry = 3, .has_get_func = IC7100_FUNC_ALL, .has_set_func = IC7100_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = IC7100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC7100_LEVEL_ALL), .has_get_parm = IC7100_PARM_ALL, .has_set_parm = IC7100_PARM_ALL, .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .ext_tokens = ic7100_tokens, .extlevels = icom_ext_levels, .extfuncs = icom_ext_funcs, .extparms = icom_ext_parms, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_KEYLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_SCREENSAVER] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 1, 2, RIG_DBLST_END, }, .attenuator = {20, RIG_DBLST_END, }, .max_rit = kHz(9.999), .max_xit = kHz(9.999), .max_ifshift = Hz(0), .agc_level_count = 3, .agc_levels = { RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7100_VFO_OPS, .scan_ops = IC7100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 5, .chan_desc_sz = 9, /* TODO */ .chan_list = { /* TBC */ { 1, 396, RIG_MTYPE_MEM }, { 397, 400, RIG_MTYPE_CALL }, { 401, 424, RIG_MTYPE_EDGE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* Europe */ {kHz(30), MHz(60), IC7100_MODES, -1, -1, IC7100_VFO_ALL, IC7100_HF_ANTS}, {kHz(136), MHz(174), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(2), W(25), IC7100_VFO_ALL, IC7100_HF_ANTS), /* only HF */ FRQ_RNG_6m(1, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_2m(1, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(1, IC7100_OTHER_TX_MODES, W(2), W(75), IC7100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION1(IC7100_OTHER_TX_MODES, W(1), W(10), IC7100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(30), MHz(60), IC7100_MODES, -1, -1, IC7100_VFO_ALL, IC7100_HF_ANTS}, {kHz(136), MHz(174), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_3}, {MHz(420), MHz(480), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_4}, {MHz(1240), MHz(1320), IC7100_MODES, -1, -1, IC7100_VFO_ALL, RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(2), W(25), IC7100_VFO_ALL, IC7100_HF_ANTS), /* only HF */ /* USA only, TBC: end of range and modes */ {MHz(5.255), MHz(5.405), IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS}, /* USA only */ {MHz(5.255), MHz(5.405), RIG_MODE_AM, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS}, /* USA only */ FRQ_RNG_6m(2, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, IC7100_HF_ANTS), FRQ_RNG_2m(2, IC7100_OTHER_TX_MODES, W(2), W(100), IC7100_VFO_ALL, RIG_ANT_3), FRQ_RNG_70cm(2, IC7100_OTHER_TX_MODES, W(2), W(75), IC7100_VFO_ALL, RIG_ANT_4), /* option */ FRQ_RNG_23cm_REGION2(IC7100_OTHER_TX_MODES, W(1), W(10), IC7100_VFO_ALL, RIG_ANT_5), RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(0.1)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_FM, kHz(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(10)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(7)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, RIG_FLT_END, }, .str_cal = IC7100_STR_CAL, .swr_cal = IC7100_SWR_CAL, .alc_cal = IC7100_ALC_CAL, .rfpower_meter_cal = IC7100_RFPOWER_METER_CAL, .comp_meter_cal = IC7100_COMP_METER_CAL, .vd_meter_cal = IC7100_VD_METER_CAL, .id_meter_cal = IC7100_ID_METER_CAL, .priv = (void *)& ic7100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icom_set_freq, .get_mode = icom_get_mode, .set_mode = icom_set_mode, // .get_vfo = icom_get_vfo, .set_vfo = icom_set_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = icom_get_func, .set_func = icom_set_func, .get_level = icom_get_level, .set_level = icom_set_level, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_code, .get_dcs_sql = icom_get_dcs_code, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ext_func = icom_set_ext_func, .get_ext_func = icom_get_ext_func, .set_mem = icom_set_mem, .set_bank = icom_set_bank, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7100_set_clock, .get_clock = ic7100_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic725.c0000644000175000017500000001141714752216205012600 00000000000000/* * Hamlib CI-V backend - description of IC-725 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC725_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC725_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC725_AM_TX_MODES (RIG_MODE_AM) #define IC725_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC725_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC725_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC725_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic725_priv_caps = { 0x28, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic725_caps = { RIG_MODEL(RIG_MODEL_IC725), .model_name = "IC-725", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC725_VFO_OPS, .scan_ops = IC725_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(33) - 10, IC725_ALL_RX_MODES, -1, -1, IC725_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(2, IC725_OTHER_TX_MODES, W(10), W(100), IC725_VFO_ALL, IC725_ANTS), FRQ_RNG_HF(2, IC725_AM_TX_MODES, W(10), W(40), IC725_VFO_ALL, IC725_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(33) - 10, IC725_ALL_RX_MODES, -1, -1, IC725_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC725_OTHER_TX_MODES, W(10), W(100), IC725_VFO_ALL, IC725_ANTS), FRQ_RNG_HF(2, IC725_AM_TX_MODES, W(10), W(40), IC725_VFO_ALL, IC725_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC725_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic725_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr6.c0000644000175000017500000001216414752216205012612 00000000000000/* * Hamlib CI-V backend - description of IC-R6 * Copyright (c) 2017 Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #include "tones.h" #define ICR6_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ICR6_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_VSC|RIG_FUNC_CSQL|RIG_FUNC_AFLT|RIG_FUNC_DSQL) #define ICR6_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define ICR6_VFO_ALL (RIG_VFO_A) #define ICR6_VFO_OPS (RIG_OP_NONE) #define ICR6_SCAN_OPS (RIG_SCAN_NONE) #define ICR6_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 255, 60 } /* +60 */ \ } } static struct icom_priv_caps icr6_priv_caps = { 0x7e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list, /* wrong, but don't have set_ts anyway */ .antack_len = 2, .ant_count = 2 }; struct rig_caps icr6_caps = { RIG_MODEL(RIG_MODEL_ICR6), .model_name = "IC-R6", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR6_FUNC_ALL, .has_set_func = ICR6_FUNC_ALL, .has_get_level = ICR6_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICR6_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR6_VFO_OPS, .scan_ops = ICR6_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = {RIG_CHAN_END,}, .rx_range_list1 = { /* Other countries but France */ {kHz(100), GHz(1.309995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(100), MHz(821.995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, {MHz(851), MHz(866.995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, {MHz(896), GHz(1.309995), ICR6_MODES, -1, -1, ICR6_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR6_MODES, Hz(5000)}, {ICR6_MODES, Hz(6250)}, {ICR6_MODES, Hz(8330)}, // Air band only {ICR6_MODES, Hz(9000)}, // AM broadcast band only {ICR6_MODES, Hz(10000)}, {ICR6_MODES, Hz(12500)}, {ICR6_MODES, kHz(15)}, {ICR6_MODES, kHz(20)}, {ICR6_MODES, kHz(25)}, {ICR6_MODES, kHz(30)}, {ICR6_MODES, kHz(50)}, {ICR6_MODES, kHz(100)}, {ICR6_MODES, kHz(125)}, {ICR6_MODES, kHz(200)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM | RIG_MODE_FM, kHz(12)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR6_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr6_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .get_dcd = icom_get_dcd, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic761.c0000644000175000017500000001645614752216205012610 00000000000000/* * Hamlib CI-V backend - description of IC-761 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC761_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC761_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) #define IC761_AM_TX_MODES (RIG_MODE_AM) #define IC761_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define IC761_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC761_SCAN_OPS (RIG_SCAN_NONE) #define IC761_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic761_priv_caps = { 0x1e, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic761_caps = { RIG_MODEL(RIG_MODEL_IC761), .model_name = "IC-761", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC761_VFO_OPS, .scan_ops = IC761_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, /* TBC */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC761_ALL_RX_MODES, -1, -1, IC761_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1.8), MHz(1.99999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC761_ALL_RX_MODES, -1, -1, IC761_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {MHz(1.8), MHz(1.99999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, /* 100W class */ {MHz(1.8), MHz(1.99999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, /* 40W class */ {MHz(3.45), MHz(4.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(3.45), MHz(4.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(6.95), MHz(7.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(9.95), MHz(10.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(13.95), MHz(14.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(17.95), MHz(18.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(20.95), MHz(21.49999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(24.45), MHz(25.09999), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_OTHER_TX_MODES, W(10), W(100), IC761_VFO_ALL}, {MHz(27.95), MHz(30), IC761_AM_TX_MODES, W(10), W(40), IC761_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC761_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_RTTY | RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic761_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic735.c0000644000175000017500000001332314752216205012577 00000000000000/* * Hamlib CI-V backend - description of IC-735 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "bandplan.h" #define IC735_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * 100W in all modes but AM (40W) */ #define IC735_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC735_AM_TX_MODES (RIG_MODE_AM) #define IC735_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC735_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define IC735_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic735_priv_caps = { 0x04, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic735_caps = { RIG_MODEL(RIG_MODEL_IC735), .model_name = "IC-735", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC735_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 10, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 11, 12, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30), IC735_ALL_RX_MODES, -1, -1, IC735_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC735_OTHER_TX_MODES, W(10), W(100), IC735_VFO_ALL, IC735_ANTS), FRQ_RNG_HF(1, IC735_AM_TX_MODES, W(10), W(40), IC735_VFO_ALL, IC735_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), IC735_ALL_RX_MODES, -1, -1, IC735_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, /* 100W class */ {kHz(1800), MHz(2) - 1, IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, /* 40W class */ {kHz(3500), MHz(4) - 1, IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(3500), MHz(4) - 1, IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(7), kHz(7300), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(7), kHz(7300), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {kHz(10100), kHz(10150), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(10100), kHz(10150), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(14), kHz(14350), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(14), kHz(14350), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {kHz(18068), kHz(18168), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(18068), kHz(18168), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(21), kHz(21450), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(21), kHz(21450), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {kHz(24890), kHz(24990), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {kHz(24890), kHz(24990), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, {MHz(28), kHz(29700), IC735_OTHER_TX_MODES, 5000, 100000, IC735_VFO_ALL}, {MHz(28), kHz(29700), IC735_AM_TX_MODES, 2000, 40000, IC735_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC735_ALL_RX_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic735_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icf8101.c0000644000175000017500000003271114752216205013022 00000000000000/* * Hamlib CI-V backend - description of IC-F8101 * Copyright (c) 2000-2010 by Stephane Fillod * Copyright (c) 2021 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "misc.h" #include "icom.h" #include "icom_defs.h" #include "frame.h" #include "idx_builtin.h" static int icf8101_rig_open(RIG *rig) { // turn on VFO mode icom_set_vfo(rig, RIG_VFO_A); return icom_rig_open(rig); } static int icf8101_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; int freq_len = 5; int ack_len; unsigned char freqbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; vfo_t vfo_save = STATE(rig)->current_vfo; if (vfo != vfo_save) { rig_set_vfo(rig, vfo); } to_bcd(freqbuf, freq, freq_len * 2); retval = icom_transaction(rig, 0x1a, 0x35, freqbuf, freq_len, ackbuf, &ack_len); if (vfo != vfo_save) { rig_set_vfo(rig, vfo_save); } return retval; } static int icf8101_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; unsigned char modebuf[2]; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_LSB: modebuf[0] = 0x00; modebuf[1] = 0x00; break; case RIG_MODE_USB: modebuf[0] = 0x00; modebuf[1] = 0x01; break; case RIG_MODE_AM: modebuf[0] = 0x00; modebuf[1] = 0x02; break; case RIG_MODE_CW: modebuf[0] = 0x00; modebuf[1] = 0x03; break; case RIG_MODE_RTTY: modebuf[0] = 0x00; modebuf[1] = 0x04; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode of '%s\n", __func__, rig_strrmode(mode)); return (-RIG_EINVAL); } retval = icom_transaction(rig, 0x1A, 0x36, modebuf, 2, NULL, 0); return retval; } static int icf8101_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval = icom_get_mode(rig, vfo, mode, width); unsigned char modebuf[MAXFRAMELEN]; int modebuf_len; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); if (retval != RIG_OK) { return retval; } retval = icom_transaction(rig, 0x1A, 0x34, NULL, 0, modebuf, &modebuf_len); if (retval != RIG_OK) { return retval; } dump_hex(modebuf, modebuf_len); switch (modebuf[1]) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_AM; break; case 0x03: *mode = RIG_MODE_CW; break; case 0x04: *mode = RIG_MODE_RTTY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode response=0x%02x\n", __func__, modebuf[1]); } return retval; } /* * This function does the special bandwidth coding for IC-F8101 * (1 - normal, 2 - narrow) */ static int icf8101_r2i_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width, unsigned char *md, signed char *pd) { int err; err = rig2icom_mode(rig, vfo, mode, width, md, pd); if (*pd == PD_NARROW_3) { *pd = PD_NARROW_2; } return err; } #define ICF8101_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_RTTY) #define ICF8101_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define ICF8101_SCAN_OPS (RIG_SCAN_MEM) #define ICF8101_FUNC_ALL (RIG_FUNC_NB| \ RIG_FUNC_NR| \ RIG_FUNC_ANF| \ RIG_FUNC_TONE| \ RIG_FUNC_COMP| \ RIG_FUNC_VOX| \ RIG_FUNC_FBKIN| \ RIG_FUNC_AFC) #define ICF8101_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_RF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_IF| \ RIG_LEVEL_NR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_ATT| \ RIG_LEVEL_PREAMP) #define ICF8101_STR_CAL UNKNOWN_IC_STR_CAL /* FIXME */ static const struct icom_priv_caps icf8101_priv_caps = { 0x8A, /* default address */ 0, /* 731 mode */ 1, /* no XCHG to avoid display flicker */ NULL, .r2i_mode = icf8101_r2i_mode }; int icf8101_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { default: return icom_set_func(rig, vfo, func, status); } } int icf8101_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { switch (func) { default: return icom_get_func(rig, vfo, func, status); } } int icf8101_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_set_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, 1, val); default: return icom_set_level(rig, vfo, level, val); } } int icf8101_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_VOXDELAY: return icom_get_level_raw(rig, level, C_CTL_MEM, S_MEM_VOXDELAY, 0, NULL, val); default: return icom_get_level(rig, vfo, level, val); } } int icf8101_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { return rig_set_freq(rig, RIG_VFO_B, tx_freq); } int icf8101_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { return rig_get_freq(rig, RIG_VFO_B, tx_freq); } int icf8101_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, rmode_t mode, pbwidth_t width) { rig_set_freq(rig, RIG_VFO_B, tx_freq); return rig_set_mode(rig, RIG_VFO_B, mode, -1); } int icf8101_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, rmode_t *mode, pbwidth_t *width) { rig_get_freq(rig, RIG_VFO_B, tx_freq); return rig_get_mode(rig, RIG_VFO_B, mode, width); } int icf8101_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmdbuf[4]; int ack_len; unsigned char ackbuf[MAXFRAMELEN]; cmdbuf[0] = 0x03; cmdbuf[1] = 0x17; cmdbuf[2] = 0x00; cmdbuf[3] = split == RIG_SPLIT_ON; return icom_transaction(rig, 0x1a, 0x05, cmdbuf, sizeof(cmdbuf), ackbuf, &ack_len); } int icf8101_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int retval; int ack_len; unsigned char ackbuf[MAXFRAMELEN]; unsigned char cmdbuf[2]; cmdbuf[0] = 0x03; cmdbuf[1] = 0x17; retval = icom_transaction(rig, 0x1a, 0x05, cmdbuf, sizeof(cmdbuf), ackbuf, &ack_len); if (retval == RIG_OK && ack_len >= 1) { dump_hex(ackbuf, ack_len); *split = ackbuf[0] == 1; *tx_vfo = *split ? RIG_VFO_B : RIG_VFO_A; } return retval; } int icf8101_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char ackbuf[MAXFRAMELEN], pttbuf[2]; int ack_len = sizeof(ackbuf), retval; ENTERFUNC; switch (ptt) { case RIG_PTT_ON: pttbuf[0] = 0; pttbuf[1] = 1; break; case RIG_PTT_ON_MIC: pttbuf[0] = 0; pttbuf[1] = 1; break; case RIG_PTT_ON_DATA: pttbuf[0] = 0; pttbuf[1] = 2; break; case RIG_PTT_OFF: pttbuf[0] = 0; pttbuf[1] = 0; break; default: RETURNFUNC(-RIG_EINVAL); } retval = icom_transaction(rig, C_CTL_MEM, S_MEM_PTT, pttbuf, 2, ackbuf, &ack_len); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((ack_len >= 1 && ackbuf[0] != ACK) && (ack_len >= 2 && ackbuf[1] != NAK)) { // if we don't get ACK/NAK some serial corruption occurred // so we'll call it a timeout for retry purposes RETURNFUNC(-RIG_ETIMEOUT); } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG (%#.2x), len=%d\n", __func__, ackbuf[0], ack_len); RETURNFUNC(-RIG_ERJCTED); } RETURNFUNC(RIG_OK); } /* * icf8101_get_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL, ptt!=NULL */ int icf8101_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { unsigned char pttbuf[MAXFRAMELEN]; int ptt_len, retval; ENTERFUNC; retval = icom_transaction(rig, C_CTL_MEM, S_MEM_PTT, NULL, 0, pttbuf, &ptt_len); if (retval != RIG_OK) { RETURNFUNC(retval); } /* * pttbuf should contain Cn,Sc,Data area */ ptt_len -= 2; if (ptt_len != 2) { rig_debug(RIG_DEBUG_ERR, "%s: wrong frame len=%d\n", __func__, ptt_len); RETURNFUNC(-RIG_ERJCTED); } if (pttbuf[3] == 0) { *ptt = RIG_PTT_OFF; } else if (pttbuf[3] == 1) { *ptt = RIG_PTT_ON_MIC; } else if (pttbuf[3] == 2) { *ptt = RIG_PTT_ON_DATA; } RETURNFUNC(RIG_OK); } struct rig_caps icf8101_caps = { RIG_MODEL(RIG_MODEL_ICF8101), .model_name = "IC-F8101", .mfg_name = "Icom", .version = BACKEND_VER ".3", .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 = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICF8101_FUNC_ALL, .has_set_func = ICF8101_FUNC_ALL | RIG_FUNC_RESUME, .has_get_level = ICF8101_LEVEL_ALL | (RIG_LEVEL_RAWSTR), .has_set_level = ICF8101_LEVEL_ALL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, }, .tuning_steps = { {ICF8101_MODES, 1}, }, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW, RIG_AGC_AUTO }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 20, RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, // is it really 20dB? */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), /* there is RTTY shift */ .targetable_vfo = RIG_TARGETABLE_FREQ, .scan_ops = ICF8101_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 500, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(29.9999), ICF8101_MODES, -1, -1, ICF8101_VFO_ALL, RIG_ANT_CURR, "Other" }, RIG_FRNG_END, }, .tx_range_list1 = { { MHz(1.6), MHz(29.9999), ICF8101_MODES, W(1), W(100), ICF8101_VFO_ALL, RIG_ANT_CURR, "Other"}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(29.9999), ICF8101_MODES, -1, -1, ICF8101_VFO_ALL, RIG_ANT_CURR, "AUS" }, RIG_FRNG_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_RTTY, kHz(3.0)}, /* builtin */ {RIG_MODE_AM, kHz(10)}, /* builtin */ RIG_FLT_END, }, .str_cal = ICF8101_STR_CAL, .priv = &icf8101_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .get_freq = icom_get_freq, .set_freq = icf8101_set_freq, .get_mode = icf8101_get_mode, .set_mode = icf8101_set_mode, .set_ptt = icf8101_set_ptt, .get_ptt = icf8101_get_ptt, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .get_ts = icom_get_ts, .set_ts = icom_set_ts, .get_func = icf8101_get_func, .set_func = icf8101_set_func, .get_level = icf8101_get_level, .set_level = icf8101_set_level, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, .decode_event = icom_decode_event, .rig_open = icf8101_rig_open, .rig_close = icom_rig_close, .set_split_freq = icf8101_set_split_freq, .get_split_freq = icf8101_get_split_freq, .set_split_vfo = icf8101_set_split_vfo, .get_split_vfo = icf8101_get_split_vfo, .set_split_freq_mode = icf8101_set_split_freq_mode, .get_split_freq_mode = icf8101_get_split_freq_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic475.c0000644000175000017500000001602614752216205012603 00000000000000/* * Hamlib CI-V backend - description of IC-475 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC475_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC475_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC475_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) /* * FIXME: this appears to be the IC-475A/E * what about the IC-475H ? please give it a fix. --SF */ static const struct icom_priv_caps ic475_priv_caps = { 0x14, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic475_caps = { RIG_MODEL(RIG_MODEL_IC475), .model_name = "IC-475", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC475_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC475_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic475_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static const struct icom_priv_caps ic575_priv_caps = { 0x16, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic575_caps = { RIG_MODEL(RIG_MODEL_IC575), .model_name = "IC-575", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC475_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, -1, -1, IC475_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(430), MHz(450), IC475_MODES, W(2.5), W(25), IC475_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC475_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic575_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op }; hamlib-4.6.2/rigs/icom/ic7700.c0000644000175000017500000003734214752216205012665 00000000000000/* * Hamlib CI-V backend - description of IC-7700 and variations * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Stre #include #include "token.h" #include "tones.h" #include "idx_builtin.h" #include "icom.h" #include "icom_defs.h" #include "bandplan.h" #include "frame.h" #include "misc.h" #define IC7700_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PSK|RIG_MODE_PSKR) #define IC7700_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_PKTAM) #define IC7700_ALL_RX_MODES IC7700_OTHER_TX_MODES | IC7700_AM_TX_MODES #define IC7700_1HZ_TS_MODES IC7700_ALL_RX_MODES #define IC7700_FUNCS (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_NR|RIG_FUNC_MON|RIG_FUNC_MN|RIG_FUNC_ANF|RIG_FUNC_VSC|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) #define IC7700_LEVELS (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_COMP|RIG_LEVEL_BKINDL|RIG_LEVEL_BALANCE|RIG_LEVEL_NR|RIG_LEVEL_PBT_IN|RIG_LEVEL_PBT_OUT|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_NOTCHF_RAW|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_APF|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_VOXDELAY|RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_AGC_TIME) #define IC7700_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC7700_PARMS (RIG_PARM_ANN|RIG_PARM_BACKLIGHT) #define IC7700_VFO_OPS (RIG_OP_CPY|RIG_OP_XCHG|RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL|RIG_OP_TUNE) #define IC7700_SCAN_OPS (RIG_SCAN_MEM|RIG_SCAN_VFO|RIG_SCAN_PROG|RIG_SCAN_DELTA|RIG_SCAN_PRIO) #define IC7700_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // IC-7700 S-meter calibration data based on manual #define IC7700_STR_CAL { 3, \ { \ { 0,-54 }, \ { 120, 0 }, \ { 241, 60 } \ } } #define IC7700_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 48, 1.5f }, \ { 80, 2.0f }, \ { 120, 3.0f }, \ { 240, 6.0f } \ } } #define IC7700_ALC_CAL { 2, \ { \ { 0, 0.0f }, \ { 120, 1.0f } \ } } #define IC7700_RFPOWER_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 143, 100.0f }, \ { 212, 200.0f }, \ { 255, 250.0f }, \ } } #define IC7700_COMP_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 130, 15.0f }, \ { 241, 30.0f } \ } } #define IC7700_VD_METER_CAL { 4, \ { \ { 0, 0.0f }, \ { 151, 44.0f }, \ { 180, 48.0f }, \ { 211, 52.0f } \ } } #define IC7700_ID_METER_CAL { 3, \ { \ { 0, 0.0f }, \ { 165, 10.0f }, \ { 241, 15.0f } \ } } struct cmdparams ic7700_extcmds[] = { { {.s = RIG_LEVEL_VOXDELAY}, CMD_PARAM_TYPE_LEVEL, C_CTL_MEM, S_MEM_PARM, SC_MOD_RW, 2, {0x01, 0x82}, CMD_DAT_INT, 1 }, { { 0 } } }; int ic7700_ext_tokens[] = { TOK_DRIVE_GAIN, TOK_DIGI_SEL_FUNC, TOK_DIGI_SEL_LEVEL, TOK_BACKEND_NONE }; /* * IC-7700 rig capabilities. */ static const struct icom_priv_caps ic7700_priv_caps = { 0x74, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic756pro_ts_sc_list, .antack_len = 4, .ant_count = 3, .agc_levels_present = 1, .agc_levels = { { .level = RIG_AGC_OFF, .icom_level = 0 }, { .level = RIG_AGC_FAST, .icom_level = 1 }, { .level = RIG_AGC_MEDIUM, .icom_level = 2 }, { .level = RIG_AGC_SLOW, .icom_level = 3 }, { .level = RIG_AGC_LAST, .icom_level = -1 }, }, .extcmds = ic7700_extcmds, .x25x26_always = 0, .x25x26_possibly = 1, .x1cx03_always = 0, .x1cx03_possibly = 1, .x1ax03_supported = 1, .mode_with_filter = 1, .data_mode_supported = 1 }; // if hour < 0 then only date will be set int ic7700_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; unsigned char prmbuf[MAXFRAMELEN]; if (year >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x58; to_bcd(&prmbuf[2], year / 100, 2); to_bcd(&prmbuf[3], year % 100, 2); to_bcd(&prmbuf[4], month, 2); to_bcd(&prmbuf[5], day, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 6, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } if (hour >= 0) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; to_bcd(&prmbuf[2], hour, 2); to_bcd(&prmbuf[3], min, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 4, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } prmbuf[0] = 0x00; prmbuf[1] = 0x61; rig_debug(RIG_DEBUG_ERR, "%s: utc_offset=%d\n", __func__, utc_offset); to_bcd(&prmbuf[2], abs(utc_offset) / 100, 2); to_bcd(&prmbuf[3], abs(utc_offset) % 100, 2); to_bcd(&prmbuf[4], utc_offset >= 0 ? 0 : 1, 2); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 5, NULL, NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): %s\b", __func__, __LINE__, rigerror(retval)); } } return retval; } int ic7700_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int cmd = 0x1a; int subcmd = 0x05; int retval = RIG_OK; int resplen; unsigned char prmbuf[MAXFRAMELEN]; unsigned char respbuf[MAXFRAMELEN]; prmbuf[0] = 0x00; prmbuf[1] = 0x58; resplen = sizeof(respbuf); retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); *year = from_bcd(&respbuf[4], 2) * 100 + from_bcd(&respbuf[5], 2); *month = from_bcd(&respbuf[6], 2); *day = from_bcd(&respbuf[7], 2); if (hour != NULL) { prmbuf[0] = 0x00; prmbuf[1] = 0x59; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *hour = from_bcd(&respbuf[4], 2); *min = from_bcd(&respbuf[5], 2); *sec = 0; *msec = 0; prmbuf[0] = 0x00; prmbuf[1] = 0x61; retval = icom_transaction(rig, cmd, subcmd, prmbuf, 2, respbuf, &resplen); if (retval != RIG_OK) { return retval; } *utc_offset = from_bcd(&respbuf[4], 2) * 100; *utc_offset += from_bcd(&respbuf[5], 2); if (respbuf[6] != 0x00) { *utc_offset *= -1; } //rig_debug(RIG_DEBUG_VERBOSE, // "%s: %02d-%02d-%02dT%02d:%02d:%06.3lf%s%04d\n'", // __func__, *year, *month, *day, *hour, *min, *sec + *msec / 1000, // *utc_offset >= 0 ? "+" : "-", (unsigned)abs(*utc_offset)); } return retval; } static int ic7700_rig_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: enter\n", __func__); struct icom_priv_data *priv = (struct icom_priv_data *) STATE(rig)->priv; priv->x26cmdfails = priv->x25cmdfails = 1; return icom_rig_open(rig); } struct rig_caps ic7700_caps = { RIG_MODEL(RIG_MODEL_IC7700), .model_name = "IC-7700", .mfg_name = "Icom", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC7700_FUNCS, .has_set_func = IC7700_FUNCS, .has_get_level = IC7700_LEVELS, .has_set_level = RIG_LEVEL_SET(IC7700_LEVELS), .has_get_parm = IC7700_PARMS, .has_set_parm = RIG_PARM_SET(IC7700_PARMS), /* FIXME: parms */ .level_gran = { #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #include "level_gran_icom.h" #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH [LVL_KEYSPD] = { .min = { .i = 6 }, .max = { .i = 48 }, .step = { .i = 1 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 900 }, .step = { .i = 1 } }, }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ext_tokens = ic7700_ext_tokens, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* FIXME: TBC */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW }, // 7700 can have a different mode on VFOB but requires VFO swap .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .vfo_ops = IC7700_VFO_OPS, .scan_ops = IC7700_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), IC7700_ALL_RX_MODES, -1, -1, IC7700_VFOS, IC7700_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_6m(1, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_HF(1, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ FRQ_RNG_6m(1, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), IC7700_ALL_RX_MODES, -1, -1, IC7700_VFOS, IC7700_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_6m(2, IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS), FRQ_RNG_HF(2, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ FRQ_RNG_6m(2, IC7700_AM_TX_MODES, W(5), W(50), IC7700_VFOS, IC7700_ANTS), /* AM class */ /* USA only, TBC: end of range and modes */ {MHz(5.33050), MHz(5.33350), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.34650), MHz(5.34950), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.36650), MHz(5.36950), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.37150), MHz(5.37450), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ {MHz(5.40350), MHz(5.40650), IC7700_OTHER_TX_MODES, W(5), W(200), IC7700_VFOS, IC7700_ANTS}, /* USA only */ RIG_FRNG_END, }, .tuning_steps = { {IC7700_1HZ_TS_MODES, 1}, {IC7700_ALL_RX_MODES, Hz(100)}, {IC7700_ALL_RX_MODES, kHz(1)}, {IC7700_ALL_RX_MODES, kHz(5)}, {IC7700_ALL_RX_MODES, kHz(9)}, {IC7700_ALL_RX_MODES, kHz(10)}, {IC7700_ALL_RX_MODES, kHz(12.5)}, {IC7700_ALL_RX_MODES, kHz(20)}, {IC7700_ALL_RX_MODES, kHz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.8)}, {RIG_MODE_SSB | RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(3)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PSK | RIG_MODE_PSKR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PSK | RIG_MODE_PSKR, kHz(1.0)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(6)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(3)}, {RIG_MODE_AM | RIG_MODE_PKTAM, kHz(9)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(15)}, RIG_FLT_END, }, .str_cal = IC7700_STR_CAL, .swr_cal = IC7700_SWR_CAL, .alc_cal = IC7700_ALC_CAL, .rfpower_meter_cal = IC7700_RFPOWER_METER_CAL, .comp_meter_cal = IC7700_COMP_METER_CAL, .vd_meter_cal = IC7700_VD_METER_CAL, .id_meter_cal = IC7700_ID_METER_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic7700_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = ic7700_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // .get_vfo = icom_get_vfo, .set_ant = icom_set_ant, .get_ant = icom_get_ant, .set_rit = icom_set_rit_new, .get_rit = icom_get_rit_new, .get_xit = icom_get_rit_new, .set_xit = icom_set_xit_new, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_ext_level = icom_set_ext_level, .get_ext_level = icom_get_ext_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .send_morse = icom_send_morse, .stop_morse = icom_stop_morse, .wait_morse = rig_wait_morse, .set_clock = ic7700_set_clock, .get_clock = ic7700_get_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic765.c0000644000175000017500000001445714752216205012613 00000000000000/* * Hamlib CI-V backend - description of IC-765 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC765_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) /* * IC-765 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic765/specs.htm * */ #define IC765_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define IC765_AM_TX_MODES (RIG_MODE_AM) #define IC765_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC765_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC765_SCAN_OPS (RIG_SCAN_PROG|RIG_SCAN_MEM) #define IC765_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic765_priv_caps = { 0x2c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic765_caps = { RIG_MODEL(RIG_MODEL_IC765), .model_name = "IC-765", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC765_VFO_OPS, .scan_ops = IC765_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), IC765_ALL_RX_MODES, -1, -1, IC765_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC765_OTHER_TX_MODES, W(10), W(100), IC765_VFO_ALL, IC765_ANTS), FRQ_RNG_HF(1, IC765_AM_TX_MODES, W(10), W(40), IC765_VFO_ALL, IC765_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), IC765_ALL_RX_MODES, -1, -1, IC765_VFO_ALL}, RIG_FRNG_END, }, /* weird transmit ranges ... --sf */ .tx_range_list2 = { {kHz(1800), 1999999, IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, /* 100W class */ {kHz(1800), 1999999, IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, /* 40W class */ {kHz(3400), 4099999, IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {kHz(3400), 4099999, IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(6.9), kHz(7499.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(9.9), MHz(1049999), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(9.9), MHz(1049999), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(13.9), MHz(14.49999), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {kHz(17900), kHz(18499.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {kHz(17900), kHz(18499.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(20.9), kHz(21499.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {kHz(24400), kHz(25099.99), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {kHz(24400), kHz(25099.99), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, {MHz(28), MHz(30), IC765_OTHER_TX_MODES, 5000, 100000, IC765_VFO_ALL}, {MHz(28), MHz(30), IC765_AM_TX_MODES, 2000, 40000, IC765_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC765_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, /* narrow */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic765_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic275.c0000644000175000017500000001611314752216205012576 00000000000000/* * Hamlib CI-V backend - description of IC-275 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC275_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC275_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC275_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) /* * FIXME: this appears to be the IC-275A/E * what about the IC-275H ? please give it a fix. --SF */ static const struct icom_priv_caps ic275_priv_caps = { 0x10, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; static const struct icom_priv_caps ic375_priv_caps = { 0x12, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic275_caps = { RIG_MODEL(RIG_MODEL_IC275), .model_name = "IC-275", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC275_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC275_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic275_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ic375_caps = { RIG_MODEL(RIG_MODEL_IC375), .model_name = "IC-375", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC275_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, { 100, 101, RIG_MTYPE_EDGE, IC_MIN_MEM_CAP }, { 102, 102, RIG_MTYPE_CALL, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(138), MHz(174), IC275_MODES, -1, -1, IC275_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC275_MODES, W(2.5), W(25), IC275_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC275_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic375_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/id1.c0000644000175000017500000001261114752216205012421 00000000000000/* * Hamlib CI-V backend - description of ID-1 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" #define ID1_MODES (RIG_MODE_FM /* |RIG_MODE_DIGVOICE|RIG_MODE_DIGDATA*/ ) #define ID1_FUNC_ALL (RIG_FUNC_MUTE|RIG_FUNC_MON|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_AFC) #define ID1_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_RAWSTR) #define ID1_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT /* |RIG_PARM_FAN */) #define ID1_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define ID1_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_MCL) #define ID1_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* * FIXME: real measurement */ #define ID1_STR_CAL UNKNOWN_IC_STR_CAL const struct ts_sc_list id1_ts_sc_list[] = { { kHz(5), 0x00 }, { kHz(10), 0x01 }, { 12500, 0x02 }, { kHz(20), 0x03 }, { kHz(25), 0x04 }, { kHz(50), 0x05 }, { kHz(100), 0x06 }, { kHz(6.25), 0x07 }, { 0, 0 }, }; /* */ static struct icom_priv_caps id1_priv_caps = { 0x01, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ id1_ts_sc_list }; struct rig_caps id1_caps = { RIG_MODEL(RIG_MODEL_ICID1), .model_name = "IC ID-1", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 19200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID1_FUNC_ALL, .has_set_func = ID1_FUNC_ALL, .has_get_level = ID1_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID1_LEVEL_ALL), .has_get_parm = ID1_PARM_ALL, .has_set_parm = ID1_PARM_ALL, .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID1_VFO_OPS, .scan_ops = ID1_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, { 100, 101, RIG_MTYPE_EDGE }, /* two by two */ { 102, 104, RIG_MTYPE_CALL }, RIG_CHAN_END, }, .rx_range_list1 = { {GHz(1.240), GHz(1.3), ID1_MODES, -1, -1, ID1_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {GHz(1.240), GHz(1.3), ID1_MODES, W(1), W(10), ID1_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {GHz(1.240), GHz(1.3), ID1_MODES, -1, -1, ID1_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {GHz(1.240), GHz(1.3), ID1_MODES, W(1), W(10), ID1_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {ID1_MODES, kHz(5)}, {ID1_MODES, kHz(6.25)}, {ID1_MODES, kHz(10)}, {ID1_MODES, kHz(12.5)}, {ID1_MODES, kHz(20)}, {ID1_MODES, kHz(25)}, {ID1_MODES, kHz(25)}, {ID1_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, #if 0 {RIG_MODE_DIGVOICE, kHz(6)}, {RIG_MODE_DIGDATA, kHz(140)}, #endif RIG_FLT_END, }, .str_cal = ID1_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id1_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_level = icom_set_level, .get_level = icom_get_level, .set_func = icom_set_func, .get_func = icom_get_func, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_ts = icom_set_ts, .set_rptr_shift = icom_set_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic726.c0000644000175000017500000001245114752216205012600 00000000000000/* * Hamlib CI-V backend - description of IC-726 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "icom.h" #define IC726_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * IC-726 * specs: http://www.qsl.net/sm7vhs/radio/icom/ic726/specs.htm * */ #define IC726_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC726_AM_TX_MODES (RIG_MODE_AM) #define IC726_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC726_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC726_SCAN_OPS (RIG_SCAN_VFO|RIG_SCAN_MEM) /* TBC */ #define IC726_ANTS RIG_ANT_1 /* */ static const struct icom_priv_caps ic726_priv_caps = { 0x30, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic726_caps = { RIG_MODEL(RIG_MODEL_IC726), .model_name = "IC-726", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC726_VFO_OPS, .scan_ops = IC726_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 26, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, {MHz(50), MHz(54), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, IC726_OTHER_TX_MODES, W(10), W(100), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_HF(1, IC726_AM_TX_MODES, W(10), W(40), IC726_VFO_ALL, IC726_ANTS), /* AM class */ FRQ_RNG_6m(1, IC726_OTHER_TX_MODES, W(1), W(10), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_6m(1, IC726_AM_TX_MODES, W(1), W(4), IC726_VFO_ALL, IC726_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, {MHz(50), MHz(54), IC726_ALL_RX_MODES, -1, -1, IC726_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, IC726_OTHER_TX_MODES, W(10), W(100), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_HF(2, IC726_AM_TX_MODES, W(10), W(40), IC726_VFO_ALL, IC726_ANTS), /* AM class */ FRQ_RNG_6m(2, IC726_OTHER_TX_MODES, W(1), W(10), IC726_VFO_ALL, IC726_ANTS), FRQ_RNG_6m(2, IC726_AM_TX_MODES, W(1), W(4), IC726_VFO_ALL, IC726_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {IC726_ALL_RX_MODES, 10}, /* basic resolution, there's no set_ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.3)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic726_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = icom_set_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .scan = icom_scan, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr7000.c0000644000175000017500000002202214752216205013025 00000000000000/* * Hamlib CI-V backend - IC-R7000 and IC-R7100 descriptions * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "idx_builtin.h" #include "icom.h" #define ICR7000_MODES (RIG_MODE_AM|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define ICR7000_OPS (RIG_OP_FROM_VFO|RIG_OP_MCL) static int r7000_set_freq(RIG *rig, vfo_t vfo, freq_t freq); #define ICR7100_FUNCS (RIG_FUNC_VSC) #define ICR7100_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define ICR7100_PARMS (RIG_PARM_ANN) #define ICR7100_SCAN_OPS (RIG_SCAN_MEM) /* TBC */ /* FIXME: S-Meter measurements */ #define ICR7100_STR_CAL UNKNOWN_IC_STR_CAL static struct icom_priv_caps icr7000_priv_caps = { 0x08, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r7100_ts_sc_list }; /* * ICR7000 rigs capabilities. */ struct rig_caps icr7000_caps = { RIG_MODEL(RIG_MODEL_ICR7000), .model_name = "IC-R7000", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, [PARM_BANDSELECT] = {.step = {.s = "BANDUNUSED,BAND160M,BAND80M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}}, [PARM_BEEP] = {.min = {.i = 0}, .max = {.i = 1}, .step = {.i = 1}}, [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_ANN] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR7000_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(1000), ICR7000_MODES, -1, -1, RIG_VFO_A}, {MHz(1025), MHz(2000), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(1000), ICR7000_MODES, -1, -1, RIG_VFO_A}, {MHz(1025), MHz(2000), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR7000_MODES, 100}, /* resolution */ #if 0 {ICR7000_MODES, kHz(1)}, {ICR7000_MODES, kHz(5)}, {ICR7000_MODES, kHz(10)}, {ICR7000_MODES, 12500}, {ICR7000_MODES, kHz(25)}, #endif RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* narrow */ {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr7000_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = r7000_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static struct icom_priv_caps icr7100_priv_caps = { 0x34, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r7100_ts_sc_list }; /* * ICR7100A rig capabilities. */ struct rig_caps icr7100_caps = { RIG_MODEL(RIG_MODEL_ICR7100), .model_name = "IC-R7100", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 1200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR7100_FUNCS, .has_set_func = ICR7100_FUNCS, .has_get_level = ICR7100_LEVELS, .has_set_level = RIG_LEVEL_SET(ICR7100_LEVELS), .has_get_parm = ICR7100_PARMS, .has_set_parm = RIG_PARM_SET(ICR7100_PARMS), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR7000_OPS, .scan_ops = ICR7100_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM }, /* TBC */ { 0x0900, 0x0909, RIG_MTYPE_EDGE }, /* 2 by 2 */ { 0x0910, 0x0919, RIG_MTYPE_EDGE }, /* 2 by 2 */ RIG_CHAN_END, }, .rx_range_list1 = { {MHz(25), MHz(1999.9999), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(25), MHz(1999.9999), ICR7000_MODES, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* no TX ranges, this is a receiver */ .tuning_steps = { {ICR7000_MODES, 100}, /* resolution */ {ICR7000_MODES, kHz(1)}, {ICR7000_MODES, kHz(5)}, {ICR7000_MODES, kHz(10)}, {ICR7000_MODES, 12500}, {ICR7000_MODES, kHz(20)}, {ICR7000_MODES, kHz(25)}, {ICR7000_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, /* narrow */ {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR7100_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr7100_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = r7000_set_freq, /* TBC for R7100 */ .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_ts = icom_set_ts, .get_ts = icom_get_ts, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, #ifdef XXREMOVEDXX .set_parm = icom_set_parm, .get_parm = icom_get_parm, #endif .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .get_dcd = icom_get_dcd, }; /* * Function definitions below */ /* * r7000_set_freq */ static int r7000_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { long long f = (long long)freq; /* * The R7000 cannot set frequencies higher than 1GHz, * this is done by flipping a switch on the front panel and * stripping the most significant digit. * This is the only change with the common icom_set_freq */ f %= (long long)GHz(1); return icom_set_freq(rig, vfo, (freq_t)f); } hamlib-4.6.2/rigs/icom/ic7300.h0000644000175000017500000000055314752216205012660 00000000000000#include "rig.h" extern int ic7300_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); extern int ic7300_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); hamlib-4.6.2/rigs/icom/omni.c0000644000175000017500000002125314752216205012710 00000000000000/* * Hamlib CI-V backend - description of the TenTenc OMNI VI * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* Improvements by Martin Ewing, AA6E, 3/2008 * This backend should support either the Ten-Tec Omni VI Plus (564) or the * Omni VI (563). Tested on an Omni VI. */ /* Known problems: * * To Do: * Implement vfo split, FSK mode */ #include #include #include "icom.h" #include "icom_defs.h" #include "frame.h" #include #define OMNIVIP_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define OMNIVIP_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define OMNIVIP_ALL_RX_MODES (OMNIVIP_OTHER_TX_MODES) #define OMNIVIP_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define OMNIVIP_STR_CAL { 0, { } } static int omni6_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int omni6_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int omni6_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static struct icom_priv_caps omnivip_priv_caps = { 0x04, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ NULL /* TODO */ }; struct rig_caps omnivip_caps = { RIG_MODEL(RIG_MODEL_OMNIVIP), .model_name = "Omni VI Plus", .mfg_name = "Ten-Tec", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, // Allow program controlled PTT .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9980), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = OMNIVIP_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* These limits measured on Omni VI SN 1A10473 */ .rx_range_list2 = { {kHz(1770), kHz(2330), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(3471), kHz(4030), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(6821), kHz(7338), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(9971), kHz(10530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(13971), kHz(14530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(17971), kHz(18530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(20971), kHz(21530), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(24471), kHz(25030), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, {kHz(27971), kHz(30030), OMNIVIP_ALL_RX_MODES, -1, -1, OMNIVIP_VFO_ALL}, RIG_FRNG_END, }, /* Note: There is no AM mode. */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(3500), MHz(4) - 1, OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(7), kHz(7300), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(10100), kHz(10150), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(14), kHz(14350), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(18068), kHz(18168), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(21), kHz(21450), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {kHz(24890), kHz(24990), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, {MHz(28), kHz(29700), OMNIVIP_OTHER_TX_MODES, 5000, 100000, OMNIVIP_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {OMNIVIP_ALL_RX_MODES, Hz(10)}, // This radio has 10 Hz steps. RIG_TS_END, }, /* mode/filter list, remember: order matters! * Possible XTAL filters: 2.4, 1.8, 0.5, 0.25 kHz - may not all be * present. FM filter is 15 kHz. * We are not supporting the 'FSK' (RTTY) mode at this time. */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& omnivip_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, // icom.c has no get_vfo .set_rit = omni6_set_rit, .get_rit = omni6_get_rit, // icom.c has no get_rit .set_xit = omni6_set_rit, // xit=rit for this rig .get_xit = omni6_get_rit, // (front panel controlled) .set_ptt = omni6_set_ptt, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * omni6_set_ptt based on icom_set_ptt * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int omni6_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval, sc; sc = ptt == RIG_PTT_ON ? 0x1 : 0x2; /* * Ignore ACK/NAK on this command, because in CW mode, the Omni VI * does not send an ACK. */ retval = icom_transaction(rig, C_OMNI6_XMT, sc, NULL, 0, NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * These 'rit' commands actually deal with an offset frequency. The operator * must select rit on/off or xit on/off manually to apply this offset. * Omni VI's rit uses 9's complement for negative freq, and freqs are in units * of 10 Hz. on the Omni. * Note that Omni VI rejects rit > 9980, but takes rit >= -9990. So the * rit limit should be +/- 9.98 kHz. */ int omni6_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char freqbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; int freq_len, ack_len = sizeof(ackbuf), retval; shortfreq_t rit10; rit10 = rit / 10; // 10 Hz resolution for Omni if (rit10 < 0) { rit10 += 10000L; } // 9's compl. freq_len = 2; to_bcd(freqbuf, rit10, 2 * freq_len); retval = icom_transaction(rig, C_SET_OFFS, -1, freqbuf, freq_len, ackbuf, &ack_len); if (retval != RIG_OK) { return retval; } if (ack_len != 1 || ackbuf[0] != ACK) { rig_debug(RIG_DEBUG_ERR, "omni6_set_rit: ack NG (%#.2x), " "len=%d\n", ackbuf[0], ack_len); return -RIG_ERJCTED; } return RIG_OK; } /* * Note: icom.c does not provide a get_rit method. It would have been * wrong for the Omni VI, anyway, so we implement it here. */ int omni6_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { unsigned char buffer[MAXFRAMELEN]; int buffer_len, retval; shortfreq_t my_rit; retval = icom_transaction(rig, C_RD_OFFS, -1, NULL, 0, buffer, & buffer_len); if (retval != RIG_OK) { return retval; } if (buffer_len != 3) { rig_debug(RIG_DEBUG_ERR, "omni6_get_rit: wrong length response (%d)\n", buffer_len); return -RIG_ERJCTED; } my_rit = 10 * from_bcd(buffer, 2 * buffer_len); if (my_rit > 10000L) { my_rit -= 100000L; } // 9's compl for negatives *rit = my_rit; return RIG_OK; } hamlib-4.6.2/rigs/icom/ic2730.c0000644000175000017500000001457114752216205012662 00000000000000/* * Hamlib CI-V backend - description of IC-2730 and variations * Copyright (c) 2015 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" #define IC2730_MODES (RIG_MODE_FM) #define IC2730_ALL_RX_MODES (RIG_MODE_AM|IC2730_MODES) #define IC2730_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB) #define IC2730_SCAN_OPS RIG_SCAN_NONE #define IC2730_VFO_OPS RIG_OP_NONE #define IC2730_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_VOX) #define IC2730_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define IC2730_PARM_ALL RIG_PARM_NONE /* * FIXME: real measurement */ #define IC2730_STR_CAL UNKNOWN_IC_STR_CAL static const struct icom_priv_caps ic2730_priv_caps = { 0x90, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps ic2730_caps = { RIG_MODEL(RIG_MODEL_IC2730), .model_name = "IC-2730", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = IC2730_FUNC_ALL, .has_set_func = IC2730_FUNC_ALL, .has_get_level = IC2730_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(IC2730_LEVEL_ALL), .has_get_parm = IC2730_PARM_ALL, .has_set_parm = IC2730_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC2730_VFO_OPS, .scan_ops = IC2730_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, {MHz(375), MHz(550), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC2730_MODES, W(5), W(25), IC2730_VFO_ALL}, {MHz(430), MHz(440), IC2730_MODES, W(5), W(25), IC2730_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, {MHz(375), MHz(550), IC2730_ALL_RX_MODES, -1, -1, IC2730_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC2730_MODES, W(5), W(50), IC2730_VFO_ALL}, {MHz(430), MHz(450), IC2730_MODES, W(5), W(50), IC2730_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {IC2730_ALL_RX_MODES, kHz(5)}, {IC2730_ALL_RX_MODES, kHz(6.25)}, // The 8.33 kHz step is not selectable, depending on the operating band or mode. {IC2730_ALL_RX_MODES, kHz(8.33)}, {IC2730_ALL_RX_MODES, kHz(10)}, {IC2730_ALL_RX_MODES, 12500}, {IC2730_ALL_RX_MODES, kHz(15)}, {IC2730_ALL_RX_MODES, kHz(20)}, {IC2730_ALL_RX_MODES, kHz(25)}, {IC2730_ALL_RX_MODES, kHz(30)}, {IC2730_ALL_RX_MODES, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, RIG_FLT_END, }, .str_cal = IC2730_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic2730_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_powerstat = icom_set_powerstat, .get_powerstat = icom_get_powerstat, .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_code, .get_dcs_sql = icom_get_dcs_code, .set_split_vfo = icom_set_split_vfo, .get_split_vfo = icom_get_split_vfo, .set_split_freq = icom_set_split_freq, .get_split_freq = icom_get_split_freq, .set_split_mode = icom_set_split_mode, .get_split_mode = icom_get_split_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/icr20.c0000644000175000017500000001122714752216205012665 00000000000000/* * Hamlib CI-V backend - description of IC-R20 * Copyright (c) 2004 by Stephane Fillod * Copyright (c) 2004 by Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #include "idx_builtin.h" #define ICR20_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_WFM) #define ICR20_FUNC_ALL (RIG_FUNC_NONE) #define ICR20_LEVEL_ALL (RIG_LEVEL_RAWSTR) #define ICR20_VFO_ALL (RIG_VFO_A) #define ICR20_VFO_OPS (RIG_OP_NONE) #define ICR20_SCAN_OPS (RIG_SCAN_NONE) #define ICR20_STR_CAL { 2, \ { \ { 0, -60 }, /* S0 */ \ { 255, 60 } /* +60 */ \ } } static struct icom_priv_caps icr20_priv_caps = { 0x6c, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ r8500_ts_sc_list /* wrong, but don't have set_ts anyway */ }; struct rig_caps icr20_caps = { RIG_MODEL(RIG_MODEL_ICR20), .model_name = "IC-R20", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER | RIG_FLAG_HANDHELD, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ICR20_FUNC_ALL, .has_set_func = ICR20_FUNC_ALL, .has_get_level = ICR20_LEVEL_ALL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_icom.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICR20_VFO_OPS, .scan_ops = ICR20_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, /* Only through cloning mode OPC-1382 */ .chan_list = { { 1, 999, RIG_MTYPE_MEM }, /* TBC */ { 1000, 1199, RIG_MTYPE_MEM }, /* auto-write */ { 1200, 1249, RIG_MTYPE_EDGE }, /* two by two */ RIG_CHAN_END, }, .rx_range_list1 = { /* Other countries but France */ {kHz(150), GHz(3.304999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { /* USA */ {kHz(150), MHz(821.999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, {MHz(851), MHz(866.999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, {MHz(896), GHz(1.304999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, {GHz(1.305), GHz(3.304999), ICR20_MODES, -1, -1, ICR20_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ICR20_MODES, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(1.8)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12)}, {RIG_MODE_WFM, kHz(150)}, RIG_FLT_END, }, .str_cal = ICR20_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& icr20_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, /* TODO: do not pass bandwidth data */ .get_mode = icom_get_mode, /* .set_vfo = icom_set_vfo, */ .decode_event = icom_decode_event, .get_level = icom_get_level, .get_dcd = icom_get_dcd, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/ic271.c0000644000175000017500000001030714752216205012571 00000000000000/* * Hamlib CI-V backend - description of IC-271 and variations * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icom.h" #define IC271_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define IC271_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define IC271_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) /* * IC-271 A/E * IC-271 H is high power (75W) * * Independent transmit/receive * * specs: http://www.qsl.net/sm7vhs/radio/icom/Ic271/specs.htm * * Please report testing / patches. Some capabilities may be missing too. --sf */ static const struct icom_priv_caps ic271_priv_caps = { 0x20, /* default address */ 0, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; struct rig_caps ic271_caps = { RIG_MODEL(RIG_MODEL_IC271), .model_name = "IC-271", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = IC271_VFO_OPS, .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 32, RIG_MTYPE_MEM, IC_MIN_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), IC271_MODES, -1, -1, IC271_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), IC271_MODES, W(2.5), W(25), IC271_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(143.8), MHz(148.2), IC271_MODES, -1, -1, IC271_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), IC271_MODES, W(2.5), W(25), IC271_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {IC271_MODES, 10}, /* TBC: does this rig supports setting tuning step? */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic271_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/id31.c0000644000175000017500000001365614752216205012516 00000000000000/* * Hamlib CI-V backend - description of ID-31 and variations * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2019 by Malcolm Herring * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "idx_builtin.h" #include "icom.h" #include "tones.h" /* * Specs and protocol details comes from the chapter 11 of ID-31A_E_CD_ENG_1.pdf * * NB: while the port labeled "Data" is used for firmware upgrades, * you have to use the port labeled "SP" for rig control. * */ #define ID31_MODES (RIG_MODE_FM|RIG_MODE_DSTAR) #define ID31_ALL_RX_MODES (RIG_MODE_AM|ID31_MODES) #define ID31_VFO_ALL (RIG_VFO_MAIN) #define ID31_SCAN_OPS RIG_SCAN_NONE #define ID31_VFO_OPS RIG_OP_NONE #define ID31_FUNC_ALL ( \ RIG_FUNC_TONE| \ RIG_FUNC_TSQL| \ RIG_FUNC_CSQL| \ RIG_FUNC_DSQL| \ RIG_FUNC_VOX) #define ID31_LEVEL_ALL (RIG_LEVEL_AF| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_RFPOWER| \ RIG_LEVEL_MICGAIN| \ RIG_LEVEL_VOXGAIN) #define ID31_PARM_ALL RIG_PARM_NONE /* * FIXME: real measurement */ #define ID31_STR_CAL UNKNOWN_IC_STR_CAL /* */ static struct icom_priv_caps id31_priv_caps = { 0xA0, /* default address */ 0, /* 731 mode */ 1, /* no XCHG */ }; struct rig_caps id31_caps = { RIG_MODEL(RIG_MODEL_ID31), .model_name = "ID-31", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = ID31_FUNC_ALL, .has_set_func = ID31_FUNC_ALL, .has_get_level = ID31_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ID31_LEVEL_ALL), .has_get_parm = ID31_PARM_ALL, .has_set_parm = ID31_PARM_ALL, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .extparms = icom_ext_parms, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = full_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ID31_VFO_OPS, .scan_ops = ID31_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { // There's no memory support through CI-V, // but there is a clone mode apart. RIG_CHAN_END, }, .rx_range_list1 = { {MHz(400), MHz(479), ID31_ALL_RX_MODES, -1, -1, ID31_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(430), MHz(440), ID31_MODES, W(2.5), W(5), ID31_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(400), MHz(479), ID31_ALL_RX_MODES, -1, -1, ID31_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(440), MHz(450), ID31_MODES, W(2.5), W(5), ID31_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = ID31_STR_CAL, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& id31_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_powerstat = icom_set_powerstat, // .get_powerstat = icom_get_powerstat, // not capable .decode_event = icom_decode_event, .set_func = icom_set_func, .get_func = icom_get_func, .set_level = icom_set_level, .get_level = icom_get_level, .set_parm = icom_set_parm, .get_parm = icom_get_parm, .set_ext_parm = icom_set_ext_parm, .get_ext_parm = icom_get_ext_parm, .set_ptt = icom_set_ptt, .get_ptt = icom_get_ptt, .get_dcd = icom_get_dcd, .set_rptr_shift = icom_set_rptr_shift, .get_rptr_shift = icom_get_rptr_shift, .set_rptr_offs = icom_set_rptr_offs, .get_rptr_offs = icom_get_rptr_offs, .set_ctcss_tone = icom_set_ctcss_tone, .get_ctcss_tone = icom_get_ctcss_tone, .set_dcs_code = icom_set_dcs_code, .get_dcs_code = icom_get_dcs_code, .set_ctcss_sql = icom_set_ctcss_sql, .get_ctcss_sql = icom_get_ctcss_sql, .set_dcs_sql = icom_set_dcs_sql, .get_dcs_sql = icom_get_dcs_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icom/optoscan.h0000644000175000017500000000424214752216205013600 00000000000000/* * Hamlib CI-V backend - main header * Copyright (c) 2000-2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _OPTOSCAN_H #define _OPTOSCAN_H 1 #include #include "icom_defs.h" #define TOK_TAPECNTL TOKEN_BACKEND(1) #define TOK_5KHZWIN TOKEN_BACKEND(2) #define TOK_SPEAKER TOKEN_BACKEND(3) #define TOK_AUDIO TOKEN_BACKEND(4) #define TOK_DTMFPEND TOKEN_BACKEND(5) #define TOK_DTMFOVRR TOKEN_BACKEND(6) #define TOK_CTCSSACT TOKEN_BACKEND(7) #define TOK_DCSACT TOKEN_BACKEND(8) #define OPTO_BUFF_SIZE 64 int optoscan_open(RIG *rig); int optoscan_close(RIG *rig); const char* optoscan_get_info(RIG *rig); int optoscan_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int optoscan_get_dcs_code(RIG * rig, vfo_t vfo, tone_t *code); int optoscan_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length); int optoscan_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int optoscan_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int optoscan_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int optoscan_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int optoscan_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); struct optostat { int remote_control; int DTMF_pending; int DTMF_overrun; int squelch_open; int CTCSS_active; int DCS_active; int tape_enabled; int speaker_enabled; int fivekhz_enabled; int audio_present; }; #endif /* _OPTOSCAN_H */ hamlib-4.6.2/rigs/icom/ic821h.c0000644000175000017500000001566014752216205012751 00000000000000/* * Hamlib CI-V backend - description of IC-821H (VHF/UHF All-Mode Transceiver) * Contributed by Francois Retief * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "icom.h" #include "misc.h" #define IC821H_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_FM) #define IC821H_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM|RIG_VFO_MAIN|RIG_VFO_SUB) /* FIXME: What about MAIN/SUB mode? And satellite mode? */ #define IC821H_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO|RIG_OP_CPY|RIG_OP_MCL) #define IC821H_SCAN_OPS (RIG_SCAN_MEM) /* FIXME: Manual talks about 3 modes: Programmed scan, Memory scan and * Mode select memory scan operation. How do i encode these? */ #define IC821H_STR_CAL { 0, { } } /* */ static const struct icom_priv_caps ic821h_priv_caps = { 0x4c, /* default address */ 1, /* 731 mode */ 0, /* no XCHG */ ic737_ts_sc_list }; // split could be on VFOA/B or Main/Sub // If Main/Sub we assume we're doing satmode int ic821h_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int retval = -RIG_EINTERNAL; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, split=%d, tx_vfo=%s\n", __func__, rig_strvfo(vfo), split, rig_strvfo(tx_vfo)); if (tx_vfo == RIG_VFO_MAIN) { CACHE(rig)->satmode = split; // we emulate satmode of other rigs since we apparently can't query rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo==MAIN so assuming sat mode=%d\n", __func__, CACHE(rig)->satmode); STATE(rig)->tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_SUB : RIG_VFO_MAIN; // the IC821 seems to be backwards in satmode -- setting Main select Sub and vice versa retval = rig_set_vfo(rig, RIG_VFO_SUB); } else if (tx_vfo == RIG_VFO_A) { retval = rig_set_vfo(rig, RIG_VFO_A); STATE(rig)->tx_vfo = split == RIG_SPLIT_ON ? RIG_VFO_B : RIG_VFO_A; } else { rig_debug(RIG_DEBUG_ERR, "%s: vfo=%s not handled for split mode\n", __func__, rig_strvfo(tx_vfo)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } struct rig_caps ic821h_caps = { RIG_MODEL(RIG_MODEL_IC821H), .model_name = "IC-821H", .mfg_name = "Icom", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, /* Attanuator 15dB for each band. manual button */ .max_rit = Hz(0), /* SSB,CW: +-1.0kHz FM: +-5.0kHz */ .max_xit = Hz(0), .max_ifshift = Hz(0), /* 1.2kHz manual knob */ .targetable_vfo = 0, .vfo_ops = IC821H_VFO_OPS, .scan_ops = IC821H_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { /* FIXME: Each band has 80 channels (2*80) */ { 1, 80, RIG_MTYPE_MEM }, { 81, 82, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(136), MHz(174), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, {MHz(430), MHz(450), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146), RIG_MODE_SSB, W(6), W(35), IC821H_VFO_ALL}, {MHz(144), MHz(146), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC821H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_SSB, W(6), W(30), IC821H_VFO_ALL}, {MHz(430), MHz(440), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC821H_VFO_ALL}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(136), MHz(174), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, {MHz(430), MHz(450), IC821H_MODES, -1, -1, IC821H_VFO_ALL}, RIG_FRNG_END, }, /* * From manual: VHF UHF * USA 144.0-148.0 MHz 430.0-450.0 MHz * Europe 144.0-146.0 MHz 430.0-440.0 MHz * Australia 144.0-148.0 MHz 430.0-450.0 MHz * Sweden 144.0-146.0 MHz 432.0-438.0 MHz */ .tx_range_list2 = { {MHz(144), MHz(148), RIG_MODE_SSB, W(6), W(35), IC821H_VFO_ALL}, {MHz(144), MHz(148), RIG_MODE_FM | RIG_MODE_CW, W(6), W(45), IC821H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_SSB, W(6), W(30), IC821H_VFO_ALL}, {MHz(430), MHz(450), RIG_MODE_FM | RIG_MODE_CW, W(6), W(40), IC821H_VFO_ALL}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_SSB | RIG_MODE_CW, 10}, {RIG_MODE_SSB | RIG_MODE_CW, 50}, {RIG_MODE_SSB | RIG_MODE_CW, 100}, {RIG_MODE_FM, kHz(5)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.3)}, /* built-in */ {RIG_MODE_FM, kHz(15)}, /* built-in */ RIG_FLT_END, }, .cfgparams = icom_cfg_params, .set_conf = icom_set_conf, .get_conf = icom_get_conf, .priv = (void *)& ic821h_priv_caps, .rig_init = icom_init, .rig_cleanup = icom_cleanup, .rig_open = icom_rig_open, .rig_close = icom_rig_close, .set_freq = icom_set_freq, .get_freq = icom_get_freq, .set_mode = icom_set_mode, .get_mode = icom_get_mode, .set_vfo = icom_set_vfo, .set_split_vfo = ic821h_set_split_vfo, .decode_event = icom_decode_event, .set_mem = icom_set_mem, .vfo_op = icom_vfo_op, .scan = icom_scan, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kachina/0000755000175000017500000000000014752216243012330 500000000000000hamlib-4.6.2/rigs/kachina/Makefile.am0000644000175000017500000000023314752216205014300 00000000000000KACHINASRC = 505dsp.c kachina.c kachina.h noinst_LTLIBRARIES = libhamlib-kachina.la libhamlib_kachina_la_SOURCES = $(KACHINASRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/kachina/Makefile.in0000644000175000017500000005242214752216216014322 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/kachina ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_kachina_la_LIBADD = am__objects_1 = 505dsp.lo kachina.lo am_libhamlib_kachina_la_OBJECTS = $(am__objects_1) libhamlib_kachina_la_OBJECTS = $(am_libhamlib_kachina_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/505dsp.Plo ./$(DEPDIR)/kachina.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_kachina_la_SOURCES) DIST_SOURCES = $(libhamlib_kachina_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ KACHINASRC = 505dsp.c kachina.c kachina.h noinst_LTLIBRARIES = libhamlib-kachina.la libhamlib_kachina_la_SOURCES = $(KACHINASRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/kachina/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/kachina/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-kachina.la: $(libhamlib_kachina_la_OBJECTS) $(libhamlib_kachina_la_DEPENDENCIES) $(EXTRA_libhamlib_kachina_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_kachina_la_OBJECTS) $(libhamlib_kachina_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/505dsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kachina.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/505dsp.Plo -rm -f ./$(DEPDIR)/kachina.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/505dsp.Plo -rm -f ./$(DEPDIR)/kachina.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/kachina/Android.mk0000644000175000017500000000040514752216205014156 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := 505dsp.c kachina.c LOCAL_MODULE := kachina LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/kachina/505dsp.c0000644000175000017500000001315614752216205013440 00000000000000/* * Hamlib Kachina backend - 505DSP description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kachina.h" #include #define K505DSP_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define K505DSP_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define K505DSP_AM_TX_MODES RIG_MODE_AM #define K505DSP_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TONE|RIG_FUNC_COMP) #define K505DSP_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|RIG_LEVEL_BKINDL|RIG_LEVEL_CWPITCH) #define K505DSP_PARM_ALL (RIG_PARM_NONE) #define K505DSP_VFO (RIG_VFO_A) #define dBm2S9(x) ((x)+73) #define K505DSP_STR_CAL { 2, { \ { 0, dBm2S9(-130) }, \ { 127, dBm2S9(20) }, \ } } /* * 505DSP rig capabilities. * * protocol is documented at * http://www.kachina-az.com/develope.htm * * TODO: * - so many ... */ struct rig_caps k505dsp_caps = { RIG_MODEL(RIG_MODEL_505DSP), .model_name = "505DSP", .mfg_name = "Kachina", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 2, .has_get_func = K505DSP_FUNC, .has_set_func = K505DSP_FUNC, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_SET(K505DSP_LEVEL_ALL), .has_get_parm = K505DSP_PARM_ALL, .has_set_parm = RIG_PARM_SET(K505DSP_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END }, .max_rit = Hz(9900), .max_xit = Hz(0), .max_ifshift = Hz(1270), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30), K505DSP_ALL_MODES, -1, -1, K505DSP_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 100, K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(1800), MHz(2) - 100, K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(3500), MHz(4) - 100, K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(3500), MHz(4) - 100, K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(7), kHz(7300), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(7), kHz(7300), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(10100), kHz(10150), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(10100), kHz(10150), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(14), kHz(14350), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(14), kHz(14350), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(18068), kHz(18168), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(18068), kHz(18168), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(21), kHz(21450), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(21), kHz(21450), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {kHz(24895), kHz(24995), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {kHz(24895), kHz(24995), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, {MHz(28), kHz(29700), K505DSP_OTHER_TX_MODES, W(10), W(100), K505DSP_VFO}, {MHz(28), kHz(29700), K505DSP_AM_TX_MODES, W(4), W(25), K505DSP_VFO}, RIG_FRNG_END, }, .tuning_steps = { {K505DSP_ALL_MODES, 1}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.1)}, {RIG_MODE_SSB, kHz(3.5)}, {RIG_MODE_SSB, kHz(1.7)}, {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = K505DSP_STR_CAL, .set_freq = kachina_set_freq, .set_mode = kachina_set_mode, .set_ptt = kachina_set_ptt, .get_level = kachina_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kachina/kachina.h0000644000175000017500000000241114752216205014013 00000000000000/* * Hamlib Kachina backend - main header * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _KACHINA_H #define _KACHINA_H 1 #include #define BACKEND_VER "20240420" int kachina_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int kachina_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int kachina_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int kachina_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern struct rig_caps k505dsp_caps; #endif /* _KACHINA_H */ hamlib-4.6.2/rigs/kachina/kachina.c0000644000175000017500000001506314752216205014015 00000000000000/* * Hamlib Kachina backend - main file * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "kachina.h" /* * protocol format */ #define STX 0x02 #define ETX 0x03 #define GDCMD 0xff #define ERRCMD 0xfe /* * modes in use by the "M" command */ #define M_AM 0x01 #define M_CW 0x02 #define M_FM 0x03 #define M_USB 0x04 #define M_LSB 0x05 #define DDS_CONST 2.2369621333 #define DDS_BASE 75000000 /* uppermost 2 bits of the high byte * designating the antenna port in DDS calculation */ #define PORT_AB 0x00 #define PORT_A 0x40 #define PORT_B 0x80 #define PORT_BA 0xc0 /* * kachina_transaction * We assume that rig!=NULL, STATE(rig)!= NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ static int kachina_transaction(RIG *rig, unsigned char cmd1, unsigned char cmd2) { int count, retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char buf4[4]; buf4[0] = STX; buf4[1] = cmd1; buf4[2] = cmd2; buf4[3] = ETX; rig_flush(rp); retval = write_block(rp, buf4, 4); if (retval != RIG_OK) { return retval; } count = read_string(rp, buf4, 1, "", 0, 0, 1); if (count != 1) { return count; } return (buf4[0] == GDCMD) ? RIG_OK : -RIG_EPROTO; } static int kachina_trans_n(RIG *rig, unsigned char cmd1, const char *data, int data_len) { int cmd_len, count, retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char buf[16]; buf[0] = STX; buf[1] = cmd1; memcpy(buf + 2, data, data_len); buf[data_len + 2] = ETX; cmd_len = data_len + 3; rig_flush(rp); retval = write_block(rp, buf, cmd_len); if (retval != RIG_OK) { return retval; } count = read_string(rp, buf, 1, "", 0, 0, 1); if (count != 1) { return count; } return (buf[0] == GDCMD) ? RIG_OK : -RIG_EPROTO; } /* * convert a frequency in Hz in the range of 30kHz to 30MHz * to DDS value, as expected by the Kachina. */ static void freq2dds(freq_t freq, int ant_port, unsigned char fbuf[4]) { double dds; unsigned long dds_ulong; dds = DDS_CONST * (DDS_BASE + freq); dds_ulong = (unsigned long)dds; /* * byte 0 transferred first, * dds is big endian format */ fbuf[0] = ant_port | ((dds_ulong >> 24) & 0x3f); fbuf[1] = (dds_ulong >> 16) & 0xff; fbuf[2] = (dds_ulong >> 8) & 0xff; fbuf[3] = dds_ulong & 0xff; } /* * kachina_set_freq * Assumes rig!=NULL */ int kachina_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; unsigned char freqbuf[4]; freq2dds(freq, PORT_A, freqbuf); /* receive frequency */ retval = kachina_trans_n(rig, 'R', (char *) freqbuf, 4); if (retval != RIG_OK) { return retval; } /* transmit frequency */ retval = kachina_trans_n(rig, 'T', (char *) freqbuf, 4); return retval; } int kachina_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char c = ptt == 0 ? 0x00 : 0x01; int retval = kachina_trans_n(rig, 'x', &c, 1); return retval; } /* * kachina_set_mode * Assumes rig!=NULL * * FIXME: pbwidth handling */ int kachina_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; unsigned char k_mode; switch (mode) { case RIG_MODE_CW: k_mode = M_CW; break; case RIG_MODE_USB: k_mode = M_USB; break; case RIG_MODE_LSB: k_mode = M_LSB; break; case RIG_MODE_FM: k_mode = M_FM; break; case RIG_MODE_AM: k_mode = M_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } retval = kachina_transaction(rig, 'M', k_mode); if (retval != RIG_OK) { return retval; } return retval; } /* * kachina_get_level * Assumes rig!=NULL */ int kachina_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int i, count; unsigned char buf[32]; hamlib_port_t *rp = RIGPORT(rig); static const char rcv_signal_range[128] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f }; /* so far, only RAWSTR supported! */ if (level != RIG_LEVEL_RAWSTR) { return -RIG_ENIMPL; } /* telemetry sent to the PC automatically at a 50msec rate */ rig_flush(rp); count = read_string(rp, buf, 31, rcv_signal_range, 128, 0, 1); if (count < 1) { return count; } for (i = 0; i < count; i++) { if (buf[i] <= 0x7f) { break; } } val->i = buf[i]; return RIG_OK; } /* * initrigs_kachina is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(kachina) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&k505dsp_caps); return RIG_OK; } hamlib-4.6.2/rigs/barrett/0000755000175000017500000000000014752216242012374 500000000000000hamlib-4.6.2/rigs/barrett/Makefile.am0000644000175000017500000000024614752216205014351 00000000000000BARRETTSRC = barrett.c barrett.h 950.c 4050.c 4100.c noinst_LTLIBRARIES = libhamlib-barrett.la libhamlib_barrett_la_SOURCES = $(BARRETTSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/barrett/Makefile.in0000644000175000017500000005316314752216216014372 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/barrett ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_barrett_la_LIBADD = am__objects_1 = barrett.lo 950.lo 4050.lo 4100.lo am_libhamlib_barrett_la_OBJECTS = $(am__objects_1) libhamlib_barrett_la_OBJECTS = $(am_libhamlib_barrett_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/4050.Plo ./$(DEPDIR)/4100.Plo \ ./$(DEPDIR)/950.Plo ./$(DEPDIR)/barrett.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_barrett_la_SOURCES) DIST_SOURCES = $(libhamlib_barrett_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ BARRETTSRC = barrett.c barrett.h 950.c 4050.c 4100.c noinst_LTLIBRARIES = libhamlib-barrett.la libhamlib_barrett_la_SOURCES = $(BARRETTSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/barrett/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/barrett/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-barrett.la: $(libhamlib_barrett_la_OBJECTS) $(libhamlib_barrett_la_DEPENDENCIES) $(EXTRA_libhamlib_barrett_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_barrett_la_OBJECTS) $(libhamlib_barrett_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/4050.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/4100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/950.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/barrett.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/4050.Plo -rm -f ./$(DEPDIR)/4100.Plo -rm -f ./$(DEPDIR)/950.Plo -rm -f ./$(DEPDIR)/barrett.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/4050.Plo -rm -f ./$(DEPDIR)/4100.Plo -rm -f ./$(DEPDIR)/950.Plo -rm -f ./$(DEPDIR)/barrett.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/barrett/4050.c0000644000175000017500000001202414752216205013046 00000000000000/* * Hamlib Barrett 4050 backend - main file * Copyright (c) 2017-2022 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "misc.h" #include "barrett.h" #define MAXCMDLEN 32 #define BARRETT4050_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define BARRETT4050_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_SSB) #define BARRETT4050_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_STRENGTH) #define BARRETT4050_FUNCTIONS (RIG_FUNC_TUNER) extern int barret950_get_freq(RIG *rig, vfo_t vfo, freq_t freq); /* * barrett4050_get_info */ static const char *barrett4050_get_info(RIG *rig) { char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction(rig, "IV", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "Software Version %s\n", response); } return response; } static int barrett4050_open(RIG *rig) { int retval; char *response; struct barrett_priv_data *priv = STATE(rig)->priv; ENTERFUNC; barrett4050_get_info(rig); retval = barrett_transaction(rig, "IDC9999", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: channel 9999 info=%s\n", __func__, response); priv->channel_base = 9990; } retval = barrett_transaction(rig, "XC9999", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } retval = barrett_transaction(rig, "IC", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } RETURNFUNC(RIG_OK); } struct rig_caps barrett4050_caps = { RIG_MODEL(RIG_MODEL_BARRETT_4050), .model_name = "4050", .mfg_name = "Barrett", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = BARRETT4050_FUNCTIONS, .has_set_func = BARRETT4050_FUNCTIONS, .has_get_level = BARRETT4050_LEVELS, .has_set_level = RIG_LEVEL_AGC, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = BARRETT4050_MODES, .low_power = -1, .high_power = -1, BARRETT4050_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT4050_MODES, 1}, {BARRETT4050_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, .rig_init = barrett_init, .rig_cleanup = barrett_cleanup, .rig_open = barrett4050_open, // Barrett said eeprom is good for 1M writes so channelized should be OK for a long time // TC command was not implemented as of 2022-01-12 which would be better .set_freq = barrett950_set_freq, .get_freq = barrett_get_freq, .set_mode = barrett_set_mode, .get_mode = barrett_get_mode, .set_level = barrett_set_level, .get_level = barrett_get_level, .get_info = barrett4050_get_info, .set_ptt = barrett_set_ptt, .get_ptt = barrett_get_ptt, .set_split_freq = barrett_set_split_freq, .set_split_vfo = barrett_set_split_vfo, .get_split_vfo = barrett_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/barrett/950.c0000644000175000017500000001675414752216205013011 00000000000000/* * Hamlib Barrett 950 backend - main file * Copyright (c) 2017-2020 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "barrett.h" #define MAXCMDLEN 32 #define BARRETT950_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define BARRETT950_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_SSB) #define BARRETT950_LEVELS (RIG_LEVEL_NONE) int barrett950_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int barrett950_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *barrett950_get_info(RIG *rig); // 10 band channel from 441 to 450 #define CHANNEL_BASE 441 struct chan_map_s { float lo, hi; int chan_offset; }; // Our 10 bands static struct chan_map_s chan_map[] = { { 0, 3.5, 0}, { 3.5, 5.3, 1}, { 5.3, 7.0, 2}, { 7.0, 10.1, 3}, { 10.1, 14.0, 4}, { 14.0, 18.068, 5}, { 18.068, 21.0, 6}, { 21.0, 24.89, 7}, { 24.89, 28.0, 8}, { 28.0, 30.0, 9} }; struct rig_caps barrett950_caps = { RIG_MODEL(RIG_MODEL_BARRETT_950), .model_name = "950", .mfg_name = "Barrett", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = BARRETT950_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = BARRETT950_MODES, .low_power = -1, .high_power = -1, BARRETT950_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT950_MODES, 1}, {BARRETT950_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, .rig_init = barrett_init, .rig_cleanup = barrett_cleanup, .set_freq = barrett950_set_freq, .get_freq = barrett_get_freq, .set_mode = barrett_set_mode, .get_mode = barrett_get_mode, .get_level = barrett950_get_level, .get_info = barrett950_get_info, .set_ptt = barrett_set_ptt, .get_ptt = NULL, .set_split_freq = barrett_set_split_freq, .set_split_vfo = barrett_set_split_vfo, .get_split_vfo = barrett_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * barrett950_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int barrett950_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd_buf[MAXCMDLEN]; int retval; int i; int chan = -1; freq_t freq_rx, freq_tx; freq_t freq_MHz; char *response = NULL; const struct barrett_priv_data *priv = STATE(rig)->priv; //struct barrett_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); // 950 can only set freq via memory channel // So we make a 10-channel memory from 441-450 by band // And we don't care about VFO -- we set TX=RX to avoid doing split freq changes // Trying to minimize writes to EEPROM // What band is being requested? freq_MHz = freq / 1e6; for (i = 0; i < 10; ++i) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Mhz=%lg, lo=%lg, hi=%lg\n", __func__, freq_MHz, chan_map[i].lo, chan_map[i].hi); if (freq_MHz >= chan_map[i].lo && freq_MHz <= chan_map[i].hi) { int channel_base = priv->channel_base; chan = channel_base + chan_map[i].chan_offset; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: using chan %d for freq %.0f \n", __func__, chan, freq); // Set the channel SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "XC%04d", chan); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } // Read the current channel for the requested freq to see if it needs changing SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "IDC%04d", chan); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } if (strstr(response, "E5")) { freq_rx = freq_tx = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: new channel being programmed\n", __func__); } else if (sscanf(response, "%4d%8lf%8lf", &chan, &freq_rx, &freq_tx) != 3) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse chan/freq from %s\n", __func__, response); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: got chan %d, freq_rx=%.0f, freq_tx=%.0f", __func__, chan, freq_rx, freq_tx); if (freq_rx == freq && freq_tx == freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: no freq change needed\n", __func__); return RIG_OK; } // New freq so let's update the channel // We do not support split mode -- too many writes to EEPROM to support it SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "PC%04dR%08.0lfT%08.0lf", chan, freq, freq); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval != RIG_OK || strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * barrett950_get_level */ int barrett950_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { return -RIG_ENIMPL; } /* * barrett950_get_info */ const char *barrett950_get_info(RIG *rig) { char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction(rig, "IV", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "Software Version %s\n", response); } return response; } hamlib-4.6.2/rigs/barrett/barrett.h0000644000175000017500000000603114752216205014127 00000000000000/* * Hamlib Barrett backend - main header * Copyright (c) 2017 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _BARRETT_H #define _BARRETT_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20240422" #define EOM "\x0d" #define TRUE 1 #define FALSE 0 // For the current implemented command set 64 is long enough // This will need a lot more room for some channel commands like IDFA which return all channels // But that would 9999*41 or 406KB so didn't do that right now #define BARRETT_DATA_LEN 64 // RET_LEN is # of max channels times the per-channel response length #define BARRETT_RET_LEN 24*1000 extern struct rig_caps barrett_caps; extern struct rig_caps barrett950_caps; extern struct rig_caps barrett4050_caps; extern struct rig_caps barrett4100_caps; struct barrett_priv_data { char cmd_str[BARRETT_DATA_LEN]; /* command string buffer */ char ret_data[BARRETT_RET_LEN]; /* returned data--max value, most are less */ char split; /* split on/off */ int channel_base; /* base channel for 0-9 10-channel assignment if needed */ }; extern int barrett_transaction(RIG *rig, char *cmd, int expected, char **result); extern int barrett_transaction2(RIG *rig, char *cmd, int expected, char **result); extern int barrett_init(RIG *rig); extern int barrett_cleanup(RIG *rig); extern int barrett_open(RIG *rig); extern int barrett950_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern int barrett_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); extern int barrett_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern int barrett_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); extern int barrett_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); extern int barrett_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); extern int barrett_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); extern int barrett_set_split_vfo(RIG *rig, vfo_t rxvfo, split_t split, vfo_t txvfo); extern int barrett_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); extern int barrett_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern int barrett_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); #endif /* _BARRETT_H */ hamlib-4.6.2/rigs/barrett/Android.mk0000644000175000017500000000041414752216205014223 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := barrett.c barrett.h 950.c LOCAL_MODULE := barrett LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/barrett/barrett.c0000644000175000017500000005706514752216205014137 00000000000000/* * Hamlib Barrett backend - main file * Copyright (c) 2017 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "serial.h" #include "misc.h" #include "register.h" #include "barrett.h" #define MAXCMDLEN 32 #define BARRETT_VFOS (RIG_VFO_A|RIG_VFO_MEM) #define BARRETT_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_SSB) #define BARRETT_LEVELS (RIG_LEVEL_STRENGTH) DECLARE_INITRIG_BACKEND(barrett) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&barrett_caps); rig_register(&barrett950_caps); rig_register(&barrett4050_caps); rig_register(&barrett4100_caps); rig_debug(RIG_DEBUG_VERBOSE, "%s: _init back from rig_register\n", __func__); return RIG_OK; } void barrett_flush(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); int timesave = STATE(rig)->timeout; STATE(rig)->timeout = 0; rig_flush(rp); STATE(rig)->timeout = timesave; } // this version is for 4100 int barrett_transaction2(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; struct barrett_priv_data *priv = STATE(rig)->priv; int retval; hamlib_port_t *rp = RIGPORT(rig); SNPRINTF(cmd_buf, sizeof(cmd_buf), "%c%s%s", 0x0a, cmd, EOM); barrett_flush(rig); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in write_block\n", __func__, __LINE__); return retval; } retval = read_block(RIGPORT(rig), (unsigned char *) priv->ret_data, expected); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_block\n", __func__, __LINE__); return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %d bytes read\n", __func__, __LINE__, retval); if (priv->ret_data[0] == 0x13) // we'll return from the 1st good char { *result = &(priv->ret_data[1]); } else // some commands like IAL don't give XOFF but XON is there -- is this a bug? { *result = &(priv->ret_data[0]); } return retval; } int barrett_transaction(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; int retval; char *p; char xon; char xoff; hamlib_port_t *rp = RIGPORT(rig); struct barrett_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, cmd); if (rig->caps->rig_model == RIG_MODEL_BARRETT_4100) { } else { SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s%s", cmd, EOM); } barrett_flush(rig); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { return retval; } if (expected == 0) { // response format is 0x11,data...,0x0d,0x0a,0x13 retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x11", 1, 0, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: resultlen=%d\n", __func__, (int)strlen(priv->ret_data)); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_string\n", __func__, __LINE__); return retval; } } else { retval = read_block(rp, (unsigned char *) priv->ret_data, expected); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s(%d): error in read_block\n", __func__, __LINE__); return retval; } } p = priv->ret_data; xon = p[0]; xoff = p[strlen(p) - 1]; if (xon == 0x13 && xoff == 0x11) { //rig_debug(RIG_DEBUG_TRACE, "%s: removing xoff char\n", __func__); p[strlen(p) - 1] = 0; } else { rig_debug(RIG_DEBUG_WARN, "%s: expected XOFF=0x13 as first and XON=0x11 as last byte, got %02x/%02x\n", __func__, xon, xoff); } //rig_debug(RIG_DEBUG_ERR, "%s: removing xon char\n", __func__); // Remove the XON char if there p = memchr(priv->ret_data, 0x11, strlen(priv->ret_data)); if (p) { *p = 0; } if (result != NULL) { int n = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting result\n", __func__); if (priv->ret_data[0] == 0x13) // we'll return from the 1st good char { *result = &(priv->ret_data[1]); } else // some commands like IAL don't give XOFF but XON is there -- is this a bug? { *result = &(priv->ret_data[0]); } // See how many CR's we have for (p = *result; *p; ++p) { if (*p == 0x0d) { ++n; } } // if only 1 CR then we'll truncate string // Several commands can return multiline strings and we'll leave them alone if (n == 1) { char *dummy; strtok_r(*result, "\r", &dummy); } //rig_debug(RIG_DEBUG_VERBOSE, "%s: returning result=%s\n", __func__, // *result); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: no result requested\n", __func__); } return RIG_OK; } int barrett_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); // cppcheck claims leak here but it's freed in cleanup STATE(rig)->priv = (struct barrett_priv_data *)calloc(1, sizeof(struct barrett_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } /* * barrett_cleanup * */ int barrett_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * barrett_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ int barrett_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *freq = 0; if (vfo == RIG_VFO_B) // We treat the TX VFO as VFO_B and RX VFO as VFO_A { retval = barrett_transaction(rig, "IT", 0, &response); } else { retval = barrett_transaction(rig, "IR", 0, &response); } if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } retval = sscanf(response, "%lg", freq); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse response\n", __func__); return -RIG_EPROTO; } return RIG_OK; } // TC command does not work on 4050 -- not implemented as of 2022-01-12 /* * barrett_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int barrett_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd_buf[MAXCMDLEN]; int retval; const struct barrett_priv_data *priv = STATE(rig)->priv; freq_t tfreq; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); retval = rig_get_freq(rig, vfo, &tfreq); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq failed: %s\n", __func__, strerror(retval)); return retval; } if (tfreq == freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq not changing\n", __func__); return RIG_OK; } // If we are not explicitly asking for VFO_B then we'll set the receive side also if (vfo != RIG_VFO_B) { char *response = NULL; SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TR%08.0f", freq); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } //dump_hex((unsigned char *)response, strlen(response)); if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } } if (priv->split == 0 || vfo == RIG_VFO_B) // if we aren't in split mode we have to set the TX VFO too { char *response = NULL; SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TC9999T%08.0f", freq); retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } } return RIG_OK; } /* * barrett_set_ptt * Assumes rig!=NULL */ int barrett_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_buf[MAXCMDLEN]; char *response; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); // we need a little extra time before we assert PTT // testing with rigctld worked, but from WSJT-X did not // WSJT-X is just a little faster without the network timing hl_usleep(100 * 1000); SNPRINTF(cmd_buf, sizeof(cmd_buf), "XP%d", ptt); response = NULL; retval = barrett_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } if (strncmp(response, "OK", 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Expected OK, got '%s'\n", __func__, response); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd:IP result=%s\n", __func__, response); return RIG_OK; } /* * barrett_get_ptt * Assumes rig!=NULL */ int barrett_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char *response = NULL; char c; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = barrett_transaction(rig, "IP", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error response?='%s'\n", __func__, response); return retval; } c = response[0]; if (c == '1' || c == '0') { *ptt = c - '0'; } else { rig_debug(RIG_DEBUG_ERR, "%s: error response='%s'\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * barrett_set_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ int barrett_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char cmd_buf[32], ttmode; int retval; rmode_t tmode; pbwidth_t twidth; //struct tt588_priv_data *priv = (struct tt588_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); retval = rig_get_mode(rig, vfo, &tmode, &twidth); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode failed %s\n", __func__, strerror(retval)); } if (tmode == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: already mode %s so not changing\n", __func__, rig_strrmode(mode)); return RIG_OK; } switch (mode) { case RIG_MODE_USB: ttmode = 'U'; break; case RIG_MODE_LSB: ttmode = 'L'; break; case RIG_MODE_CW: ttmode = 'C'; break; case RIG_MODE_AM: ttmode = 'A'; break; case RIG_MODE_RTTY: ttmode = 'F'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TB%c" EOM, ttmode); retval = barrett_transaction(rig, cmd_buf, 0, NULL); if (retval < 0) { return retval; } return RIG_OK; } /* * barrett_get_mode * Assumes rig!=NULL * Note that 2050 does not have set or get width */ int barrett_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *result = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = barrett_transaction(rig, "IB", 0, &result); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad response=%s\n", __func__, result); return retval; } //dump_hex((unsigned char *)result,strlen(result)); switch (result[1]) { case 'L': *mode = RIG_MODE_LSB; break; case 'U': *mode = RIG_MODE_USB; break; case 'A': *mode = RIG_MODE_AM; break; case 'F': *mode = RIG_MODE_RTTY; break; case 'C': *mode = RIG_MODE_CW; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode='%c%c'\n", __func__, result[0], result[1]); return -RIG_EPROTO; } *width = 3000; // we'll default this to 3000 for now rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } #if 0 int barrett_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = RIG_VFO_A; if (check_vfo(*vfo) == FALSE) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } #endif /* * barrett_set_split_freq */ int barrett_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { // The 2050 only has one RX and one TX VFO -- it's not treated as VFOA/VFOB char cmd_buf[MAXCMDLEN]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%g\n", __func__, rig_strvfo(vfo), tx_freq); SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "TT%08.0f" EOM, tx_freq); retval = barrett_transaction(rig, cmd_buf, 0, NULL); if (retval < 0) { return retval; } return RIG_OK; } int barrett_set_split_vfo(RIG *rig, vfo_t rxvfo, split_t split, vfo_t txvfo) { struct barrett_priv_data *priv; priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called rxvfo=%s, txvfo=%s, split=%d\n", __func__, rig_strvfo(rxvfo), rig_strvfo(txvfo), split); priv->split = split; return RIG_OK; } int barrett_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { struct barrett_priv_data *priv; priv = STATE(rig)->priv; *split = priv->split; *txvfo = RIG_VFO_B; // constant rig_debug(RIG_DEBUG_VERBOSE, "%s called rxvfo=%s, txvfo=%s, split=%d\n", __func__, rig_strvfo(rxvfo), rig_strvfo(*txvfo), *split); return RIG_OK; } /* * barrett_get_level */ int barrett_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval = 0; char *response = NULL; switch (level) { int strength; int n; case RIG_LEVEL_STRENGTH: retval = barrett_transaction(rig, "IAL", 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } n = sscanf(response, "%2d", &strength); if (n == 1) { val->i = strength; } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse STRENGTH from %s\n", __func__, response); return -RIG_EPROTO; } break; case RIG_LEVEL_AGC: retval = barrett_transaction(rig, "IGA", 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } if (response[0] == 'H') // then AGC hang is on { val->i = 1; } else { val->i = 0; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s level=%s val=%s\n", __func__, rig_strvfo(vfo), rig_strlevel(level), response); return RIG_OK; } int barrett_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmd_buf[MAXCMDLEN]; hamlib_port_t *rp = RIGPORT(rig); int retval; switch (level) { case RIG_LEVEL_AGC: sprintf(cmd_buf, "EG%c%s", val.i == 0 ? 'N' : 'H', EOM); break; default: return -RIG_ENIMPL; } barrett_flush(rig); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); if (retval < 0) { return retval; } return RIG_OK; } /* * barrett_get_info */ const char *barrett_get_info(RIG *rig) { char *response = NULL; char *series; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction(rig, "IDR", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: IDR command failed: %s\n", __func__, strerror(retval)); series = "unknown"; } else { series = strdup(response); } retval = barrett_transaction(rig, "IDS", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_WARN, "%s: IDS command failed: %s\n", __func__, strerror(retval)); response = "unknown"; } rig_debug(RIG_DEBUG_VERBOSE, "%s: Barrett series %s, serial# %s\n", __func__, series, response); retval = barrett_transaction(rig, "IV", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: IV failed result=%s\n", __func__, response); } else { rig_debug(RIG_DEBUG_VERBOSE, "Barrett software Version %s\n", response); } return response; } int barrett_open(RIG *rig) { ENTERFUNC; barrett_get_info(rig); RETURNFUNC(RIG_OK); } struct rig_caps barrett_caps = { RIG_MODEL(RIG_MODEL_BARRETT_2050), .model_name = "2050", .mfg_name = "Barrett", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = BARRETT_LEVELS, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } }, // .ctcss_list = common_ctcss_list, // .dcs_list = full_dcs_list, // 2050 does have channels...not implemented yet as no need yet // .chan_list = { // { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP }, // { 19, 19, RIG_MTYPE_CALL }, // { 20, NB_CHAN-1, RIG_MTYPE_EDGE }, // RIG_CHAN_END, // }, // .scan_ops = DUMMY_SCAN, // .vfo_ops = DUMMY_VFO_OP, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = BARRETT_MODES, .low_power = -1, .high_power = -1, BARRETT_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT_MODES, 1}, {BARRETT_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, // .extlevels = dummy_ext_levels, // .extparms = dummy_ext_parms, // .cfgparams = dummy_cfg_params, .rig_init = barrett_init, .rig_open = barrett_open, .rig_cleanup = barrett_cleanup, // .set_conf = dummy_set_conf, // .get_conf = dummy_get_conf, .set_freq = barrett_set_freq, .get_freq = barrett_get_freq, .set_mode = barrett_set_mode, .get_mode = barrett_get_mode, // .set_powerstat = dummy_set_powerstat, // .get_powerstat = dummy_get_powerstat, // .set_level = dummy_set_level, .get_level = barrett_get_level, // .set_func = dummy_set_func, // .get_func = dummy_get_func, // .set_parm = dummy_set_parm, // .get_parm = dummy_get_parm, // .set_ext_level = dummy_set_ext_level, // .get_ext_level = dummy_get_ext_level, // .set_ext_parm = dummy_set_ext_parm, // .get_ext_parm = dummy_get_ext_parm, .get_info = barrett_get_info, .set_ptt = barrett_set_ptt, .get_ptt = barrett_get_ptt, // .get_dcd = dummy_get_dcd, // .set_rptr_shift = dummy_set_rptr_shift, // .get_rptr_shift = dummy_get_rptr_shift, // .set_rptr_offs = dummy_set_rptr_offs, // .get_rptr_offs = dummy_get_rptr_offs, // .set_ctcss_tone = dummy_set_ctcss_tone, // .get_ctcss_tone = dummy_get_ctcss_tone, // .set_dcs_code = dummy_set_dcs_code, // .get_dcs_code = dummy_get_dcs_code, // .set_ctcss_sql = dummy_set_ctcss_sql, // .get_ctcss_sql = dummy_get_ctcss_sql, // .set_dcs_sql = dummy_set_dcs_sql, // .get_dcs_sql = dummy_get_dcs_sql, .set_split_freq = barrett_set_split_freq, // .get_split_freq = dummy_get_split_freq, // .set_split_mode = dummy_set_split_mode, // .get_split_mode = dummy_get_split_mode, .set_split_vfo = barrett_set_split_vfo, .get_split_vfo = barrett_get_split_vfo, // .set_rit = dummy_set_rit, // .get_rit = dummy_get_rit, // .set_xit = dummy_set_xit, // .get_xit = dummy_get_xit, // .set_ts = dummy_set_ts, // .get_ts = dummy_get_ts, // .set_ant = dummy_set_ant, // .get_ant = dummy_get_ant, // .set_bank = dummy_set_bank, // .set_mem = dummy_set_mem, // .get_mem = dummy_get_mem, // .vfo_op = dummy_vfo_op, // .scan = dummy_scan, // .send_dtmf = dummy_send_dtmf, // .recv_dtmf = dummy_recv_dtmf, // .send_morse = dummy_send_morse, // .set_channel = dummy_set_channel, // .get_channel = dummy_get_channel, // .set_trn = dummy_set_trn, // .get_trn = dummy_get_trn, // .power2mW = dummy_power2mW, // .mW2power = dummy_mW2power, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/barrett/4100.c0000644000175000017500000002164714752216205013055 00000000000000/* * Hamlib Barrett 4100 backend - main file * Derived from 4050 backend * Copyright (c) 2017-2024 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "misc.h" #include "barrett.h" #define MAXCMDLEN 32 //#define BARRETT4100 VFOS (RIG_VFO_A|RIG_VFO_MEM) // VFO_MEM eventually? #define BARRETT4100 VFOS (RIG_VFO_A) #define BARRETT4100_MODES (RIG_MODE_CW | RIG_MODE_SSB) // Levels eventually //#define BARRETT4100_LEVELS (RIG_LEVEL_AGC|RIG_LEVEL_STRENGTH) // Functions eventually //#define BARRETT4100_FUNCTIONS (RIG_FUNC_TUNER) extern int barret950_get_freq(RIG *rig, vfo_t vfo, freq_t freq); /* * barrett4100_get_info */ static const char *barrett4100_get_info(RIG *rig) { static char *response; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = barrett_transaction2(rig, "M:MIB GM", 64, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "MIB GM: %s\n", response); } retval = barrett_transaction2(rig, "M:FF GM", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "M:MIB GM: %s\n", response); } retval = barrett_transaction2(rig, "M:FF BWA", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "FF BWA: %s\n", response); } retval = barrett_transaction2(rig, "M:FF GRFA", 0, &response); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: error=\"%s\", result=\"%s\"\n", __func__, strerror(retval), response); } else { rig_debug(RIG_DEBUG_VERBOSE, "M:FF GRFA: %s\n", response); } return response; } static int barrett4100_open(RIG *rig) { int retval; char *response; ENTERFUNC; retval = barrett_transaction2(rig, "M:REMOTE SENTER2,1", 3, &response); rig_debug(RIG_DEBUG_ERR, "%s: back from REMOTE SENTER2: got %d\n", __func__, retval); if (response[0] != 's') { rig_debug(RIG_DEBUG_ERR, "%s: REMOTE SENTER2 error: got %s\n", __func__, response); } //barrett4100_get_info(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: success, ret=%d\n", __func__, retval); RETURNFUNC(RIG_OK); } static int barrett4100_close(RIG *rig) { char *response; int retval = barrett_transaction2(rig, "M:REMOTE SENTER0", 18, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } return rig_close(rig); } int barrett4100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char *response; int retval = barrett_transaction2(rig, "M:FF SRF%.0f GRF", freq, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } else { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); freq_t freq2 = 0; int n = sscanf(response, "s gRF%lf", &freq2); if (n == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq set to %.0f\n", __func__, freq2); } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse s gRF\n", __func__); } } retval = barrett_transaction2(rig, "M:FF STF%.0f GTF", freq, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } else { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); freq_t freq2 = 0; int n = sscanf(response, "s gTF%lf", &freq2); if (n == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq set to %.0f\n", __func__, freq2); } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse s gTF\n", __func__); } } return retval; } int barrett4100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char *response; int retval = barrett_transaction2(rig, "M:FF GRF", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } else { int n = sscanf(response, "gRF%lf", freq); //int n = sscanf(response, "gRFA1,%*d,%lf,%*d", freq); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s(%d): unable to parse freq from '%s'\n", __func__, __LINE__, response); return -RIG_EPROTO; } } return retval; } int barrett4100_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char *response; int retval = barrett_transaction2(rig, "M:FF SRPTT%d GRPTT", ptt, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d); response=%s\n", __func__, __LINE__, response); return retval; } int barrett4100_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char *response; int retval = barrett_transaction2(rig, "M:FF GRPTT", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): result=%s\n", __func__, __LINE__, response); } rig_debug(RIG_DEBUG_VERBOSE, "%s(%d); response=%s\n", __func__, __LINE__, response); return retval; } struct rig_caps barrett4100_caps = { RIG_MODEL(RIG_MODEL_BARRETT_4100), .model_name = "4100", .mfg_name = "Rhode&Schwarz", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, // do no promote until somebody confirms it works ok -- nobody to test it .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NETWORK, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, // .has_get_func = BARRETT4100_FUNCTIONS, // .has_set_func = BARRETT4100_FUNCTIONS, // .has_get_level = BARRETT4100_LEVELS, .has_set_level = RIG_LEVEL_AGC, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(10), .endf = MHz(30), .modes = BARRETT4100_MODES, .low_power = -1, .high_power = -1, BARRETT4100_MODES, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {BARRETT4100_MODES, 1}, {BARRETT4100_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(8)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .priv = NULL, .rig_init = barrett_init, .rig_cleanup = barrett_cleanup, .rig_open = barrett4100_open, .rig_close = barrett4100_close, .set_freq = barrett4100_set_freq, .get_freq = barrett4100_get_freq, // .set_mode = barrett_set_mode, // .get_mode = barrett_get_mode, // .set_level = barrett_set_level, // .get_level = barrett_get_level, .get_info = barrett4100_get_info, .set_ptt = barrett4100_set_ptt, .get_ptt = barrett4100_get_ptt, // .set_split_freq = barrett_set_split_freq, // .set_split_vfo = barrett_set_split_vfo, // .get_split_vfo = barrett_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/flexradio/0000755000175000017500000000000014752216242012706 500000000000000hamlib-4.6.2/rigs/flexradio/dttsp.c0000644000175000017500000006010714752216205014133 00000000000000/* * Hamlib DttSP backend - main file * Copyright (c) 2001-2012 by Stephane Fillod * * Some code derived from DttSP * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 by Frank Brickle, AB2KT and Bob McGwier, N4HY * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include "hamlib/rig.h" #include "iofunc.h" #include "misc.h" #include "token.h" #include "cal.h" /* * This backend is a two layer rig control: DttSP core over a mundane tuner * * 2 interfaces of DttSP are supported: IPC & UDP * * TODO: Transmit setup * http://openhpsdr.org/wiki/index.php?title=Ghpsdr */ #define DEFAULT_DTTSP_CMD_PATH "/dev/shm/SDRcommands" #define DEFAULT_DTTSP_CMD_NET_ADDR "127.0.0.1:19001" #define DEFAULT_SAMPLE_RATE 48000 /* DttSP constants */ #define MAXRX 4 #define RXMETERPTS 5 #define TXMETERPTS 9 #define MAXMETERPTS 9 #define DTTSP_PORT_CLIENT_COMMAND 19001 #define DTTSP_PORT_CLIENT_SPECTRUM 19002 #define DTTSP_PORT_CLIENT_METER 19003 #define DTTSP_PORT_CLIENT_BUFSIZE 65536 struct dttsp_priv_data { /* tuner providing IF */ rig_model_t tuner_model; RIG *tuner; shortfreq_t IF_center_freq; int sample_rate; int rx_delta_f; hamlib_port_t meter_port; }; static int dttsp_init(RIG *rig); static int dttsp_cleanup(RIG *rig); static int dttsp_open(RIG *rig); static int dttsp_close(RIG *rig); static int dttsp_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int dttsp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int dttsp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int dttsp_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int dttsp_get_conf(RIG *rig, hamlib_token_t token, char *val); static int dttsp_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int dttsp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int dttsp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int dttsp_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); static int dttsp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int dttsp_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); #define TOK_TUNER_MODEL TOKEN_BACKEND(1) #define TOK_SAMPLE_RATE TOKEN_BACKEND(2) const struct confparams dttsp_cfg_params[] = { { TOK_TUNER_MODEL, "tuner_model", "Tuner model", "Hamlib rig tuner model number", "1" /* RIG_MODEL_DUMMY */, RIG_CONF_NUMERIC, { /* .n = */ { 0, 100000, 1 } } }, { TOK_SAMPLE_RATE, "sample_rate", "Sample rate", "DttSP sample rate in Spls/sec", "48000", RIG_CONF_NUMERIC, { /* .n = */ { 8000, 192000, 1 } } }, /* * TODO: IF_center_freq, etc. */ { RIG_CONF_END, NULL, } }; /* * DttSP dsr-core rig capabilities. */ #define DTTSP_FUNC (RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_NR|RIG_FUNC_MUTE) #define DTTSP_LEVEL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_AGC) #define DTTSP_PARM RIG_PARM_NONE #define DTTSP_VFO_OP RIG_OP_NONE #define DTTSP_SCAN RIG_SCAN_NONE #define DTTSP_VFO (RIG_VFO_A) #define DTTSP_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_SAM|RIG_MODE_DSB| \ RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB) enum dttsp_mode_e { LSB, USB, DSB, CWL, CWU, FMN, AM, DIGU, SPEC, DIGL, SAM, DRM }; static const struct hamlib_vs_dttsp { rmode_t hamlib_mode; enum dttsp_mode_e dttsp_mode; } hamlib_vs_dttsp_modes[] = { { RIG_MODE_USB, USB }, { RIG_MODE_LSB, LSB }, { RIG_MODE_CW, CWU }, { RIG_MODE_CWR, CWL }, { RIG_MODE_AM, AM }, { RIG_MODE_SAM, SAM }, { RIG_MODE_FM, FMN }, { RIG_MODE_DSB, DSB }, }; #define HAMLIB_VS_DTTSP_MODES_COUNT (sizeof(hamlib_vs_dttsp_modes)/sizeof(struct hamlib_vs_dttsp)) #define DTTSP_REAL_STR_CAL { 16, \ { \ { -73, -73 }, /* S0 */ \ { 50, 40 }, /* +40 */ \ } } struct rig_caps dttsp_rig_caps = { RIG_MODEL(RIG_MODEL_DTTSP), .model_name = "DttSP IPC", .mfg_name = "DTTS Microwave Society", .version = "20200319.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .targetable_vfo = RIG_TARGETABLE_ALL, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_DEVICE, .has_get_func = DTTSP_FUNC, .has_set_func = DTTSP_FUNC, .has_get_level = DTTSP_LEVEL, .has_set_level = RIG_LEVEL_SET(DTTSP_LEVEL), .has_get_parm = DTTSP_PARM, .has_set_parm = RIG_PARM_SET(DTTSP_PARM), .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .scan_ops = DTTSP_SCAN, .vfo_ops = DTTSP_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { RIG_DBLST_END, }, /* In fact, RX and TX ranges are dependent on the tuner */ .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* TODO */ .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* TODO */ .tuning_steps = { {DTTSP_MODES, 1}, {DTTSP_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_DSB | RIG_MODE_SAM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, {DTTSP_MODES, RIG_FLT_ANY}, RIG_FLT_END, }, .str_cal = DTTSP_REAL_STR_CAL, .priv = NULL, .rig_init = dttsp_init, .rig_cleanup = dttsp_cleanup, .rig_open = dttsp_open, .rig_close = dttsp_close, .cfgparams = dttsp_cfg_params, .set_conf = dttsp_set_conf, .get_conf = dttsp_get_conf, .set_freq = dttsp_set_freq, .get_freq = dttsp_get_freq, .set_mode = dttsp_set_mode, .set_level = dttsp_set_level, .get_level = dttsp_get_level, .set_func = dttsp_set_func, .set_rit = dttsp_set_rit, .get_rit = dttsp_get_rit, .set_ant = dttsp_set_ant, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * The same as the previous IPC, but of type RIG_PORT_UDP_NETWORK */ struct rig_caps dttsp_udp_rig_caps = { RIG_MODEL(RIG_MODEL_DTTSP_UDP), .model_name = "DttSP UDP", .mfg_name = "DTTS Microwave Society", .version = "20200319.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_COMPUTER, .targetable_vfo = RIG_TARGETABLE_ALL, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_UDP_NETWORK, .timeout = 500, .has_get_func = DTTSP_FUNC, .has_set_func = DTTSP_FUNC, .has_get_level = DTTSP_LEVEL, .has_set_level = RIG_LEVEL_SET(DTTSP_LEVEL), .has_get_parm = DTTSP_PARM, .has_set_parm = RIG_PARM_SET(DTTSP_PARM), .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .scan_ops = DTTSP_SCAN, .vfo_ops = DTTSP_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { RIG_DBLST_END, }, /* In fact, RX and TX ranges are dependent on the tuner */ .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, /* TODO */ .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = DTTSP_MODES, .low_power = -1, .high_power = -1, DTTSP_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, /* TODO */ .tuning_steps = { {DTTSP_MODES, 1}, {DTTSP_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_DSB | RIG_MODE_SAM, kHz(8)}, {RIG_MODE_FM, kHz(15)}, {DTTSP_MODES, RIG_FLT_ANY}, RIG_FLT_END, }, .str_cal = DTTSP_REAL_STR_CAL, .priv = NULL, .rig_init = dttsp_init, .rig_cleanup = dttsp_cleanup, .rig_open = dttsp_open, .rig_close = dttsp_close, .cfgparams = dttsp_cfg_params, .set_conf = dttsp_set_conf, .get_conf = dttsp_get_conf, .set_freq = dttsp_set_freq, .get_freq = dttsp_get_freq, .set_mode = dttsp_set_mode, .set_level = dttsp_set_level, .get_level = dttsp_get_level, .set_func = dttsp_set_func, .set_rit = dttsp_set_rit, .get_rit = dttsp_get_rit, .set_ant = dttsp_set_ant, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int send_command(RIG *rig, const char *cmdstr, size_t buflen) { int ret; ret = write_block(RIGPORT(rig), (unsigned char *) cmdstr, buflen); return ret; } static int fetch_meter(RIG *rig, int *label, float *data, int npts) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret, buf_len; if (priv->meter_port.type.rig == RIG_PORT_UDP_NETWORK) { char buf[sizeof(float)*MAXMETERPTS * MAXRX]; buf_len = sizeof(buf); ret = read_block(&priv->meter_port, (unsigned char *) buf, buf_len); if (ret != buf_len) { ret = -RIG_EIO; } /* copy payload back to client space */ memcpy((void *) label, buf, sizeof(int)); memcpy((void *) data, buf + sizeof(int), npts * sizeof(float)); } else { /* IPC */ buf_len = sizeof(int); ret = read_block(&priv->meter_port, (unsigned char *) label, buf_len); if (ret != buf_len) { ret = -RIG_EIO; } if (ret < 0) { return ret; } buf_len = (int) sizeof(float) * npts; if (sizeof(float) != 4) { rig_debug(RIG_DEBUG_ERR, "%s: sizeof(float)!=4, instead = %d\n", __func__, (int)sizeof(float)); return -RIG_EINTERNAL; } ret = read_block(&priv->meter_port, (unsigned char *) data, buf_len); if (ret != buf_len) { ret = -RIG_EIO; } if (ret < 0) { return ret; } } return ret; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int dttsp_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct dttsp_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct dttsp_priv_data *)rs->priv; switch (token) { case TOK_TUNER_MODEL: priv->tuner_model = atoi(val); break; case TOK_SAMPLE_RATE: priv->sample_rate = atoi(val); break; default: /* if it's not for the dttsp backend, maybe it's for the tuner */ if (priv->tuner) { return rig_set_conf(priv->tuner, token, val); } else { return -RIG_EINVAL; } } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int dttsp_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct dttsp_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct dttsp_priv_data *)rs->priv; switch (token) { case TOK_TUNER_MODEL: SNPRINTF(val, val_len, "%u", priv->tuner_model); break; case TOK_SAMPLE_RATE: SNPRINTF(val, val_len, "%d", priv->sample_rate); break; default: /* if it's not for the dttsp backend, maybe it's for the tuner */ if (priv->tuner) { return rig_get_conf(priv->tuner, token, val); } else { return -RIG_EINVAL; } } return RIG_OK; } int dttsp_get_conf(RIG *rig, hamlib_token_t token, char *val) { return dttsp_get_conf2(rig, token, val, 128); } int dttsp_init(RIG *rig) { struct dttsp_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); const char *cmdpath; char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct dttsp_priv_data *)calloc(1, sizeof(struct dttsp_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->tuner = NULL; priv->tuner_model = RIG_MODEL_DUMMY; priv->IF_center_freq = 0; p = getenv("SDR_DEFRATE"); if (p) { priv->sample_rate = atoi(p); } else { priv->sample_rate = DEFAULT_SAMPLE_RATE; } cmdpath = getenv("SDR_PARMPATH"); if (!cmdpath) cmdpath = rp->type.rig == RIG_PORT_UDP_NETWORK ? DEFAULT_DTTSP_CMD_NET_ADDR : DEFAULT_DTTSP_CMD_PATH; strncpy(rp->pathname, cmdpath, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int dttsp_open(RIG *rig) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret; char *p; char *meterpath; hamlib_port_t *rp = RIGPORT(rig); struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * prevent l8ps */ if (priv->tuner_model == RIG_MODEL_DTTSP || priv->tuner_model == RIG_MODEL_DTTSP_UDP) { return -RIG_ECONF; } priv->tuner = rig_init(priv->tuner_model); if (!priv->tuner) { /* FIXME: wrong rig model? */ return -RIG_ENOMEM; } ret = rig_open(priv->tuner); if (ret != RIG_OK) { rig_cleanup(priv->tuner); priv->tuner = NULL; return ret; } /* open DttSP meter pipe */ priv->meter_port.post_write_delay = rp->post_write_delay; priv->meter_port.timeout = rp->timeout; priv->meter_port.retry = rp->retry; p = getenv("SDR_METERPATH"); if (!p) { meterpath = priv->meter_port.pathname; SNPRINTF(meterpath, HAMLIB_FILPATHLEN, "%s", rp->pathname); if (rp->type.rig == RIG_PORT_UDP_NETWORK) { p = strrchr(meterpath, ':'); if (p) { strcpy(p + 1, "19003"); } else { strcat(meterpath, ":19003"); } p = meterpath; } else { p = strrchr(meterpath, '/'); if (p) { strcpy(p + 1, "SDRmeter"); } } } if (!p) { /* disabled */ priv->meter_port.fd = -1; } else { priv->meter_port.type.rig = rp->type.rig; ret = port_open(&priv->meter_port); if (ret < 0) { return ret; } } /* TODO: * copy priv->tuner->rx_range/tx_range to rig->state */ #if 1 rs->has_set_func |= STATE(priv->tuner)->has_set_func; rs->has_get_func |= STATE(priv->tuner)->has_get_func; rs->has_set_level |= STATE(priv->tuner)->has_set_level; rs->has_get_level |= STATE(priv->tuner)->has_get_level; rs->has_set_parm |= STATE(priv->tuner)->has_set_parm; rs->has_get_parm |= STATE(priv->tuner)->has_get_parm; #endif /* Because model dummy has funky init value */ if (priv->tuner_model == RIG_MODEL_DUMMY) { dttsp_set_freq(rig, RIG_VFO_CURR, priv->IF_center_freq); } dttsp_set_func(rig, RIG_VFO_CURR, RIG_FUNC_MUTE, 0); return RIG_OK; } int dttsp_close(RIG *rig) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); port_close(&priv->meter_port, priv->meter_port.type.rig); rig_close(priv->tuner); return RIG_OK; } int dttsp_cleanup(RIG *rig) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (priv && priv->tuner) { rig_cleanup(priv->tuner); priv->tuner = NULL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_set_freq is a good candidate for the GNUradio GUI setFrequency callback? */ int dttsp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; freq_t tuner_freq; int ret; char fstr[20]; char buf[32]; shortfreq_t max_delta; freq_t freq_offset; max_delta = priv->sample_rate / 2 - kHz(2); sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_TRACE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq); if (ret != RIG_OK) { return ret; } freq_offset = freq - tuner_freq; /* TODO: take into account the mode width and the IF dead zone */ if (fabs(freq_offset) > max_delta) { tuner_freq = priv->IF_center_freq + freq - kHz(6); ret = rig_set_freq(priv->tuner, RIG_VFO_CURR, tuner_freq); if (ret != RIG_OK) { return ret; } /* reread the tuner freq because some rigs can't tune to exact frequency. * The rx_delta_f will correct that */ ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq); if (ret != RIG_OK) { return ret; } } priv->rx_delta_f = freq - tuner_freq; sprintf_freq(fstr, sizeof(fstr), tuner_freq); rig_debug(RIG_DEBUG_TRACE, "%s: tuner=%s, rx_delta=%d Hz\n", __func__, fstr, priv->rx_delta_f); /* setRxFrequenc */ SNPRINTF(buf, sizeof(buf), "setOsc %d\n", priv->rx_delta_f); ret = send_command(rig, buf, strlen(buf)); return ret; } int dttsp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; freq_t tuner_freq; int ret; ret = rig_get_freq(priv->tuner, RIG_VFO_CURR, &tuner_freq); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *freq = tuner_freq - priv->rx_delta_f; return RIG_OK; } static enum dttsp_mode_e rmode2dttsp(rmode_t mode) { int i; for (i = 0; i < HAMLIB_VS_DTTSP_MODES_COUNT; i++) { if (hamlib_vs_dttsp_modes[i].hamlib_mode == mode) { return hamlib_vs_dttsp_modes[i].dttsp_mode; } } return 0; } /* * WIP */ int dttsp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32]; int ret = RIG_OK; int filter_l, filter_h; /* DttSP set mode */ SNPRINTF(buf, sizeof(buf), "setMode %d\n", rmode2dttsp(mode)); ret = send_command(rig, buf, strlen(buf)); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, buf); if (ret != RIG_OK || RIG_PASSBAND_NOCHANGE == width) { return ret; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } sprintf_freq(buf, sizeof(buf), width); rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s\n", __func__, rig_strrmode(mode), buf); switch (mode) { case RIG_MODE_USB: case RIG_MODE_CW: filter_l = 10; filter_h = width; break; case RIG_MODE_LSB: case RIG_MODE_CWR: filter_l = -width; filter_h = -10; break; case RIG_MODE_AM: case RIG_MODE_SAM: case RIG_MODE_FM: case RIG_MODE_DSB: filter_l = -width / 2; filter_h = width / 2; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "setFilter %d %d\n", filter_l, filter_h); ret = send_command(rig, buf, strlen(buf)); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, buf); return ret; } static int agc_level2dttsp(enum agc_level_e agc) { switch (agc) { case RIG_AGC_OFF: return 0; case RIG_AGC_SLOW: return 2; case RIG_AGC_MEDIUM: return 3; case RIG_AGC_FAST: return 4; default: return 0; } return 0; } /* */ int dttsp_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret = RIG_OK; char buf[32]; switch (level) { case RIG_LEVEL_AGC: SNPRINTF(buf, sizeof(buf), "setRXAGC %d\n", agc_level2dttsp(val.i)); ret = send_command(rig, buf, strlen(buf)); break; default: rig_debug(RIG_DEBUG_TRACE, "%s: level %s, try tuner\n", __func__, rig_strlevel(level)); return rig_set_level(priv->tuner, vfo, level, val); } return ret; } int dttsp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; int ret = RIG_OK; char buf[32]; float rxm[MAXRX][RXMETERPTS]; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strlevel(level)); switch (level) { case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: SNPRINTF(buf, sizeof(buf), "reqRXMeter %d\n", getpid()); ret = send_command(rig, buf, strlen(buf)); if (ret < 0) { return ret; } ret = fetch_meter(rig, (int *)buf, (float *)rxm, MAXRX * RXMETERPTS); if (ret < 0) { return ret; } val->i = (int)rxm[0][0]; if (level == RIG_LEVEL_STRENGTH) { val->i = (int)rig_raw2val(val->i, &STATE(rig)->str_cal); } ret = RIG_OK; break; default: rig_debug(RIG_DEBUG_TRACE, "%s: level %s, try tuner\n", __func__, rig_strlevel(level)); return rig_get_level(priv->tuner, vfo, level, val); } return ret; } int dttsp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; char buf[32]; const char *cmd; int ret; status = status ? 1 : 0; switch (func) { case RIG_FUNC_MUTE: cmd = "setRunState"; status = status ? 0 : 2; break; case RIG_FUNC_NB: cmd = "setNB"; break; case RIG_FUNC_ANF: cmd = "setANF"; break; case RIG_FUNC_NR: cmd = "setNR"; break; default: rig_debug(RIG_DEBUG_TRACE, "%s: func %s, try tuner\n", __func__, rig_strfunc(func)); return rig_set_func(priv->tuner, vfo, func, status); } SNPRINTF(buf, sizeof(buf), "%s %d\n", cmd, status); ret = send_command(rig, buf, strlen(buf)); return ret; } /* * TODO */ int dttsp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENIMPL; } int dttsp_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return -RIG_ENIMPL; } int dttsp_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct dttsp_priv_data *priv = (struct dttsp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: ant %u, try tuner\n", __func__, ant); return rig_set_ant(priv->tuner, vfo, ant, option); } hamlib-4.6.2/rigs/flexradio/flexradio.h0000644000175000017500000000271214752216205014755 00000000000000/* * Hamlib FLEXRADIO backend - main header * Copyright (c) 2004-2012 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FLEXRADIO_H #define _FLEXRADIO_H 1 #include "hamlib/rig.h" extern struct rig_caps sdr1k_rig_caps; extern struct rig_caps sdr1krfe_rig_caps; extern struct rig_caps dttsp_rig_caps; extern struct rig_caps dttsp_udp_rig_caps; extern struct rig_caps smartsdr_a_rig_caps; extern struct rig_caps smartsdr_b_rig_caps; extern struct rig_caps smartsdr_c_rig_caps; extern struct rig_caps smartsdr_d_rig_caps; extern struct rig_caps smartsdr_e_rig_caps; extern struct rig_caps smartsdr_f_rig_caps; extern struct rig_caps smartsdr_g_rig_caps; extern struct rig_caps smartsdr_h_rig_caps; #endif /* _FLEXRADIO_H */ hamlib-4.6.2/rigs/flexradio/Makefile.am0000644000175000017500000000025214752216205014660 00000000000000 noinst_LTLIBRARIES = libhamlib-flexradio.la libhamlib_flexradio_la_SOURCES = flexradio.c flexradio.h sdr1k.c dttsp.c smartsdr.c smartsdr_caps.h EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/flexradio/Makefile.in0000644000175000017500000005325314752216216014704 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/flexradio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_flexradio_la_LIBADD = am_libhamlib_flexradio_la_OBJECTS = flexradio.lo sdr1k.lo dttsp.lo \ smartsdr.lo libhamlib_flexradio_la_OBJECTS = $(am_libhamlib_flexradio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dttsp.Plo ./$(DEPDIR)/flexradio.Plo \ ./$(DEPDIR)/sdr1k.Plo ./$(DEPDIR)/smartsdr.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_flexradio_la_SOURCES) DIST_SOURCES = $(libhamlib_flexradio_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libhamlib-flexradio.la libhamlib_flexradio_la_SOURCES = flexradio.c flexradio.h sdr1k.c dttsp.c smartsdr.c smartsdr_caps.h EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/flexradio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/flexradio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-flexradio.la: $(libhamlib_flexradio_la_OBJECTS) $(libhamlib_flexradio_la_DEPENDENCIES) $(EXTRA_libhamlib_flexradio_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_flexradio_la_OBJECTS) $(libhamlib_flexradio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dttsp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flexradio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdr1k.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smartsdr.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dttsp.Plo -rm -f ./$(DEPDIR)/flexradio.Plo -rm -f ./$(DEPDIR)/sdr1k.Plo -rm -f ./$(DEPDIR)/smartsdr.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dttsp.Plo -rm -f ./$(DEPDIR)/flexradio.Plo -rm -f ./$(DEPDIR)/sdr1k.Plo -rm -f ./$(DEPDIR)/smartsdr.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/flexradio/flexradio.c0000644000175000017500000000340414752216205014747 00000000000000/* * Hamlib Flexradio backend * Copyright (c) 2003-2012 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "flexradio.h" #include "register.h" #ifdef HAVE_NETINET_IN_H # include #endif #if HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_SYS_IOCTL_H) # include # include #endif DECLARE_INITRIG_BACKEND(flexradio) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); rig_register(&sdr1k_rig_caps); //rig_register(&sdr1krfe_rig_caps); rig_register(&dttsp_rig_caps); rig_register(&dttsp_udp_rig_caps); rig_register(&smartsdr_a_rig_caps); rig_register(&smartsdr_b_rig_caps); rig_register(&smartsdr_c_rig_caps); rig_register(&smartsdr_d_rig_caps); rig_register(&smartsdr_e_rig_caps); rig_register(&smartsdr_f_rig_caps); rig_register(&smartsdr_g_rig_caps); rig_register(&smartsdr_h_rig_caps); return RIG_OK; } hamlib-4.6.2/rigs/flexradio/Android.mk0000644000175000017500000000045314752216205014540 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := flexradio.c sdr1k.c dttsp.c smartsdr.c smartsdr_caps.h LOCAL_MODULE := flexradio LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/flexradio/smartsdr.c0000644000175000017500000004332014752216205014632 00000000000000/* * Hamlib backend - SmartSDR TCP on port 4952 * See https://github.com/flexradio/smartsdr-api-docs/wiki/SmartSDR-TCPIP-API * Copyright (c) 2024 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "parallel.h" #include "misc.h" #include "bandplan.h" #include "cache.h" #include "network.h" static int smartsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int smartsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); //static int smartsdr_reset(RIG *rig, reset_t reset); static int smartsdr_init(RIG *rig); static int smartsdr_open(RIG *rig); static int smartsdr_close(RIG *rig); static int smartsdr_cleanup(RIG *rig); static int smartsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int smartsdr_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int smartsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int smartsdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); //static int smartsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); struct smartsdr_priv_data { int slicenum; // slice 0-7 maps to A-H int seqnum; int ptt; int tx; // when 1 this slice has PTT control double freqA; double freqB; rmode_t modeA; rmode_t modeB; int widthA; int widthB; }; #define DEFAULTPATH "127.0.0.1:4992" #define SMARTSDR_FUNC RIG_FUNC_MUTE #define SMARTSDR_LEVEL RIG_LEVEL_PREAMP #define SMARTSDR_PARM RIG_PARM_NONE #define SMARTSDR_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_SAM) #define SMARTSDR_VFO (RIG_VFO_A) #define SMARTSDR_ANTS 3 static int smartsdr_parse_S(RIG *rig, char *s); struct rig_caps smartsdr_a_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_A), .model_name = "SmartSDR Slice A", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_b_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_B), .model_name = "SmartSDR Slice B", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_c_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_C), .model_name = "SmartSDR Slice C", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_d_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_D), .model_name = "SmartSDR Slice D", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_e_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_E), .model_name = "SmartSDR Slice E", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_f_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_F), .model_name = "SmartSDR Slice F", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_g_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_G), .model_name = "SmartSDR Slice G", #include "smartsdr_caps.h" }; struct rig_caps smartsdr_h_rig_caps = { RIG_MODEL(RIG_MODEL_SMARTSDR_H), .model_name = "SmartSDR Slice H", #include "smartsdr_caps.h" }; /* ************************************************************************* */ int smartsdr_init(RIG *rig) { struct smartsdr_priv_data *priv; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rs->priv = (struct smartsdr_priv_data *)calloc(1, sizeof( struct smartsdr_priv_data)); if (!rs->priv) { /* whoops! memory shortage! */ RETURNFUNC(-RIG_ENOMEM); } priv = rs->priv; strncpy(rp->pathname, DEFAULTPATH, sizeof(rp->pathname)); switch (rs->rig_model) { case RIG_MODEL_SMARTSDR_A: priv->slicenum = 0; break; case RIG_MODEL_SMARTSDR_B: priv->slicenum = 1; break; case RIG_MODEL_SMARTSDR_C: priv->slicenum = 2; break; case RIG_MODEL_SMARTSDR_D: priv->slicenum = 3; break; case RIG_MODEL_SMARTSDR_E: priv->slicenum = 4; break; case RIG_MODEL_SMARTSDR_F: priv->slicenum = 5; break; case RIG_MODEL_SMARTSDR_G: priv->slicenum = 6; break; case RIG_MODEL_SMARTSDR_H: priv->slicenum = 7; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown rig model=%s\n", __func__, rs->model_name); RETURNFUNC(-RIG_ENIMPL); } priv->ptt = 0; RETURNFUNC(RIG_OK); } // flush any messages in the queue and process them too // return 0 if OK, otherwise SMARTSDR error code static int smartsdr_flush(RIG *rig) { char buf[8192]; int buf_len = 8192; char stopset[1] = { 0x0a }; int len = 0; int retval = RIG_OK; ENTERFUNC; #if 0 // for this flush routine we expect at least one message for sure -- might be more len = read_string(RIGPORT(rig), (unsigned char *)buf, buf_len, stopset, 1, 0, 1); if (buf[0] == 'S') { smartsdr_parse_S(rig, buf); } rig_debug(RIG_DEBUG_VERBOSE, "%s: read %d bytes\n", __func__, len); #endif do { buf[0] = 0; len = network_flush2(RIGPORT(rig), (unsigned char *)stopset, buf, buf_len); if (buf[0] == 'S') { smartsdr_parse_S(rig, buf); } else if (buf[0] == 'R') { sscanf(buf, "R%d", &retval); } else if (strlen(buf) > 0) { rig_debug(RIG_DEBUG_WARN, "%s: Unknown packet type=%s\n", __func__, buf); } } while (len > 0); RETURNFUNC(retval); } static int smartsdr_transaction(RIG *rig, char *buf) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[4096]; int retval; if (priv->seqnum > 999999) { priv->seqnum = 0; } if (buf) { sprintf(cmd, "C%d|%s%c", priv->seqnum++, buf, 0x0a); retval = write_block(RIGPORT(rig), (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SmartSDR write_block err=0x%x\n", __func__, retval); } } retval = smartsdr_flush(rig); if (retval != 0) { rig_debug(RIG_DEBUG_ERR, "%s: SmartSDR flush err=0x%x\n", __func__, retval); retval = -RIG_EPROTO; } return retval; } int smartsdr_open(RIG *rig) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[64]; int loops = 20; ENTERFUNC; // Once we've connected and hit here we should have two messages queued from the initial connect sprintf(cmd, "sub slice %d", priv->slicenum); //sprintf(cmd, "sub slice all"); smartsdr_transaction(rig, cmd); do { hl_usleep(100 * 1000); smartsdr_transaction(rig, NULL); } while (priv->freqA == 0 && --loops > 0); //smartsdr_transaction(rig, "info", buf, sizeof(buf)); //rig_debug(RIG_DEBUG_VERBOSE, "%s: info=%s", __func__, buf); RETURNFUNC(RIG_OK); } int smartsdr_close(RIG *rig) { ENTERFUNC; RETURNFUNC(RIG_OK); } int smartsdr_cleanup(RIG *rig) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; ENTERFUNC; if (priv) { free(priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } #if 0 #if defined(HAVE_PTHREAD) typedef struct smartsdr_data_handler_args_s { RIG *rig; } smartsdr_data_handler_args; typedef struct smartsdr_data_handler_priv_data_s { pthread_t thread_id; smartsdr_data_handler_args args; int smartsdr_data_handler_thread_run; } smartsdr_data_handler_priv_data; void *smartsdr_data_handler(void *arg) { struct smartsdr_priv_data *priv; struct smartsdr_data_handler_args_s *args = (struct smartsdr_data_handler_args_s *) arg; smartsdr_data_handler_priv_data *smartsdr_data_handler_priv; //RIG *rig = args->rig; //const struct rig_state *rs = STATE(rig); //int result; rig_debug(RIG_DEBUG_VERBOSE, "%s: Starting morse data handler thread\n", __func__); while (priv->smartsdr_data_handler_priv_data->smartsdr_data_handler_thread_run) { } pthread_exit(NULL); return NULL; } static int smartsdr_data_handler_start(RIG *rig) { struct smartsdr_priv_data *priv; smartsdr_data_handler_priv_data *smartsdr_data_handler_priv; ENTERFUNC; priv->smartsdr_data_handler_thread_run = 1; priv->smartsdr_data_handler_priv_data = calloc(1, sizeof(smartsdr_data_handler_priv_data)); if (priv->smartsdr_data_handler_priv_data == NULL) { RETURNFUNC(-RIG_ENOMEM); } smartsdr_data_handler_priv = (smartsdr_data_handler_priv_data *) priv->smartsdr_data_handler_priv_data; smartsdr_data_handler_priv->args.rig = rig; int err = pthread_create(&smartsdr_data_handler_priv->thread_id, NULL, smartsdr_data_handler, &smartsdr_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); fset = 1500 post_demod_bypass = 0 rfgain = 24 tx_ant_list = ANT1, ANT2, XVTA, XVTB } #endif #endif /* Example response to "sub slice 0" 511+511+35 S67319A86|slice 0 in_use=1 sample_rate=24000 RF_frequency=10.137000 client_handle=0x76AF7C73 index_letter=A rit_on=0 rit_freq=0 xit_on=0 xit_freq=0 rxant=ANT2 mode=DIGU wide=0 filter_lo=0 filter_hi=3510 step=10 step_list=1,5,10,20,100,250,500,1000 agc_mode=fast agc_threshold=65 agc_off_level=10 pan=0x40000000 txant=ANT2 loopa=0 loopb=0 qsk=0 dax=1 dax_clients=1 lock=0 tx=1 active=1 audio_level=100 audio_pan=51 audio_mute=1 record=0 play=disabled record_time=0.0 anf=0 anf_level=0 nr=0 nr_level=0 nb=0 nb_lev direct=1 el=50 wnb=0 wnb_level=100 apf=0 apf_level=0 squelch=1 squelch_level=20 diversity=0 diversity_parent=0 diversity_child=0 diversity_index=1342177293 ant_list=ANT1,ANT2,RX_A,RX_B,XVTA,XVTB mode_list=LSB,USB,AM,CW,DIGL,DIGU,SAM,FM,NFM,DFM,RTTY fm_tone_mode=OFF fm_tone_value=67.0 fm_repeater_offset_freq=0.000000 tx_offset_freq=0.000000 repeater_offset_dir=SIMPLEX fm_tone_burst=0 fm_deviation=5000 dfm_pre_de_emphasis=0 post_demod_low=300 post_demod_high=3300 rtty_mark=2125 rtty_shift=170 digl_offset=2210 digu_offset=1500 post_demod_bypass=0 rfgain=24 tx_ant_list=ANT1,ANT2,XVTA,XVTB S67319A86|waveform installed_list= R0|0| */ int smartsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char buf[4096]; char cmd[64]; ENTERFUNC; sprintf(cmd, "slice tune %d %.6f autopan=1", priv->slicenum, freq / 1e6); smartsdr_transaction(rig, cmd); rig_debug(RIG_DEBUG_VERBOSE, "%s: set_freq answer: %s", __func__, buf); rig_set_cache_freq(rig, vfo, freq); if (vfo == RIG_VFO_A) { priv->freqA = freq; } else { priv->freqB = freq; } RETURNFUNC(RIG_OK); } static int smartsdr_parse_S(RIG *rig, char *s) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; freq_t freq; char mode[16]; char state[16]; char *s2 = strdup(s); char *sep = "| \n"; char *p = strtok(s2, sep); int gotFreq = 0, gotMode = 0; do { rig_debug(RIG_DEBUG_VERBOSE, "%s: parsing '%s'\n", __func__, p); if (sscanf(p, "RF_frequency=%lf", &freq) == 1) { priv->freqA = freq * 1e6; rig_debug(RIG_DEBUG_VERBOSE, "%s: got freq=%.0f\n", __func__, priv->freqA); gotFreq = 1; rig_set_cache_freq(rig, RIG_VFO_A, priv->freqA); } else if (sscanf(p, "filter_hi=%d\n", &priv->widthA) == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: got width=%d\n", __func__, priv->widthA); rig_set_cache_mode(rig, RIG_VFO_A, priv->modeA, priv->widthA); } else if (sscanf(p, "mode=%s\n", mode) == 1) { if (strcmp(mode, "USB") == 0) { priv->modeA = RIG_MODE_USB; } else if (strcmp(mode, "LSB") == 0) { priv->modeA = RIG_MODE_LSB; } else if (strcmp(mode, "DIGU") == 0) { priv->modeA = RIG_MODE_PKTUSB; } else if (strcmp(mode, "DIGL") == 0) { priv->modeA = RIG_MODE_PKTLSB; } else if (strcmp(mode, "AM") == 0) { priv->modeA = RIG_MODE_AM; } else if (strcmp(mode, "CW") == 0) { priv->modeA = RIG_MODE_CW; } else if (strcmp(mode, "SAM") == 0) { priv->modeA = RIG_MODE_SAM; } else if (strcmp(mode, "FM") == 0) { priv->modeA = RIG_MODE_FM; } else if (strcmp(mode, "FMN") == 0) { priv->modeA = RIG_MODE_FMN; } else if (strcmp(mode, "RTTY") == 0) { priv->modeA = RIG_MODE_RTTY; } else { priv->modeA = RIG_MODE_NONE; rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, mode); return -RIG_EPROTO; } rig_set_cache_mode(rig, RIG_VFO_A, priv->modeA, priv->widthA); gotMode = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: got mode=%s\n", __func__, rig_strrmode(priv->modeA)); } else if (sscanf(p, "state=%s\n", state) == 1) { if (strcmp(state, "TRANSMITTING") == 0) { priv->ptt = 1; } else { priv->ptt = 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: PTT state=%s, ptt=%d\n", __func__, state, priv->ptt); } else if (sscanf(p, "tx=%d\n", &priv->tx) == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tx=%d\n", __func__, priv->tx); } } while ((p = strtok(NULL, sep))); free(s2); rig_debug(RIG_DEBUG_VERBOSE, "%s gotFreq=%d, gotMode=%d\n", __func__, gotFreq, gotMode); return RIG_OK; } int smartsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; //char cmd[64]; ENTERFUNC; //int retval = -RIG_EINTERNAL; // doing the sub slice causes audio problems //sprintf(cmd, "sub slice %d", priv->slicenum); //sprintf(cmd, "info"); smartsdr_transaction(rig, NULL); if (vfo == RIG_VFO_A || vfo == RIG_VFO_CURR) { *freq = priv->freqA; } else { *freq = priv->freqB; } RETURNFUNC(RIG_OK); } int smartsdr_reset(RIG *rig, reset_t reset) { return -RIG_ENIMPL; } int smartsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[64]; char slicechar[] = { '?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' }; ENTERFUNC; if (priv->ptt && ptt) // abort ptt if we're already transmitting { rig_debug(RIG_DEBUG_ERR, "%s: abort PTT on slice %c, another slice has PTT control\n", __func__, slicechar[priv->slicenum]); RETURNFUNC(-RIG_ENTARGET); } priv->ptt = ptt; if (ptt) { sprintf(cmd, "dax audio set %d tx=1", priv->slicenum + 1); smartsdr_transaction(rig, cmd); rig_debug(RIG_DEBUG_VERBOSE, "%s: slice set answer: %s", __func__, cmd); } sprintf(cmd, "slice set %d tx=1", priv->slicenum); smartsdr_transaction(rig, cmd); sprintf(cmd, "xmit %d", ptt); smartsdr_transaction(rig, cmd); RETURNFUNC(RIG_OK); } int smartsdr_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; ENTERFUNC; smartsdr_transaction(rig, NULL); *ptt = 0; if (priv->tx) { *ptt = priv->ptt; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, *ptt); RETURNFUNC(RIG_OK); } int smartsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; char cmd[64]; char *rmode = RIG_MODE_NONE; ENTERFUNC; switch (mode) { case RIG_MODE_CW: rmode = "CW"; break; case RIG_MODE_USB: rmode = "USB"; break; case RIG_MODE_LSB: rmode = "LSB"; break; case RIG_MODE_PKTUSB: rmode = "DIGU"; break; case RIG_MODE_PKTLSB: rmode = "DIGL"; break; case RIG_MODE_AM: rmode = "AM"; break; case RIG_MODE_FM: rmode = "FM"; break; case RIG_MODE_FMN: rmode = "FMN"; break; case RIG_MODE_SAM: rmode = "SAM"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); } sprintf(cmd, "slice set %d mode=%s", priv->slicenum, rmode); smartsdr_transaction(rig, cmd); if (width != RIG_PASSBAND_NOCHANGE) { sprintf(cmd, "filt %d 0 %ld", priv->slicenum, width); } RETURNFUNC(RIG_OK); } int smartsdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct smartsdr_priv_data *priv = (struct smartsdr_priv_data *)STATE(rig)->priv; ENTERFUNC; *mode = priv->modeA; *width = priv->widthA; RETURNFUNC(RIG_OK); } #if 0 int sdr1k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: %s %d\n", __func__, rig_strlevel(level), val.i); switch (level) { case RIG_LEVEL_PREAMP: return set_bit(rig, L_EXT, 7, !(val.i == rig->caps->preamp[0])); int smartsdr_set_ptt(RIG * rig, vfo_t vfo, ptt_t ptt) break; default: return -RIG_EINVAL; } } #endif hamlib-4.6.2/rigs/flexradio/README0000644000175000017500000000011314752216205013500 00000000000000See https://github.com/flexradio/smartsdr-api-docs/wiki/SmartSDR-TCPIP-API hamlib-4.6.2/rigs/flexradio/smartsdr_caps.h0000644000175000017500000000472714752216205015655 00000000000000 .mfg_name = "FlexRadio", .version = "20240814.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_NONE, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_NETWORK, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 2, .has_get_func = SMARTSDR_FUNC, .has_set_func = SMARTSDR_FUNC, .has_get_level = SMARTSDR_LEVEL, .has_set_level = RIG_LEVEL_SET(SMARTSDR_LEVEL), .has_get_parm = SMARTSDR_PARM, .has_set_parm = RIG_PARM_SET(SMARTSDR_PARM), .chan_list = { RIG_CHAN_END, }, .scan_ops = RIG_SCAN_NONE, .vfo_ops = RIG_OP_NONE, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { 14, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(30), .endf = MHz(54), .modes = SMARTSDR_MODES, .low_power = -1, .high_power = -1, SMARTSDR_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { /* restricted to ham band */ FRQ_RNG_HF(1, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), FRQ_RNG_6m(1, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(30), .endf = MHz(100), .modes = SMARTSDR_MODES, .low_power = -1, .high_power = -1, SMARTSDR_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { /* restricted to ham band */ FRQ_RNG_HF(2, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), FRQ_RNG_6m(2, SMARTSDR_MODES, W(1), W(100), SMARTSDR_VFO, SMARTSDR_ANTS), RIG_FRNG_END, }, .tuning_steps = { {SMARTSDR_MODES, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* priv */ .rig_init = smartsdr_init, .rig_open = smartsdr_open, .rig_close = smartsdr_close, .rig_cleanup = smartsdr_cleanup, .set_freq = smartsdr_set_freq, .get_freq = smartsdr_get_freq, .get_mode= smartsdr_get_mode, .set_mode= smartsdr_set_mode, .set_ptt = smartsdr_set_ptt, .get_ptt = smartsdr_get_ptt, // .reset = smartsdr_reset, // .set_level = smartsdr_set_level, // .set_func = _set_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS hamlib-4.6.2/rigs/flexradio/sdr1k.c0000644000175000017500000003105414752216205014020 00000000000000/* * Hamlib backend - SDR-1000 * Copyright (c) 2003-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "parallel.h" #include "misc.h" #include "bandplan.h" static int sdr1k_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int sdr1k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int sdr1k_reset(RIG *rig, reset_t reset); static int sdr1k_init(RIG *rig); static int sdr1k_open(RIG *rig); static int sdr1k_close(RIG *rig); static int sdr1k_cleanup(RIG *rig); static int sdr1k_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int sdr1k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); typedef enum { L_EXT = 0, L_BAND = 1, L_DDS0 = 2, L_DDS1 = 3 } latch_t; #define TR 0x40 #define MUTE 0x80 #define GAIN 0x80 #define WRB 0x40 #define RESET 0x80 /* DDS Control Constants */ #define COMP_PD 0x10 /* DDS Comparator power down */ #define DIG_PD 0x01 /* DDS Digital Power down */ #define BYPASS_PLL 0x20 /* Bypass DDS PLL */ #define INT_IOUD 0x01 /* Internal IO Update */ #define OSK_EN 0x20 /* Offset Shift Keying enable */ #define OSK_INT 0x10 /* Offset Shift Keying */ #define BYPASS_SINC 0x40 /* Bypass Inverse Sinc Filter */ #define PLL_RANGE 0x40 /* Set PLL Range */ static int write_latch(RIG *rig, latch_t which, unsigned value, unsigned mask); static int dds_write_reg(RIG *rig, unsigned addr, unsigned data); static int set_bit(RIG *rig, latch_t reg, unsigned bit, unsigned state); #define DEFAULT_XTAL MHz(200) #define DEFAULT_PLL_MULT 1 #define DEFAULT_DAC_MULT 4095 struct sdr1k_priv_data { unsigned shadow[4]; /* shadow latches */ freq_t dds_freq; /* current freq */ freq_t xtal; /* base XTAL */ int pll_mult; /* PLL mult */ }; #define SDR1K_FUNC RIG_FUNC_MUTE #define SDR1K_LEVEL RIG_LEVEL_PREAMP #define SDR1K_PARM RIG_PARM_NONE #define SDR1K_MODES (RIG_MODE_USB|RIG_MODE_CW) #define SDR1K_VFO RIG_VFO_A #define SDR1K_ANTS 0 /* ************************************************************************* */ /* * http://www.flex-radio.com * SDR-1000 rig capabilities. * * * TODO: RIG_FUNC_MUTE, set_external_pin? * * def set_mute (self, mute = 1): * self.set_bit(1, 7, mute) * * def set_unmute (self): * self.set_bit(1, 7, 0) * * def set_external_pin (self, pin, on = 1): * assert (pin < 8 and pin > 0), "Out of range 1..7" * self.set_bit(0, pin-1, on) * * def read_input_pin * * set_conf(XTAL,PLL_mult,spur_red) * * What about IOUD_Clock? */ struct rig_caps sdr1k_rig_caps = { RIG_MODEL(RIG_MODEL_SDR1000), .model_name = "SDR-1000", .mfg_name = "FlexRadio", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, .targetable_vfo = 0, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_PARALLEL, .has_get_func = SDR1K_FUNC, .has_set_func = SDR1K_FUNC, .has_get_level = SDR1K_LEVEL, .has_set_level = RIG_LEVEL_SET(SDR1K_LEVEL), .has_get_parm = SDR1K_PARM, .has_set_parm = RIG_PARM_SET(SDR1K_PARM), .chan_list = { RIG_CHAN_END, }, .scan_ops = RIG_SCAN_NONE, .vfo_ops = RIG_OP_NONE, .transceive = RIG_TRN_OFF, .attenuator = { RIG_DBLST_END, }, .preamp = { 14, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = Hz(1), .endf = MHz(65), .modes = SDR1K_MODES, .low_power = -1, .high_power = -1, SDR1K_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { /* restricted to ham band */ FRQ_RNG_HF(1, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), FRQ_RNG_6m(1, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { { .startf = Hz(1), .endf = MHz(65), .modes = SDR1K_MODES, .low_power = -1, .high_power = -1, SDR1K_VFO }, RIG_FRNG_END, }, .tx_range_list2 = { /* restricted to ham band */ FRQ_RNG_HF(2, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), FRQ_RNG_6m(2, SDR1K_MODES, W(1), W(1), SDR1K_VFO, SDR1K_ANTS), RIG_FRNG_END, }, .tuning_steps = { {SDR1K_MODES, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* priv */ .rig_init = sdr1k_init, .rig_open = sdr1k_open, .rig_close = sdr1k_close, .rig_cleanup = sdr1k_cleanup, .set_freq = sdr1k_set_freq, .get_freq = sdr1k_get_freq, .set_ptt = sdr1k_set_ptt, .reset = sdr1k_reset, .set_level = sdr1k_set_level, // .set_func = sdr1k_set_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ************************************************************************* */ int sdr1k_init(RIG *rig) { struct sdr1k_priv_data *priv; struct rig_state *rs = STATE(rig); rs->priv = (struct sdr1k_priv_data *)calloc(1, sizeof( struct sdr1k_priv_data)); if (!rs->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = rs->priv; priv->dds_freq = RIG_FREQ_NONE; priv->xtal = DEFAULT_XTAL; priv->pll_mult = DEFAULT_PLL_MULT; return RIG_OK; } static void pdelay(RIG *rig) { unsigned char r; par_read_data(RIGPORT(rig), &r); /* ~1us */ } int sdr1k_open(RIG *rig) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; priv->shadow[0] = 0; priv->shadow[1] = 0; priv->shadow[2] = 0; priv->shadow[3] = 0; sdr1k_reset(rig, 1); return RIG_OK; } int sdr1k_close(RIG *rig) { /* TODO: release relays? */ return RIG_OK; } int sdr1k_cleanup(RIG *rig) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; if (priv) { free(priv); } STATE(rig)->priv = NULL; return RIG_OK; } static int set_band(RIG *rig, freq_t freq) { int band, ret; /* set_band */ if (freq <= MHz(2.25)) { band = 0; } else if (freq <= MHz(5.5)) { band = 1; } else if (freq <= MHz(11)) { band = 3; /* due to wiring mistake on board */ } else if (freq <= MHz(22)) { band = 2; /* due to wiring mistake on board */ } else if (freq <= MHz(37.5)) { band = 4; } else { band = 5; } ret = write_latch(rig, L_BAND, 1 << band, 0x3f); // cppcheck-suppress * rig_debug(RIG_DEBUG_VERBOSE, "%s %"PRIll" band %d\n", __func__, (int64_t)freq, band); return ret; } /* * set DDS frequency. * NB: due to spur reduction, effective frequency might not be the expected one */ int sdr1k_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; int i; double ftw; double DDS_step_size; freq_t frqval; // why is spur_red always true? // int spur_red = 1; #define spur_red 1 int ret; ret = set_band(rig, freq); if (ret != RIG_OK) { return ret; } /* Calculate DDS step for spu reduction * DDS steps = 3051.7578125Hz */ DDS_step_size = ((double)priv->xtal * priv->pll_mult) / 65536; rig_debug(RIG_DEBUG_VERBOSE, "%s DDS step size %g %g %g\n", __func__, DDS_step_size, (double)freq / DDS_step_size, rint((double)freq / DDS_step_size)); // why is spur_red always true? if (spur_red) { frqval = (freq_t)(DDS_step_size * rint((double)freq / DDS_step_size)); } else { frqval = freq; } rig_debug(RIG_DEBUG_VERBOSE, "%s curr %"PRIll" frqval %"PRIll"\n", __func__, (int64_t)freq, (int64_t)frqval); if (priv->dds_freq == frqval) { return RIG_OK; } /*** */ ftw = (double)frqval / priv->xtal ; for (i = 0; i < 6; i++) { unsigned word; if (spur_red && i == 2) { word = 128; } else if (spur_red && i > 2) { word = 0; } else { word = (unsigned)(ftw * 256); ftw = ftw * 256 - word; } rig_debug(RIG_DEBUG_TRACE, "DDS %d [%02x]\n", i, word); ret = dds_write_reg(rig, 4 + i, word); if (ret != RIG_OK) { return ret; } } priv->dds_freq = frqval; return ret; } int sdr1k_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; *freq = priv->dds_freq; rig_debug(RIG_DEBUG_TRACE, "%s: %"PRIll"\n", __func__, (int64_t)priv->dds_freq); return RIG_OK; } /* Set DAC multiplier value */ static int DAC_mult(RIG *rig, unsigned mult) { rig_debug(RIG_DEBUG_TRACE, "DAC [%02x,%02x]\n", mult >> 8, mult & 0xff); /* Output Shape Key I Mult */ dds_write_reg(rig, 0x21, mult >> 8); dds_write_reg(rig, 0x22, mult & 0xff); /* Output Shape Key Q Mult */ dds_write_reg(rig, 0x23, mult >> 8); dds_write_reg(rig, 0x24, mult & 0xff); return RIG_OK; } int sdr1k_reset(RIG *rig, reset_t reset) { /* Reset all Latches (relays off) */ write_latch(rig, L_BAND, 0x00, 0xff); write_latch(rig, L_DDS1, 0x00, 0xff); write_latch(rig, L_DDS0, 0x00, 0xff); write_latch(rig, L_EXT, 0x00, 0xff); /* Reset DDS */ write_latch(rig, L_DDS1, RESET | WRB, 0xff); /* reset the DDS chip */ write_latch(rig, L_DDS1, WRB, 0xff); /* leave WRB high */ dds_write_reg(rig, 0x1d, COMP_PD); /* Power down comparator */ /* TODO: add PLL multiplier property and logic */ dds_write_reg(rig, 0x1e, BYPASS_PLL); /* Bypass PLL */ dds_write_reg(rig, 0x20, BYPASS_SINC | OSK_EN); /* Bypass Inverse Sinc and enable DAC */ DAC_mult(rig, DEFAULT_DAC_MULT); /* Set DAC multiplier value */ return RIG_OK; } int sdr1k_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { return set_bit(rig, L_BAND, 6, ptt == RIG_PTT_ON); } int sdr1k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: %s %d\n", __func__, rig_strlevel(level), val.i); switch (level) { case RIG_LEVEL_PREAMP: return set_bit(rig, L_EXT, 7, !(val.i == rig->caps->preamp[0])); break; default: return -RIG_EINVAL; } } int write_latch(RIG *rig, latch_t which, unsigned value, unsigned mask) { struct sdr1k_priv_data *priv = (struct sdr1k_priv_data *)STATE(rig)->priv; hamlib_port_t *pport = RIGPORT(rig); if (!(L_EXT <= which && which <= L_DDS1)) { return -RIG_EINVAL; } par_lock(pport); priv->shadow[which] = (priv->shadow[which] & ~mask) | (value & mask); par_write_data(pport, priv->shadow[which]); pdelay(rig); par_write_control(pport, 0x0F ^ (1 << which)); pdelay(rig); par_write_control(pport, 0x0F); pdelay(rig); par_unlock(pport); return RIG_OK; } int dds_write_reg(RIG *rig, unsigned addr, unsigned data) { #if 0 write_latch(rig, L_DDS1, addr & 0x3f, 0x3f); write_latch(rig, L_DDS0, data, 0xff); write_latch(rig, L_DDS1, 0x40, 0x40); write_latch(rig, L_DDS1, 0x00, 0x40); #else /* set up data bits */ write_latch(rig, L_DDS0, data, 0xff); /* set up address bits with WRB high */ //write_latch (rig, L_DDS1, addr & 0x3f, 0x3f); write_latch(rig, L_DDS1, WRB | addr, 0xff); /* send write command with WRB low */ write_latch(rig, L_DDS1, addr, 0xff); /* return WRB high */ write_latch(rig, L_DDS1, WRB, 0xff); #endif return RIG_OK; } int set_bit(RIG *rig, latch_t reg, unsigned bit, unsigned state) { unsigned val; val = state ? 1 << bit : 0; return write_latch(rig, reg, val, 1 << bit); } hamlib-4.6.2/rigs/tuner/0000755000175000017500000000000014752216244012070 500000000000000hamlib-4.6.2/rigs/tuner/Makefile.am0000644000175000017500000000025214752216205014040 00000000000000TUNERSRC = v4l.c v4l2.c tuner.c tuner.h videodev.h videodev2.h noinst_LTLIBRARIES = libhamlib-tuner.la libhamlib_tuner_la_SOURCES = $(TUNERSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/tuner/Makefile.in0000644000175000017500000005263614752216216014070 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/tuner ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_tuner_la_LIBADD = am__objects_1 = v4l.lo v4l2.lo tuner.lo am_libhamlib_tuner_la_OBJECTS = $(am__objects_1) libhamlib_tuner_la_OBJECTS = $(am_libhamlib_tuner_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/tuner.Plo ./$(DEPDIR)/v4l.Plo \ ./$(DEPDIR)/v4l2.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_tuner_la_SOURCES) DIST_SOURCES = $(libhamlib_tuner_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TUNERSRC = v4l.c v4l2.c tuner.c tuner.h videodev.h videodev2.h noinst_LTLIBRARIES = libhamlib-tuner.la libhamlib_tuner_la_SOURCES = $(TUNERSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/tuner/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/tuner/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-tuner.la: $(libhamlib_tuner_la_OBJECTS) $(libhamlib_tuner_la_DEPENDENCIES) $(EXTRA_libhamlib_tuner_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_tuner_la_OBJECTS) $(libhamlib_tuner_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tuner.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v4l2.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/tuner.Plo -rm -f ./$(DEPDIR)/v4l.Plo -rm -f ./$(DEPDIR)/v4l2.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/tuner.Plo -rm -f ./$(DEPDIR)/v4l.Plo -rm -f ./$(DEPDIR)/v4l2.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/tuner/tuner.h0000644000175000017500000000227514752216205013321 00000000000000/* * Hamlib Tuners backend - main header * Copyright (c) 2004-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TUNER_H #define _TUNER_H 1 #include "hamlib/config.h" /* * So far, only Linux has Video4Linux support through ioctl :) * until someone port it to some other OS... */ #ifdef HAVE_LINUX_IOCTL_H #define V4L_IOCTL #endif #include "hamlib/rig.h" extern struct rig_caps v4l_caps; extern struct rig_caps v4l2_caps; #endif /* _TUNER_H */ hamlib-4.6.2/rigs/tuner/videodev.h0000644000175000017500000002746314752216205013777 00000000000000/* This header is extracted from linux/videodev.h, approximately version 2.6.0. We can't use linux/videodev.h directly because it indirectly defines struct timespec, which is also defined by the standard C library headers. Argh. -blp */ #ifndef FM_VIDEODEV_H #define FM_VIDEODEV_H 1 #include #include #define VID_TYPE_CAPTURE 1 /* Can capture */ #define VID_TYPE_TUNER 2 /* Can tune */ #define VID_TYPE_TELETEXT 4 /* Does teletext */ #define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ #define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ #define VID_TYPE_CLIPPING 32 /* Can clip */ #define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ #define VID_TYPE_SCALES 128 /* Scalable */ #define VID_TYPE_MONOCHROME 256 /* Monochrome only */ #define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ #define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ #define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ #define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ #define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ struct video_capability { char name[32]; int type; int channels; /* Num channels */ int audios; /* Num audio devices */ int maxwidth; /* Supported width */ int maxheight; /* And height */ int minwidth; /* Supported width */ int minheight; /* And height */ }; struct video_channel { int channel; char name[32]; int tuners; uint32_t flags; #define VIDEO_VC_TUNER 1 /* Channel has a tuner */ #define VIDEO_VC_AUDIO 2 /* Channel has audio */ uint16_t type; #define VIDEO_TYPE_TV 1 #define VIDEO_TYPE_CAMERA 2 uint16_t norm; /* Norm set by channel */ }; struct video_tuner { int tuner; char name[32]; unsigned long rangelow, rangehigh; /* Tuner range */ uint32_t flags; #define VIDEO_TUNER_PAL 1 #define VIDEO_TUNER_NTSC 2 #define VIDEO_TUNER_SECAM 4 #define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ #define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ #define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ #define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ #define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ uint16_t mode; /* PAL/NTSC/SECAM/OTHER */ #define VIDEO_MODE_PAL 0 #define VIDEO_MODE_NTSC 1 #define VIDEO_MODE_SECAM 2 #define VIDEO_MODE_AUTO 3 uint16_t signal; /* Signal strength 16bit scale */ }; struct video_picture { uint16_t brightness; uint16_t hue; uint16_t colour; uint16_t contrast; uint16_t whiteness; /* Black and white only */ uint16_t depth; /* Capture depth */ uint16_t palette; /* Palette in use */ #define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ #define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ #define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ #define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ #define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ #define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ #define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ #define VIDEO_PALETTE_YUYV 8 #define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ #define VIDEO_PALETTE_YUV420 10 #define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ #define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ #define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ #define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ #define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ #define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ #define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ #define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ }; struct video_audio { int audio; /* Audio channel */ uint16_t volume; /* If settable */ uint16_t bass, treble; uint32_t flags; #define VIDEO_AUDIO_MUTE 1 #define VIDEO_AUDIO_MUTABLE 2 #define VIDEO_AUDIO_VOLUME 4 #define VIDEO_AUDIO_BASS 8 #define VIDEO_AUDIO_TREBLE 16 #define VIDEO_AUDIO_BALANCE 32 char name[16]; #define VIDEO_SOUND_MONO 1 #define VIDEO_SOUND_STEREO 2 #define VIDEO_SOUND_LANG1 4 #define VIDEO_SOUND_LANG2 8 uint16_t mode; uint16_t balance; /* Stereo balance */ uint16_t step; /* Step actual volume uses */ }; struct video_clip { int32_t x,y; int32_t width, height; struct video_clip *next; /* For user use/driver use only */ }; struct video_window { uint32_t x,y; /* Position of window */ uint32_t width,height; /* Its size */ uint32_t chromakey; uint32_t flags; struct video_clip *clips; /* Set only */ int clipcount; #define VIDEO_WINDOW_INTERLACE 1 #define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */ #define VIDEO_CLIP_BITMAP -1 /* bitmap is 1024x625, a '1' bit represents a clipped pixel */ #define VIDEO_CLIPMAP_SIZE (128 * 625) }; struct video_capture { uint32_t x,y; /* Offsets into image */ uint32_t width, height; /* Area to capture */ uint16_t decimation; /* Decimation divider */ uint16_t flags; /* Flags for capture */ #define VIDEO_CAPTURE_ODD 0 /* Temporal */ #define VIDEO_CAPTURE_EVEN 1 }; struct video_buffer { void *base; int height,width; int depth; int bytesperline; }; struct video_mmap { unsigned int frame; /* Frame (0 - n) for double buffer */ int height,width; unsigned int format; /* should be VIDEO_PALETTE_* */ }; struct video_key { uint8_t key[8]; uint32_t flags; }; #define VIDEO_MAX_FRAME 32 struct video_mbuf { int size; /* Total memory to map */ int frames; /* Frames */ int offsets[VIDEO_MAX_FRAME]; }; #define VIDEO_NO_UNIT (-1) struct video_unit { int video; /* Video minor */ int vbi; /* VBI minor */ int radio; /* Radio minor */ int audio; /* Audio minor */ int teletext; /* Teletext minor */ }; struct vbi_format { uint32_t sampling_rate; /* in Hz */ uint32_t samples_per_line; uint32_t sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */ int32_t start[2]; /* starting line for each frame */ uint32_t count[2]; /* count of lines for each frame */ uint32_t flags; #define VBI_UNSYNC 1 /* can distingues between top/bottom field */ #define VBI_INTERLACED 2 /* lines are interlaced */ }; /* video_info is biased towards hardware mpeg encode/decode */ /* but it could apply generically to any hardware compressor/decompressor */ struct video_info { uint32_t frame_count; /* frames output since decode/encode began */ uint32_t h_size; /* current unscaled horizontal size */ uint32_t v_size; /* current unscaled vertical size */ uint32_t smpte_timecode; /* current SMPTE timecode (for current GOP) */ uint32_t picture_type; /* current picture type */ uint32_t temporal_reference; /* current temporal reference */ uint8_t user_data[256]; /* user data last found in compressed stream */ /* user_data[0] contains user data flags, user_data[1] has count */ }; /* generic structure for setting playback modes */ struct video_play_mode { int mode; int p1; int p2; }; /* for loading microcode / fpga programming */ struct video_code { char loadwhat[16]; /* name or tag of file being passed */ int datasize; uint8_t *data; }; #define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ #define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ #define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ #define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ #define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ #define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ #define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ #define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ #define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */ #define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ #define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ #define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ #define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ #define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ #define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ #define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ #define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ #define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ #define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ #define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */ #define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */ #define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */ #define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */ #define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ #define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ #define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ #define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ #define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */ #define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */ #define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ /* VIDIOCSWRITEMODE */ #define VID_WRITE_MPEG_AUD 0 #define VID_WRITE_MPEG_VID 1 #define VID_WRITE_OSD 2 #define VID_WRITE_TTX 3 #define VID_WRITE_CC 4 #define VID_WRITE_MJPEG 5 /* VIDIOCSPLAYMODE */ #define VID_PLAY_VID_OUT_MODE 0 /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ #define VID_PLAY_GENLOCK 1 /* p1: 0 = OFF, 1 = ON */ /* p2: GENLOCK FINE DELAY value */ #define VID_PLAY_NORMAL 2 #define VID_PLAY_PAUSE 3 #define VID_PLAY_SINGLE_FRAME 4 #define VID_PLAY_FAST_FORWARD 5 #define VID_PLAY_SLOW_MOTION 6 #define VID_PLAY_IMMEDIATE_NORMAL 7 #define VID_PLAY_SWITCH_CHANNELS 8 #define VID_PLAY_FREEZE_FRAME 9 #define VID_PLAY_STILL_MODE 10 #define VID_PLAY_MASTER_MODE 11 /* p1: see below */ #define VID_PLAY_MASTER_NONE 1 #define VID_PLAY_MASTER_VIDEO 2 #define VID_PLAY_MASTER_AUDIO 3 #define VID_PLAY_ACTIVE_SCANLINES 12 /* p1 = first active; p2 = last active */ #define VID_PLAY_RESET 13 #define VID_PLAY_END_MARK 14 #define VID_HARDWARE_BT848 1 #define VID_HARDWARE_QCAM_BW 2 #define VID_HARDWARE_PMS 3 #define VID_HARDWARE_QCAM_C 4 #define VID_HARDWARE_PSEUDO 5 #define VID_HARDWARE_SAA5249 6 #define VID_HARDWARE_AZTECH 7 #define VID_HARDWARE_SF16MI 8 #define VID_HARDWARE_RTRACK 9 #define VID_HARDWARE_ZOLTRIX 10 #define VID_HARDWARE_SAA7146 11 #define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */ #define VID_HARDWARE_RTRACK2 13 #define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ #define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ #define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ #define VID_HARDWARE_BROADWAY 17 /* Broadway project */ #define VID_HARDWARE_GEMTEK 18 #define VID_HARDWARE_TYPHOON 19 #define VID_HARDWARE_VINO 20 /* SGI Indy Vino */ #define VID_HARDWARE_CADET 21 /* Cadet radio */ #define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ #define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ #define VID_HARDWARE_CPIA 24 #define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */ #define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */ #define VID_HARDWARE_OV511 27 #define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */ #define VID_HARDWARE_W9966 29 #define VID_HARDWARE_SE401 30 /* SE401 USB webcams */ #define VID_HARDWARE_PWC 31 /* Philips webcams */ #define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */ #define VID_HARDWARE_CPIA2 33 #define VID_HARDWARE_VICAM 34 #define VID_HARDWARE_SF16FMR2 35 #endif /* videodev.h */ hamlib-4.6.2/rigs/tuner/Android.mk0000644000175000017500000000040514752216205013715 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := tuner.c v4l.c v4l2.c LOCAL_MODULE := tuner LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/tuner/v4l.c0000644000175000017500000002375614752216205012673 00000000000000/* * Hamlib Tuner backend - Video4Linux (v1) description * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include #include "hamlib/rig.h" #include "tuner.h" /* include config.h */ #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef V4L_IOCTL #include "idx_builtin.h" #define V4L_FUNC (RIG_FUNC_MUTE) #define V4L_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RAWSTR) #define V4L_PARM_ALL (RIG_PARM_NONE) #define V4L_VFO (RIG_VFO_A) /* FIXME: per card measures? */ #define V4L_STR_CAL { 2, { \ { 0, -60 }, \ { 65535, 60 }, \ } } static int v4l_init(RIG *rig); static int v4l_open(RIG *rig); static int v4l_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int v4l_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int v4l_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int v4l_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int v4l_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int v4l_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *v4l_get_info(RIG *rig); /* * v4l (v1) rig capabilities. * * */ struct rig_caps v4l_caps = { RIG_MODEL(RIG_MODEL_V4L), .model_name = "SW/FM radio", .mfg_name = "Video4Linux", .version = "20120107.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_DEVICE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 1, .has_get_func = V4L_FUNC, .has_set_func = V4L_FUNC, .has_get_level = V4L_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(V4L_LEVEL_ALL), .has_get_parm = V4L_PARM_ALL, .has_set_parm = RIG_PARM_SET(V4L_PARM_ALL), .vfo_ops = RIG_OP_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 65535 } }, }, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* will be rewritten at runtime */ .rx_range_list1 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_WFM, 100}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(230)}, /* guess */ {RIG_MODE_AM, kHz(8)}, /* guess */ RIG_FLT_END, }, .str_cal = V4L_STR_CAL, .rig_init = v4l_init, .rig_open = v4l_open, .set_freq = v4l_set_freq, .get_freq = v4l_get_freq, .set_func = v4l_set_func, .get_func = v4l_get_func, .set_level = v4l_set_level, .get_level = v4l_get_level, .get_info = v4l_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #include "videodev.h" #define DEFAULT_V4L_PATH "/dev/radio0" int v4l_init(RIG *rig) { RIGPORT(rig)->type.rig = RIG_PORT_DEVICE; strncpy(RIGPORT(rig)->pathname, DEFAULT_V4L_PATH, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int v4l_open(RIG *rig) { int i; struct video_tuner vt; struct rig_state *rs = STATE(rig); for (i = 0; i < 8; i++) { int ret; double fact; vt.tuner = i; ret = ioctl(RIGPORT(rig)->fd, VIDIOCGTUNER, &vt); if (ret < 0) { break; } fact = (vt.flags & VIDEO_TUNER_LOW) == 0 ? 16 : 16000; rs->rx_range_list[i].startf = vt.rangelow / fact; rs->rx_range_list[i].endf = vt.rangehigh / fact; rs->rx_range_list[i].modes = vt.rangehigh / fact < MHz(30) ? RIG_MODE_AM : RIG_MODE_WFM; /* hack! hack! store the resolution in low_power! */ rs->rx_range_list[i].low_power = rint(fact); } return RIG_OK; } int v4l_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct video_tuner vt; const freq_range_t *range; unsigned long f; double fact; int ret; /* AM or WFM */ range = rig_get_range(rs->rx_range_list, freq, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } /* at this point, we are trying to tune to a frequency */ vt.tuner = (rs->rx_range_list - range) / sizeof(freq_range_t); ret = ioctl(rp->fd, VIDIOCSTUNER, &vt); /* set tuner # */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSTUNER: %s\n", strerror(errno)); return -RIG_EIO; } fact = range->low_power; f = rint(freq * fact); /* rounding to nearest int */ ret = ioctl(rp->fd, VIDIOCSFREQ, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSFREQ: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct rig_state *rs = STATE(rig); const freq_range_t *range; unsigned long f; double fact; int ret; ret = ioctl(RIGPORT(rig)->fd, VIDIOCGFREQ, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGFREQ: %s\n", strerror(errno)); return -RIG_EIO; } /* FIXME: remember tuner and current *fact* */ range = rig_get_range(rs->rx_range_list, f / 16, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } fact = range->low_power; *freq = f / fact; return RIG_OK; } int v4l_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct video_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(rp->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } va.flags = status ? VIDEO_AUDIO_MUTE : 0; ret = ioctl(rp->fd, VIDIOCSAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct video_audio va; int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(RIGPORT(rig)->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } *status = (va.flags & VIDEO_AUDIO_MUTE) == VIDEO_AUDIO_MUTE ; break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct video_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; ret = ioctl(rp->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } switch (level) { case RIG_LEVEL_AF: va.volume = val.f * 65535; break; default: return -RIG_EINVAL; } ret = ioctl(rp->fd, VIDIOCSAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCSAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct video_audio va; struct video_tuner vt; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (level) { case RIG_LEVEL_AF: ret = ioctl(rp->fd, VIDIOCGAUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGAUDIO: %s\n", strerror(errno)); return -RIG_EIO; } val->f = (float)va.volume / 65535.; break; case RIG_LEVEL_RAWSTR: ret = ioctl(rp->fd, VIDIOCGTUNER, &vt); /* get info */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGTUNER: %s\n", strerror(errno)); return -RIG_EIO; } val->i = vt.signal; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * FIXME: static buf does not allow reentrancy! */ const char *v4l_get_info(RIG *rig) { static struct video_tuner vt; int ret; vt.tuner = 0; ret = ioctl(RIGPORT(rig)->fd, VIDIOCGTUNER, &vt); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOCGTUNER: %s\n", strerror(errno)); return "Get info failed"; } return vt.name; } #endif /* V4L_IOCTL */ hamlib-4.6.2/rigs/tuner/videodev2.h0000644000175000017500000017753714752216205014071 00000000000000/* * Video for Linux Two header file * * Copyright (C) 1999-2007 the contributors * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Alternatively you can redistribute this file under the terms of the * BSD license as stated below: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of its contributors may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Header file for v4l or V4L2 drivers and applications * with public API. * All kernel-specific stuff were moved to media/v4l2-dev.h, so * no #if __KERNEL tests are allowed here * * See http://linuxtv.org for more info * * Author: Bill Dirks * Justin Schoeman * Hans Verkuil * et al. */ #ifndef __LINUX_VIDEODEV2_H #define __LINUX_VIDEODEV2_H #include #include #include /* * Common stuff for both V4L1 and V4L2 * Moved from videodev.h */ #define VIDEO_MAX_FRAME 32 /* These defines are V4L1 specific and should not be used with the V4L2 API! They will be removed from this header in the future. */ #define VID_TYPE_CAPTURE 1 /* Can capture */ #define VID_TYPE_TUNER 2 /* Can tune */ #define VID_TYPE_TELETEXT 4 /* Does teletext */ #define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ #define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ #define VID_TYPE_CLIPPING 32 /* Can clip */ #define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ #define VID_TYPE_SCALES 128 /* Scalable */ #define VID_TYPE_MONOCHROME 256 /* Monochrome only */ #define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ #define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ #define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ #define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ #define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ /* * M I S C E L L A N E O U S */ /* Four-character-code (FOURCC) */ #define v4l2_fourcc(a, b, c, d)\ ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) /* * E N U M S */ enum v4l2_field { V4L2_FIELD_ANY = 0, /* driver can choose from none, top, bottom, interlaced depending on whatever it thinks is approximate ... */ V4L2_FIELD_NONE = 1, /* this device has no fields ... */ V4L2_FIELD_TOP = 2, /* top field only */ V4L2_FIELD_BOTTOM = 3, /* bottom field only */ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one buffer, top-bottom order */ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into separate buffers */ V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field first and the top field is transmitted first */ V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field first and the bottom field is transmitted first */ }; #define V4L2_FIELD_HAS_TOP(field) \ ((field) == V4L2_FIELD_TOP ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTTOM(field) \ ((field) == V4L2_FIELD_BOTTOM ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTH(field) \ ((field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, V4L2_BUF_TYPE_VBI_CAPTURE = 4, V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, #if 1 /* Experimental */ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, #endif V4L2_BUF_TYPE_PRIVATE = 0x80, }; enum v4l2_tuner_type { V4L2_TUNER_RADIO = 1, V4L2_TUNER_ANALOG_TV = 2, V4L2_TUNER_DIGITAL_TV = 3, }; enum v4l2_memory { V4L2_MEMORY_MMAP = 1, V4L2_MEMORY_USERPTR = 2, V4L2_MEMORY_OVERLAY = 3, }; /* see also http://vektor.theorem.ca/graphics/ycbcr/ */ enum v4l2_colorspace { /* ITU-R 601 -- broadcast NTSC/PAL */ V4L2_COLORSPACE_SMPTE170M = 1, /* 1125-Line (US) HDTV */ V4L2_COLORSPACE_SMPTE240M = 2, /* HD and modern captures. */ V4L2_COLORSPACE_REC709 = 3, /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ V4L2_COLORSPACE_BT878 = 4, /* These should be useful. Assume 601 extents. */ V4L2_COLORSPACE_470_SYSTEM_M = 5, V4L2_COLORSPACE_470_SYSTEM_BG = 6, /* I know there will be cameras that send this. So, this is * unspecified chromaticities and full 0-255 on each of the * Y'CbCr components */ V4L2_COLORSPACE_JPEG = 7, /* For RGB colourspaces, this is probably a good start. */ V4L2_COLORSPACE_SRGB = 8, }; enum v4l2_priority { V4L2_PRIORITY_UNSET = 0, /* not initialized */ V4L2_PRIORITY_BACKGROUND = 1, V4L2_PRIORITY_INTERACTIVE = 2, V4L2_PRIORITY_RECORD = 3, V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, }; struct v4l2_rect { __s32 left; __s32 top; __s32 width; __s32 height; }; struct v4l2_fract { __u32 numerator; __u32 denominator; }; /* * D R I V E R C A P A B I L I T I E S */ struct v4l2_capability { __u8 driver[16]; /* i.e. "bttv" */ __u8 card[32]; /* i.e. "Hauppauge WinTV" */ __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ __u32 version; /* should use KERNEL_VERSION() */ __u32 capabilities; /* Device capabilities */ __u32 reserved[4]; }; /* Values for 'capabilities' field */ #define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ #define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ #define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ #define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ #define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ #define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ #define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ #define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ #define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ #define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ #define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ #define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ #define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ #define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ /* * V I D E O I M A G E F O R M A T */ struct v4l2_pix_format { __u32 width; __u32 height; __u32 pixelformat; enum v4l2_field field; __u32 bytesperline; /* for padding, zero if unused */ __u32 sizeimage; enum v4l2_colorspace colorspace; __u32 priv; /* private data, depends on pixelformat */ }; /* Pixel format FOURCC depth Description */ /* RGB formats */ #define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ #define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ #define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ #define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ #define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ #define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ #define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ #define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ #define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ #define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ /* Grey formats */ #define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ #define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ #define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ #define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ /* Palette formats */ #define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ /* Luminance+Chrominance formats */ #define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ #define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ #define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ #define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ #define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ #define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ #define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ #define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ #define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ #define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ #define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ #define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ #define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ /* 10bit raw bayer DPCM compressed to 8 bits */ #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') /* * 10bit raw bayer, expanded to 16 bits * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... */ #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ /* compressed formats */ #define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ #define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ #define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ #define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */ /* Vendor-specific formats */ #define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ #define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ #define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ #define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ #define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ #define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ #define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ #define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ #define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ #define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ #define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ #define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ /* * F O R M A T E N U M E R A T I O N */ struct v4l2_fmtdesc { __u32 index; /* Format number */ enum v4l2_buf_type type; /* buffer type */ __u32 flags; __u8 description[32]; /* Description string */ __u32 pixelformat; /* Format fourcc */ __u32 reserved[4]; }; #define V4L2_FMT_FLAG_COMPRESSED 0x0001 #define V4L2_FMT_FLAG_EMULATED 0x0002 #if 1 /* Experimental Frame Size and frame rate enumeration */ /* * F R A M E S I Z E E N U M E R A T I O N */ enum v4l2_frmsizetypes { V4L2_FRMSIZE_TYPE_DISCRETE = 1, V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, V4L2_FRMSIZE_TYPE_STEPWISE = 3, }; struct v4l2_frmsize_discrete { __u32 width; /* Frame width [pixel] */ __u32 height; /* Frame height [pixel] */ }; struct v4l2_frmsize_stepwise { __u32 min_width; /* Minimum frame width [pixel] */ __u32 max_width; /* Maximum frame width [pixel] */ __u32 step_width; /* Frame width step size [pixel] */ __u32 min_height; /* Minimum frame height [pixel] */ __u32 max_height; /* Maximum frame height [pixel] */ __u32 step_height; /* Frame height step size [pixel] */ }; struct v4l2_frmsizeenum { __u32 index; /* Frame size number */ __u32 pixel_format; /* Pixel format */ __u32 type; /* Frame size type the device supports. */ union { /* Frame size */ struct v4l2_frmsize_discrete discrete; struct v4l2_frmsize_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; /* * F R A M E R A T E E N U M E R A T I O N */ enum v4l2_frmivaltypes { V4L2_FRMIVAL_TYPE_DISCRETE = 1, V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, V4L2_FRMIVAL_TYPE_STEPWISE = 3, }; struct v4l2_frmival_stepwise { struct v4l2_fract min; /* Minimum frame interval [s] */ struct v4l2_fract max; /* Maximum frame interval [s] */ struct v4l2_fract step; /* Frame interval step size [s] */ }; struct v4l2_frmivalenum { __u32 index; /* Frame format index */ __u32 pixel_format; /* Pixel format */ __u32 width; /* Frame width */ __u32 height; /* Frame height */ __u32 type; /* Frame interval type the device supports. */ union { /* Frame interval */ struct v4l2_fract discrete; struct v4l2_frmival_stepwise stepwise; }; __u32 reserved[2]; /* Reserved space for future use */ }; #endif /* * T I M E C O D E */ struct v4l2_timecode { __u32 type; __u32 flags; __u8 frames; __u8 seconds; __u8 minutes; __u8 hours; __u8 userbits[4]; }; /* Type */ #define V4L2_TC_TYPE_24FPS 1 #define V4L2_TC_TYPE_25FPS 2 #define V4L2_TC_TYPE_30FPS 3 #define V4L2_TC_TYPE_50FPS 4 #define V4L2_TC_TYPE_60FPS 5 /* Flags */ #define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ #define V4L2_TC_FLAG_COLORFRAME 0x0002 #define V4L2_TC_USERBITS_field 0x000C #define V4L2_TC_USERBITS_USERDEFINED 0x0000 #define V4L2_TC_USERBITS_8BITCHARS 0x0008 /* The above is based on SMPTE timecodes */ struct v4l2_jpegcompression { int quality; int APPn; /* Number of APP segment to be written, * must be 0..15 */ int APP_len; /* Length of data in JPEG APPn segment */ char APP_data[60]; /* Data in the JPEG APPn segment. */ int COM_len; /* Length of data in JPEG COM segment */ char COM_data[60]; /* Data in JPEG COM segment */ __u32 jpeg_markers; /* Which markers should go into the JPEG * output. Unless you exactly know what * you do, leave them untouched. * Including less markers will make the * resulting code smaller, but there will * be fewer applications which can read it. * The presence of the APP and COM marker * is influenced by APP_len and COM_len * ONLY, not by this property! */ #define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ #define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ #define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ #define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ #define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will * always use APP0 */ }; /* * M E M O R Y - M A P P I N G B U F F E R S */ struct v4l2_requestbuffers { __u32 count; enum v4l2_buf_type type; enum v4l2_memory memory; __u32 reserved[2]; }; struct v4l2_buffer { __u32 index; enum v4l2_buf_type type; __u32 bytesused; __u32 flags; enum v4l2_field field; struct timeval timestamp; struct v4l2_timecode timecode; __u32 sequence; /* memory location */ enum v4l2_memory memory; union { __u32 offset; unsigned long userptr; } m; __u32 length; __u32 input; __u32 reserved; }; /* Flags for 'flags' field */ #define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ #define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ #define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ #define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ #define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ #define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ /* Buffer is ready, but the data contained within is corrupted. */ #define V4L2_BUF_FLAG_ERROR 0x0040 #define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ #define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ /* * O V E R L A Y P R E V I E W */ struct v4l2_framebuffer { __u32 capability; __u32 flags; /* FIXME: in theory we should pass something like PCI device + memory * region + offset instead of some physical address */ void *base; struct v4l2_pix_format fmt; }; /* Flags for the 'capability' field. Read only */ #define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 #define V4L2_FBUF_CAP_CHROMAKEY 0x0002 #define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 #define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 #define V4L2_FBUF_CAP_LOCAL_BETA 0x0010 #define V4L2_FBUF_CAP_GLOBAL_BETA 0x0020 #define V4L2_FBUF_CAP_LOCAL_INV_BETA 0x0040 #define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 /* Flags for the 'flags' field. */ #define V4L2_FBUF_FLAG_PRIMARY 0x0001 #define V4L2_FBUF_FLAG_OVERLAY 0x0002 #define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 #define V4L2_FBUF_FLAG_LOCAL_BETA 0x0008 #define V4L2_FBUF_FLAG_GLOBAL_BETA 0x0010 #define V4L2_FBUF_FLAG_LOCAL_INV_BETA 0x0020 #define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 struct v4l2_clip { struct v4l2_rect c; struct v4l2_clip *next; }; struct v4l2_window { struct v4l2_rect w; enum v4l2_field field; __u32 chromakey; struct v4l2_clip *clips; __u32 clipcount; void *bitmap; __u8 global_alpha; }; /* * C A P T U R E P A R A M E T E R S */ struct v4l2_captureparm { __u32 capability; /* Supported modes */ __u32 capturemode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in .1us units */ __u32 extendedmode; /* Driver-specific extensions */ __u32 readbuffers; /* # of buffers for read */ __u32 reserved[4]; }; /* Flags for 'capability' and 'capturemode' fields */ #define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ #define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ struct v4l2_outputparm { __u32 capability; /* Supported modes */ __u32 outputmode; /* Current mode */ struct v4l2_fract timeperframe; /* Time per frame in seconds */ __u32 extendedmode; /* Driver-specific extensions */ __u32 writebuffers; /* # of buffers for write */ __u32 reserved[4]; }; /* * I N P U T I M A G E C R O P P I N G */ struct v4l2_cropcap { enum v4l2_buf_type type; struct v4l2_rect bounds; struct v4l2_rect defrect; struct v4l2_fract pixelaspect; }; struct v4l2_crop { enum v4l2_buf_type type; struct v4l2_rect c; }; /* * A N A L O G V I D E O S T A N D A R D */ typedef __u64 v4l2_std_id; /* one bit for each */ #define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) #define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) #define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) #define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) #define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) #define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) #define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) #define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) #define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) #define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) #define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) #define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) #define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) #define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) #define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) #define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) #define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) #define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) #define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) #define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) #define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) #define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) #define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) #define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) /* ATSC/HDTV */ #define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) #define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) /* FIXME: Although std_id is 64 bits, there is an issue on PPC32 architecture that makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding this value to 32 bits. As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), it should work fine. However, if needed to add more than two standards, v4l2-common.c should be fixed. */ /* some merged standards */ #define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) #define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) #define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) #define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK) /* some common needed stuff */ #define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ V4L2_STD_PAL_B1 |\ V4L2_STD_PAL_G) #define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ V4L2_STD_PAL_D1 |\ V4L2_STD_PAL_K) #define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ V4L2_STD_PAL_DK |\ V4L2_STD_PAL_H |\ V4L2_STD_PAL_I) #define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ V4L2_STD_NTSC_M_JP |\ V4L2_STD_NTSC_M_KR) #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ V4L2_STD_SECAM_K |\ V4L2_STD_SECAM_K1) #define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ V4L2_STD_SECAM_G |\ V4L2_STD_SECAM_H |\ V4L2_STD_SECAM_DK |\ V4L2_STD_SECAM_L |\ V4L2_STD_SECAM_LC) #define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ V4L2_STD_PAL_60 |\ V4L2_STD_NTSC |\ V4L2_STD_NTSC_443) #define V4L2_STD_625_50 (V4L2_STD_PAL |\ V4L2_STD_PAL_N |\ V4L2_STD_PAL_Nc |\ V4L2_STD_SECAM) #define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ V4L2_STD_ATSC_16_VSB) #define V4L2_STD_UNKNOWN 0 #define V4L2_STD_ALL (V4L2_STD_525_60 |\ V4L2_STD_625_50) struct v4l2_standard { __u32 index; v4l2_std_id id; __u8 name[24]; struct v4l2_fract frameperiod; /* Frames, not fields */ __u32 framelines; __u32 reserved[4]; }; /* * V I D E O T I M I N G S D V P R E S E T */ struct v4l2_dv_preset { __u32 preset; __u32 reserved[4]; }; /* * D V P R E S E T S E N U M E R A T I O N */ struct v4l2_dv_enum_preset { __u32 index; __u32 preset; __u8 name[32]; /* Name of the preset timing */ __u32 width; __u32 height; __u32 reserved[4]; }; /* * D V P R E S E T V A L U E S */ #define V4L2_DV_INVALID 0 #define V4L2_DV_480P59_94 1 /* BT.1362 */ #define V4L2_DV_576P50 2 /* BT.1362 */ #define V4L2_DV_720P24 3 /* SMPTE 296M */ #define V4L2_DV_720P25 4 /* SMPTE 296M */ #define V4L2_DV_720P30 5 /* SMPTE 296M */ #define V4L2_DV_720P50 6 /* SMPTE 296M */ #define V4L2_DV_720P59_94 7 /* SMPTE 274M */ #define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ #define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ #define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ #define V4L2_DV_1080I25 11 /* BT.1120 */ #define V4L2_DV_1080I50 12 /* SMPTE 296M */ #define V4L2_DV_1080I60 13 /* SMPTE 296M */ #define V4L2_DV_1080P24 14 /* SMPTE 296M */ #define V4L2_DV_1080P25 15 /* SMPTE 296M */ #define V4L2_DV_1080P30 16 /* SMPTE 296M */ #define V4L2_DV_1080P50 17 /* BT.1120 */ #define V4L2_DV_1080P60 18 /* BT.1120 */ /* * D V B T T I M I N G S */ /* BT.656/BT.1120 timing data */ struct v4l2_bt_timings { __u32 width; /* width in pixels */ __u32 height; /* height in lines */ __u32 interlaced; /* Interlaced or progressive */ __u32 polarities; /* Positive or negative polarity */ __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ __u32 hfrontporch; /* Horizpontal front porch in pixels */ __u32 hsync; /* Horizontal Sync length in pixels */ __u32 hbackporch; /* Horizontal back porch in pixels */ __u32 vfrontporch; /* Vertical front porch in pixels */ __u32 vsync; /* Vertical Sync length in lines */ __u32 vbackporch; /* Vertical back porch in lines */ __u32 il_vfrontporch; /* Vertical front porch for bottom field of * interlaced field formats */ __u32 il_vsync; /* Vertical sync length for bottom field of * interlaced field formats */ __u32 il_vbackporch; /* Vertical back porch for bottom field of * interlaced field formats */ __u32 reserved[16]; } __attribute__ ((packed)); /* Interlaced or progressive format */ #define V4L2_DV_PROGRESSIVE 0 #define V4L2_DV_INTERLACED 1 /* Polarities. If bit is not set, it is assumed to be negative polarity */ #define V4L2_DV_VSYNC_POS_POL 0x00000001 #define V4L2_DV_HSYNC_POS_POL 0x00000002 /* DV timings */ struct v4l2_dv_timings { __u32 type; union { struct v4l2_bt_timings bt; __u32 reserved[32]; }; } __attribute__ ((packed)); /* Values for the type field */ #define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ /* * V I D E O I N P U T S */ struct v4l2_input { __u32 index; /* Which input */ __u8 name[32]; /* Label */ __u32 type; /* Type of input */ __u32 audioset; /* Associated audios (bitfield) */ __u32 tuner; /* Associated tuner */ v4l2_std_id std; __u32 status; __u32 capabilities; __u32 reserved[3]; }; /* Values for the 'type' field */ #define V4L2_INPUT_TYPE_TUNER 1 #define V4L2_INPUT_TYPE_CAMERA 2 /* field 'status' - general */ #define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ #define V4L2_IN_ST_NO_SIGNAL 0x00000002 #define V4L2_IN_ST_NO_COLOR 0x00000004 /* field 'status' - sensor orientation */ /* If sensor is mounted upside down set both bits */ #define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ #define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ /* field 'status' - analog */ #define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ #define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ /* field 'status' - digital */ #define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ #define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ #define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ /* field 'status' - VCR and set-top box */ #define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ #define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ #define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ /* capabilities flags */ #define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ #define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ #define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ /* * V I D E O O U T P U T S */ struct v4l2_output { __u32 index; /* Which output */ __u8 name[32]; /* Label */ __u32 type; /* Type of output */ __u32 audioset; /* Associated audios (bitfield) */ __u32 modulator; /* Associated modulator */ v4l2_std_id std; __u32 capabilities; __u32 reserved[3]; }; /* Values for the 'type' field */ #define V4L2_OUTPUT_TYPE_MODULATOR 1 #define V4L2_OUTPUT_TYPE_ANALOG 2 #define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 /* capabilities flags */ #define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ #define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ #define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ /* * C O N T R O L S */ struct v4l2_control { __u32 id; __s32 value; }; struct v4l2_ext_control { __u32 id; __u32 size; __u32 reserved2[1]; union { __s32 value; __s64 value64; char *string; }; } __attribute__ ((packed)); struct v4l2_ext_controls { __u32 ctrl_class; __u32 count; __u32 error_idx; __u32 reserved[2]; struct v4l2_ext_control *controls; }; /* Values for ctrl_class field */ #define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ #define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ #define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ #define V4L2_CTRL_ID_MASK (0x0fffffff) #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) #define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) enum v4l2_ctrl_type { V4L2_CTRL_TYPE_INTEGER = 1, V4L2_CTRL_TYPE_BOOLEAN = 2, V4L2_CTRL_TYPE_MENU = 3, V4L2_CTRL_TYPE_BUTTON = 4, V4L2_CTRL_TYPE_INTEGER64 = 5, V4L2_CTRL_TYPE_CTRL_CLASS = 6, V4L2_CTRL_TYPE_STRING = 7, }; /* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ struct v4l2_queryctrl { __u32 id; enum v4l2_ctrl_type type; __u8 name[32]; /* Whatever */ __s32 minimum; /* Note signedness */ __s32 maximum; __s32 step; __s32 default_value; __u32 flags; __u32 reserved[2]; }; /* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ struct v4l2_querymenu { __u32 id; __u32 index; __u8 name[32]; /* Whatever */ __u32 reserved; }; /* Control flags */ #define V4L2_CTRL_FLAG_DISABLED 0x0001 #define V4L2_CTRL_FLAG_GRABBED 0x0002 #define V4L2_CTRL_FLAG_READ_ONLY 0x0004 #define V4L2_CTRL_FLAG_UPDATE 0x0008 #define V4L2_CTRL_FLAG_INACTIVE 0x0010 #define V4L2_CTRL_FLAG_SLIDER 0x0020 #define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 /* Query flag, to be ORed with the control ID */ #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 /* User-class control IDs defined by V4L2 */ #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) #define V4L2_CID_USER_BASE V4L2_CID_BASE /* IDs reserved for driver specific controls */ #define V4L2_CID_PRIVATE_BASE 0x08000000 #define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) #define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) #define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) #define V4L2_CID_SATURATION (V4L2_CID_BASE+2) #define V4L2_CID_HUE (V4L2_CID_BASE+3) #define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) #define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) #define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) #define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) #define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) #define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) #define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ #define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) #define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) #define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) #define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) #define V4L2_CID_GAMMA (V4L2_CID_BASE+16) #define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ #define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) #define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) #define V4L2_CID_GAIN (V4L2_CID_BASE+19) #define V4L2_CID_HFLIP (V4L2_CID_BASE+20) #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) /* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ #define V4L2_CID_HCENTER (V4L2_CID_BASE+22) #define V4L2_CID_VCENTER (V4L2_CID_BASE+23) #define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) enum v4l2_power_line_frequency { V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, }; #define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) #define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) #define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) #define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) #define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) #define V4L2_CID_COLORFX (V4L2_CID_BASE+31) enum v4l2_colorfx { V4L2_COLORFX_NONE = 0, V4L2_COLORFX_BW = 1, V4L2_COLORFX_SEPIA = 2, V4L2_COLORFX_NEGATIVE = 3, V4L2_COLORFX_EMBOSS = 4, V4L2_COLORFX_SKETCH = 5, V4L2_COLORFX_SKY_BLUE = 6, V4L2_COLORFX_GRASS_GREEN = 7, V4L2_COLORFX_SKIN_WHITEN = 8, V4L2_COLORFX_VIVID = 9, }; #define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) #define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) #define V4L2_CID_ROTATE (V4L2_CID_BASE+34) #define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) #define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) /* last CID + 1 */ #define V4L2_CID_LASTP1 (V4L2_CID_BASE+37) /* MPEG-class control IDs defined by V4L2 */ #define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) #define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) /* MPEG streams */ #define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) enum v4l2_mpeg_stream_type { V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ }; #define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) #define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) #define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) #define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) #define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) #define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) #define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) enum v4l2_mpeg_stream_vbi_fmt { V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ }; /* MPEG audio */ #define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) enum v4l2_mpeg_audio_sampling_freq { V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, }; #define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) enum v4l2_mpeg_audio_encoding { V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, V4L2_MPEG_AUDIO_ENCODING_AAC = 3, V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, }; #define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) enum v4l2_mpeg_audio_l1_bitrate { V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, }; #define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) enum v4l2_mpeg_audio_l2_bitrate { V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, }; #define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) enum v4l2_mpeg_audio_l3_bitrate { V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, }; #define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) enum v4l2_mpeg_audio_mode { V4L2_MPEG_AUDIO_MODE_STEREO = 0, V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, V4L2_MPEG_AUDIO_MODE_DUAL = 2, V4L2_MPEG_AUDIO_MODE_MONO = 3, }; #define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) enum v4l2_mpeg_audio_mode_extension { V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, }; #define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) enum v4l2_mpeg_audio_emphasis { V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, }; #define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) enum v4l2_mpeg_audio_crc { V4L2_MPEG_AUDIO_CRC_NONE = 0, V4L2_MPEG_AUDIO_CRC_CRC16 = 1, }; #define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) #define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) #define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) enum v4l2_mpeg_audio_ac3_bitrate { V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, }; /* MPEG video */ #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) enum v4l2_mpeg_video_encoding { V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, }; #define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) enum v4l2_mpeg_video_aspect { V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, }; #define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) #define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) #define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) #define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) #define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) enum v4l2_mpeg_video_bitrate_mode { V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, }; #define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) #define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) #define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) #define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) #define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) enum v4l2_mpeg_cx2341x_video_median_filter_type { V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, }; #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) #define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) #define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) /* Camera class control IDs */ #define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) #define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) enum v4l2_exposure_auto_type { V4L2_EXPOSURE_AUTO = 0, V4L2_EXPOSURE_MANUAL = 1, V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, V4L2_EXPOSURE_APERTURE_PRIORITY = 3 }; #define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) #define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) #define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) #define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) #define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) #define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) #define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) #define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) #define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) #define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) #define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) #define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) #define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) #define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) #define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) /* FM Modulator class control IDs */ #define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) #define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) #define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) #define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) #define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) #define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) #define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) #define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) #define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) #define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) #define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) #define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) #define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) #define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) #define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) #define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) #define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) #define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) #define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) enum v4l2_preemphasis { V4L2_PREEMPHASIS_DISABLED = 0, V4L2_PREEMPHASIS_50_uS = 1, V4L2_PREEMPHASIS_75_uS = 2, }; #define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) #define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) /* * T U N I N G */ struct v4l2_tuner { __u32 index; __u8 name[32]; enum v4l2_tuner_type type; __u32 capability; __u32 rangelow; __u32 rangehigh; __u32 rxsubchans; __u32 audmode; __s32 signal; __s32 afc; __u32 reserved[4]; }; struct v4l2_modulator { __u32 index; __u8 name[32]; __u32 capability; __u32 rangelow; __u32 rangehigh; __u32 txsubchans; __u32 reserved[4]; }; /* Flags for the 'capability' field */ #define V4L2_TUNER_CAP_LOW 0x0001 #define V4L2_TUNER_CAP_NORM 0x0002 #define V4L2_TUNER_CAP_STEREO 0x0010 #define V4L2_TUNER_CAP_LANG2 0x0020 #define V4L2_TUNER_CAP_SAP 0x0020 #define V4L2_TUNER_CAP_LANG1 0x0040 #define V4L2_TUNER_CAP_RDS 0x0080 /* Flags for the 'rxsubchans' field */ #define V4L2_TUNER_SUB_MONO 0x0001 #define V4L2_TUNER_SUB_STEREO 0x0002 #define V4L2_TUNER_SUB_LANG2 0x0004 #define V4L2_TUNER_SUB_SAP 0x0004 #define V4L2_TUNER_SUB_LANG1 0x0008 #define V4L2_TUNER_SUB_RDS 0x0010 /* Values for the 'audmode' field */ #define V4L2_TUNER_MODE_MONO 0x0000 #define V4L2_TUNER_MODE_STEREO 0x0001 #define V4L2_TUNER_MODE_LANG2 0x0002 #define V4L2_TUNER_MODE_SAP 0x0002 #define V4L2_TUNER_MODE_LANG1 0x0003 #define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 struct v4l2_frequency { __u32 tuner; enum v4l2_tuner_type type; __u32 frequency; __u32 reserved[8]; }; struct v4l2_hw_freq_seek { __u32 tuner; enum v4l2_tuner_type type; __u32 seek_upward; __u32 wrap_around; __u32 reserved[8]; }; /* * R D S */ struct v4l2_rds_data { __u8 lsb; __u8 msb; __u8 block; } __attribute__ ((packed)); #define V4L2_RDS_BLOCK_MSK 0x7 #define V4L2_RDS_BLOCK_A 0 #define V4L2_RDS_BLOCK_B 1 #define V4L2_RDS_BLOCK_C 2 #define V4L2_RDS_BLOCK_D 3 #define V4L2_RDS_BLOCK_C_ALT 4 #define V4L2_RDS_BLOCK_INVALID 7 #define V4L2_RDS_BLOCK_CORRECTED 0x40 #define V4L2_RDS_BLOCK_ERROR 0x80 /* * A U D I O */ struct v4l2_audio { __u32 index; __u8 name[32]; __u32 capability; __u32 mode; __u32 reserved[2]; }; /* Flags for the 'capability' field */ #define V4L2_AUDCAP_STEREO 0x00001 #define V4L2_AUDCAP_AVL 0x00002 /* Flags for the 'mode' field */ #define V4L2_AUDMODE_AVL 0x00001 struct v4l2_audioout { __u32 index; __u8 name[32]; __u32 capability; __u32 mode; __u32 reserved[2]; }; /* * M P E G S E R V I C E S * * NOTE: EXPERIMENTAL API */ #if 1 #define V4L2_ENC_IDX_FRAME_I (0) #define V4L2_ENC_IDX_FRAME_P (1) #define V4L2_ENC_IDX_FRAME_B (2) #define V4L2_ENC_IDX_FRAME_MASK (0xf) struct v4l2_enc_idx_entry { __u64 offset; __u64 pts; __u32 length; __u32 flags; __u32 reserved[2]; }; #define V4L2_ENC_IDX_ENTRIES (64) struct v4l2_enc_idx { __u32 entries; __u32 entries_cap; __u32 reserved[4]; struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; }; #define V4L2_ENC_CMD_START (0) #define V4L2_ENC_CMD_STOP (1) #define V4L2_ENC_CMD_PAUSE (2) #define V4L2_ENC_CMD_RESUME (3) /* Flags for V4L2_ENC_CMD_STOP */ #define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) struct v4l2_encoder_cmd { __u32 cmd; __u32 flags; union { struct { __u32 data[8]; } raw; }; }; #endif /* * D A T A S E R V I C E S ( V B I ) * * Data services API by Michael Schimek */ /* Raw VBI */ struct v4l2_vbi_format { __u32 sampling_rate; /* in 1 Hz */ __u32 offset; __u32 samples_per_line; __u32 sample_format; /* V4L2_PIX_FMT_* */ __s32 start[2]; __u32 count[2]; __u32 flags; /* V4L2_VBI_* */ __u32 reserved[2]; /* must be zero */ }; /* VBI flags */ #define V4L2_VBI_UNSYNC (1 << 0) #define V4L2_VBI_INTERLACED (1 << 1) /* Sliced VBI * * This implements is a proposal V4L2 API to allow SLICED VBI * required for some hardware encoders. It should change without * notice in the definitive implementation. */ struct v4l2_sliced_vbi_format { __u16 service_set; /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field (equals frame lines 313-336 for 625 line video standards, 263-286 for 525 line standards) */ __u16 service_lines[2][24]; __u32 io_size; __u32 reserved[2]; /* must be zero */ }; /* Teletext World System Teletext (WST), defined on ITU-R BT.653-2 */ #define V4L2_SLICED_TELETEXT_B (0x0001) /* Video Program System, defined on ETS 300 231*/ #define V4L2_SLICED_VPS (0x0400) /* Closed Caption, defined on EIA-608 */ #define V4L2_SLICED_CAPTION_525 (0x1000) /* Wide Screen System, defined on ITU-R BT1119.1 */ #define V4L2_SLICED_WSS_625 (0x4000) #define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) #define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) struct v4l2_sliced_vbi_cap { __u16 service_set; /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field (equals frame lines 313-336 for 625 line video standards, 263-286 for 525 line standards) */ __u16 service_lines[2][24]; enum v4l2_buf_type type; __u32 reserved[3]; /* must be 0 */ }; struct v4l2_sliced_vbi_data { __u32 id; __u32 field; /* 0: first field, 1: second field */ __u32 line; /* 1-23 */ __u32 reserved; /* must be 0 */ __u8 data[48]; }; /* * Sliced VBI data inserted into MPEG Streams */ /* * V4L2_MPEG_STREAM_VBI_FMT_IVTV: * * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI * data * * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header * definitions are not included here. See the MPEG-2 specifications for details * on these headers. */ /* Line type IDs */ #define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) #define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) #define V4L2_MPEG_VBI_IVTV_WSS_625 (5) #define V4L2_MPEG_VBI_IVTV_VPS (7) struct v4l2_mpeg_vbi_itv0_line { __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ __u8 data[42]; /* Sliced VBI data for the line */ } __attribute__ ((packed)); struct v4l2_mpeg_vbi_itv0 { __le32 linemask[2]; /* Bitmasks of VBI service lines present */ struct v4l2_mpeg_vbi_itv0_line line[35]; } __attribute__ ((packed)); struct v4l2_mpeg_vbi_ITV0 { struct v4l2_mpeg_vbi_itv0_line line[36]; } __attribute__ ((packed)); #define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" #define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" struct v4l2_mpeg_vbi_fmt_ivtv { __u8 magic[4]; union { struct v4l2_mpeg_vbi_itv0 itv0; struct v4l2_mpeg_vbi_ITV0 ITV0; }; } __attribute__ ((packed)); /* * A G G R E G A T E S T R U C T U R E S */ /* Stream data format */ struct v4l2_format { enum v4l2_buf_type type; union { struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ __u8 raw_data[200]; /* user-defined */ } fmt; }; /* Stream type-dependent parameters */ struct v4l2_streamparm { enum v4l2_buf_type type; union { struct v4l2_captureparm capture; struct v4l2_outputparm output; __u8 raw_data[200]; /* user-defined */ } parm; }; /* * E V E N T S */ #define V4L2_EVENT_ALL 0 #define V4L2_EVENT_VSYNC 1 #define V4L2_EVENT_EOS 2 #define V4L2_EVENT_PRIVATE_START 0x08000000 /* Payload for V4L2_EVENT_VSYNC */ struct v4l2_event_vsync { /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ __u8 field; } __attribute__ ((packed)); struct v4l2_event { __u32 type; union { struct v4l2_event_vsync vsync; __u8 data[64]; } u; __u32 pending; __u32 sequence; struct timespec timestamp; __u32 reserved[9]; }; struct v4l2_event_subscription { __u32 type; __u32 reserved[7]; }; /* * A D V A N C E D D E B U G G I N G * * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! */ /* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ #define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ #define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ #define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ #define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ struct v4l2_dbg_match { __u32 type; /* Match type */ union { /* Match this chip, meaning determined by type */ __u32 addr; char name[32]; }; } __attribute__ ((packed)); struct v4l2_dbg_register { struct v4l2_dbg_match match; __u32 size; /* register size in bytes */ __u64 reg; __u64 val; } __attribute__ ((packed)); /* VIDIOC_DBG_G_CHIP_IDENT */ struct v4l2_dbg_chip_ident { struct v4l2_dbg_match match; __u32 ident; /* chip identifier as specified in */ __u32 revision; /* chip revision, chip specific */ } __attribute__ ((packed)); /* * I O C T L C O D E S F O R V I D E O D E V I C E S * */ #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) #define VIDIOC_RESERVED _IO('V', 1) #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) #define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) #define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) #define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) #define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) #define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) #define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) #define VIDIOC_OVERLAY _IOW('V', 14, int) #define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) #define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) #define VIDIOC_STREAMON _IOW('V', 18, int) #define VIDIOC_STREAMOFF _IOW('V', 19, int) #define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) #define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) #define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) #define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) #define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) #define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) #define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) #define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) #define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) #define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) #define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) #define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) #define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) #define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) #define VIDIOC_G_INPUT _IOR('V', 38, int) #define VIDIOC_S_INPUT _IOWR('V', 39, int) #define VIDIOC_G_OUTPUT _IOR('V', 46, int) #define VIDIOC_S_OUTPUT _IOWR('V', 47, int) #define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) #define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) #define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) #define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) #define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) #define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) #define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) #define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) #define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) #define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) #define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) #define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) #define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) #define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) #define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) #define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) #define VIDIOC_G_PRIORITY _IOR('V', 67, enum v4l2_priority) #define VIDIOC_S_PRIORITY _IOW('V', 68, enum v4l2_priority) #define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) #define VIDIOC_LOG_STATUS _IO('V', 70) #define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) #define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) #define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) #if 1 #define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) #define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) #define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) #define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) #define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) #endif #if 1 /* Experimental, meant for debugging, testing and internal use. Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. You must be root to use these ioctls. Never use these in applications! */ #define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) #define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) /* Experimental, meant for debugging, testing and internal use. Never use this ioctl in applications! */ #define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident) #endif #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) #define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) #define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) #define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) #define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) #define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) #define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) #define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) #define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) /* Reminder: when adding new ioctls please add support for them to drivers/media/video/v4l2-compat-ioctl32.c as well! */ #ifdef __OLD_VIDIOC_ /* for compatibility, will go away some day */ #define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int) #define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm) #define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control) #define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio) #define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout) #define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap) #endif #define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ #endif /* __LINUX_VIDEODEV2_H */ hamlib-4.6.2/rigs/tuner/tuner.c0000644000175000017500000000217714752216205013315 00000000000000/* * Hamlib Tuner backend - main file * Copyright (C) 2004-2011 Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "tuner.h" /* config.h */ #include "hamlib/rig.h" #include "register.h" DECLARE_INITRIG_BACKEND(tuner) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); #ifdef V4L_IOCTL rig_register(&v4l_caps); rig_register(&v4l2_caps); #endif return RIG_OK; } hamlib-4.6.2/rigs/tuner/v4l2.c0000644000175000017500000002443514752216205012750 00000000000000/* * Hamlib Tuner backend - Video4Linux (v2) description * Copyright (c) 2004-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include #include #include "hamlib/rig.h" #include "tuner.h" /* include config.h */ #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef V4L_IOCTL #include "idx_builtin.h" #define V4L2_FUNC (RIG_FUNC_MUTE) #define V4L2_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_RAWSTR) #define V4L2_PARM_ALL (RIG_PARM_NONE) #define V4L2_VFO (RIG_VFO_A) /* FIXME: per card measures? */ #define V4L2_STR_CAL { 2, { \ { 0, -60 }, \ { 65535, 60 }, \ } } static int v4l2_init(RIG *rig); static int v4l2_open(RIG *rig); static int v4l2_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int v4l2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int v4l2_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int v4l2_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int v4l2_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int v4l2_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *v4l2_get_info(RIG *rig); /* * v4l (v1) rig capabilities. * * */ struct rig_caps v4l2_caps = { RIG_MODEL(RIG_MODEL_V4L2), .model_name = "SW/FM radio", .mfg_name = "Video4Linux2", .version = "20191223.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_DEVICE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 1, .has_get_func = V4L2_FUNC, .has_set_func = V4L2_FUNC, .has_get_level = V4L2_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(V4L2_LEVEL_ALL), .has_get_parm = V4L2_PARM_ALL, .has_set_parm = RIG_PARM_SET(V4L2_PARM_ALL), .vfo_ops = RIG_OP_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 65535 } }, }, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* will be rewritten at runtime */ .rx_range_list1 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L2_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(87.9), MHz(108.9), RIG_MODE_WFM, -1, -1, V4L2_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_WFM, 100}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(230)}, /* guess */ {RIG_MODE_AM, kHz(8)}, /* guess */ RIG_FLT_END, }, .str_cal = V4L2_STR_CAL, .rig_init = v4l2_init, .rig_open = v4l2_open, .set_freq = v4l2_set_freq, .get_freq = v4l2_get_freq, .set_func = v4l2_set_func, .get_func = v4l2_get_func, .set_level = v4l2_set_level, .get_level = v4l2_get_level, .get_info = v4l2_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #include "videodev2.h" #define DEFAULT_V4L2_PATH "/dev/radio0" int v4l2_init(RIG *rig) { RIGPORT(rig)->type.rig = RIG_PORT_DEVICE; strncpy(RIGPORT(rig)->pathname, DEFAULT_V4L2_PATH, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int v4l2_open(RIG *rig) { int i; struct v4l2_tuner vt; struct rig_state *rs = STATE(rig); for (i = 0; i < 8; i++) { int ret; double fact; vt.index = i; ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_TUNER, &vt); if (ret < 0) { break; } fact = (vt.capability & V4L2_TUNER_CAP_LOW) == 0 ? 16 : 16000; rs->rx_range_list[i].startf = vt.rangelow / fact; rs->rx_range_list[i].endf = vt.rangehigh / fact; rs->rx_range_list[i].modes = vt.rangehigh / fact < MHz(30) ? RIG_MODE_AM : RIG_MODE_WFM; /* hack! hack! store the resolution in low_power! */ rs->rx_range_list[i].low_power = rint(fact); } return RIG_OK; } int v4l2_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct v4l2_tuner vt; const freq_range_t *range; unsigned long f; double fact; int ret; /* AM or WFM */ range = rig_get_range(rs->rx_range_list, freq, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } /* at this point, we are trying to tune to a frequency */ vt.index = (rs->rx_range_list - range) / sizeof(freq_range_t); ret = ioctl(rp->fd, VIDIOC_S_TUNER, &vt); /* set tuner # */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_TUNER: %s\n", strerror(errno)); return -RIG_EIO; } fact = range->low_power; f = rint(freq * fact); /* rounding to nearest int */ ret = ioctl(rp->fd, VIDIOC_S_FREQUENCY, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_FREQUENCY: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l2_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct rig_state *rs = STATE(rig); const freq_range_t *range; unsigned long f; double fact; int ret; /* FIXME */ ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_FREQUENCY, &f); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_FREQUENCY: %s\n", strerror(errno)); return -RIG_EIO; } /* FIXME: remember tuner and current *fact* */ range = rig_get_range(rs->rx_range_list, f / 16, RIG_MODE_AM | RIG_MODE_WFM); if (!range) { return -RIG_ECONF; } fact = range->low_power; *freq = f / fact; return RIG_OK; } int v4l2_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct v4l2_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(rp->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } va.capability = status ? V4L2_CID_AUDIO_MUTE : 0; ret = ioctl(rp->fd, VIDIOC_S_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l2_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct v4l2_audio va; int ret; switch (func) { case RIG_FUNC_MUTE: ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } *status = (va.capability & V4L2_CID_AUDIO_MUTE) == V4L2_CID_AUDIO_MUTE ; break; default: return -RIG_EINVAL; } return RIG_OK; } int v4l2_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct v4l2_audio va; hamlib_port_t *rp = RIGPORT(rig); int ret; ret = ioctl(rp->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } // TODO RIG_LEVEL_AGC:V4L2_CID_AUTOGAIN & RIG_LEVEL_RF:V4L2_CID_GAIN //V4L2_CID_AUDIO_VOLUME switch (level) { case RIG_LEVEL_AF: //va.volume = val.f * 65535; break; default: return -RIG_EINVAL; } ret = ioctl(rp->fd, VIDIOC_S_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_S_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } return RIG_OK; } int v4l2_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct v4l2_audio va; struct v4l2_tuner vt; hamlib_port_t *rp = RIGPORT(rig); int ret; switch (level) { case RIG_LEVEL_AF: ret = ioctl(rp->fd, VIDIOC_G_AUDIO, &va); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_AUDIO: %s\n", strerror(errno)); return -RIG_EIO; } //val->f = (float)va.volume / 65535.; break; case RIG_LEVEL_RAWSTR: /* FE_READ_SIGNAL_STRENGTH ? */ ret = ioctl(rp->fd, VIDIOC_G_TUNER, &vt); /* get info */ if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_TUNER: %s\n", strerror(errno)); return -RIG_EIO; } val->i = vt.signal; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * FIXME: static buf does not allow reentrancy! */ const char *v4l2_get_info(RIG *rig) { static struct v4l2_tuner vt; int ret; vt.index = 0; ret = ioctl(RIGPORT(rig)->fd, VIDIOC_G_TUNER, &vt); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "ioctl VIDIOC_G_TUNER: %s\n", strerror(errno)); return "Get info failed"; } return (const char *)vt.name; } #endif /* V4L_IOCTL */ hamlib-4.6.2/rigs/icmarine/0000755000175000017500000000000014752216243012521 500000000000000hamlib-4.6.2/rigs/icmarine/Makefile.am0000644000175000017500000000032514752216205014473 00000000000000#icm802.c ICMARINESRC = icm700pro.c icm710.c icm710.h icm802.c icm803.c \ icmarine.c icmarine.h noinst_LTLIBRARIES = libhamlib-icmarine.la libhamlib_icmarine_la_SOURCES = $(ICMARINESRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/icmarine/Makefile.in0000644000175000017500000005365014752216216014517 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/icmarine ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_icmarine_la_LIBADD = am__objects_1 = icm700pro.lo icm710.lo icm802.lo icm803.lo icmarine.lo am_libhamlib_icmarine_la_OBJECTS = $(am__objects_1) libhamlib_icmarine_la_OBJECTS = $(am_libhamlib_icmarine_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/icm700pro.Plo ./$(DEPDIR)/icm710.Plo \ ./$(DEPDIR)/icm802.Plo ./$(DEPDIR)/icm803.Plo \ ./$(DEPDIR)/icmarine.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_icmarine_la_SOURCES) DIST_SOURCES = $(libhamlib_icmarine_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ #icm802.c ICMARINESRC = icm700pro.c icm710.c icm710.h icm802.c icm803.c \ icmarine.c icmarine.h noinst_LTLIBRARIES = libhamlib-icmarine.la libhamlib_icmarine_la_SOURCES = $(ICMARINESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/icmarine/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/icmarine/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-icmarine.la: $(libhamlib_icmarine_la_OBJECTS) $(libhamlib_icmarine_la_DEPENDENCIES) $(EXTRA_libhamlib_icmarine_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_icmarine_la_OBJECTS) $(libhamlib_icmarine_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm700pro.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm802.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icm803.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/icmarine.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/icm700pro.Plo -rm -f ./$(DEPDIR)/icm710.Plo -rm -f ./$(DEPDIR)/icm802.Plo -rm -f ./$(DEPDIR)/icm803.Plo -rm -f ./$(DEPDIR)/icmarine.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/icm700pro.Plo -rm -f ./$(DEPDIR)/icm710.Plo -rm -f ./$(DEPDIR)/icm802.Plo -rm -f ./$(DEPDIR)/icm803.Plo -rm -f ./$(DEPDIR)/icmarine.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/icmarine/icm710.c0000644000175000017500000004136114752216205013610 00000000000000/* * Hamlib ICOM Marine backend - description of IC-M710 caps * Copyright (c) 2015 by Stephane Fillod * Copyright (c) 2017 by Michael Black W9MDB * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include "idx_builtin.h" #include "icm710.h" #include "icmarine.h" #define ICM710_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM710_RX_MODES (ICM710_MODES|RIG_MODE_AM) #define ICM710_FUNC_ALL (RIG_FUNC_NB) #define ICM710_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM710_VFO_ALL (RIG_VFO_A) #define ICM710_VFO_OPS (RIG_OP_TUNE) #define ICM710_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM710_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icm710_priv_caps icm710_priv_caps = { .default_remote_id = 0x01, /* default address */ }; struct rig_caps icm710_caps = { RIG_MODEL(RIG_MODEL_IC_M710), .model_name = "IC-M710", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM710_FUNC_ALL, .has_set_func = ICM710_FUNC_ALL, .has_get_level = ICM710_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM710_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM710_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM710_VFO_OPS, //.scan_ops = ICM710_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM710_RX_MODES, -1, -1, ICM710_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM710_MODES, W(60), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM710_MODES, W(60), W(60), ICM710_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM710_RX_MODES, -1, -1, ICM710_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM710_MODES, W(20), W(150), ICM710_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM710_MODES, W(20), W(60), ICM710_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM710_RX_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icm710_cfg_params, .set_conf = icm710_set_conf, .get_conf = icm710_get_conf, .get_conf2 = icm710_get_conf2, .priv = (void *)& icm710_priv_caps, .rig_init = icm710_init, .rig_cleanup = icm710_cleanup, .rig_open = icm710_open, .rig_close = icm710_close, .set_freq = icm710_set_freq, .get_freq = icm710_get_freq, .set_split_freq = icm710_set_tx_freq, .get_split_freq = icm710_get_tx_freq, .set_split_vfo = icm710_set_split_vfo, .get_split_vfo = icm710_get_split_vfo, .set_mode = icm710_set_mode, .get_mode = icm710_get_mode, .set_ptt = icm710_set_ptt, .get_ptt = icm710_get_ptt, .vfo_op = icm710_vfo_op, .set_level = icm710_set_level, .get_level = icm710_get_level, .set_func = icm710_set_func, .get_func = icm710_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * NMEA 0183 protocol * * Total message is maximum 82 characters, including '$' and CR+LF. * * Serial setup is 8N1, msb always 0, -> ASCII protocol * * Proprietary Extension Message format: * Byte pos Length Value Description * 0 1 0x24 '$' Start character * 1 1 0x50 'P' Type: Proprietary * 2 3 'ICO' Manufacturer ID * 5 Message Data */ /* CR LF */ #define EOM "\x0d\x0a" #define BUFSZ 96 /* * Protocol stuff */ #define CONTROLLER_ID 90 #define MD_LSB "LSB" #define MD_USB "USB" #define MD_CW "CW" #define MD_AM "AM" #define MD_FSK "AFS" #define CMD_TXFREQ "TXF" /* Transmit frequency */ #define CMD_RXFREQ "RXF" /* Receive frequency */ #define CMD_MODE "MODE" /* Mode */ #define CMD_REMOTE "REMOTE" /* Remote */ #define CMD_PTT "TRX" /* PTT */ #define CMD_AFGAIN "AFG" #define CMD_RFGAIN "RFG" #define CMD_RFPWR "TXP" #define CMD_NB "NB" #define CMD_AGC "AGC" #define CMD_TUNER "TUNER" /* Data Output Commands */ #define CMD_SMETER "SIGM" /* S-meter read */ #define CMD_SQLS "SQLS" /* Squelch status */ /* Tokens */ #define TOK_REMOTEID TOKEN_BACKEND(1) const struct confparams icm710_cfg_params[] = { { TOK_REMOTEID, "remoteid", "Remote ID", "Transceiver's remote ID", "1", RIG_CONF_NUMERIC, { .n = { 1, 99, 1 } } }, { RIG_CONF_END, NULL, } }; /* * Basically, set up *priv */ int icm710_init(RIG *rig) { struct icm710_priv_data *priv; const struct icm710_priv_caps *priv_caps; struct rig_caps *caps; if (!rig || !rig->caps) { return -RIG_EINVAL; } caps = rig->caps; if (!caps->priv) { return -RIG_ECONF; } priv_caps = (const struct icm710_priv_caps *) caps->priv; STATE(rig)->priv = (struct icm710_priv_data *)calloc(1, sizeof(struct icm710_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->remote_id = priv_caps->default_remote_id; priv->split = RIG_SPLIT_OFF; return RIG_OK; } int icm710_open(RIG *rig) { int retval = icmarine_transaction(rig, "REMOTE", "ON", NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not responding? %s\n", __func__, rigerror(retval)); } return RIG_OK; } int icm710_close(RIG *rig) { int retval = icmarine_transaction(rig, "REMOTE", "OFF", NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not responding? %s\n", __func__, rigerror(retval)); } return RIG_OK; } int icm710_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int icm710_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: priv->remote_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } int icm710_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: SNPRINTF(val, val_len, "%u", priv->remote_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int icm710_get_conf(RIG *rig, hamlib_token_t token, char *val) { return icm710_get_conf2(rig, token, val, 128); } int icm710_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; struct icm710_priv_data *priv; int retval; priv = (struct icm710_priv_data *)STATE(rig)->priv; SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); /* no error reporting upon TXFREQ failure */ if (RIG_SPLIT_OFF == priv->split) { retval = icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); if (retval != RIG_OK) { return retval; } priv->txfreq = freq; } retval = icmarine_transaction(rig, CMD_RXFREQ, freqbuf, NULL); if (retval != RIG_OK) { return retval; } priv->rxfreq = freq; return RIG_OK; } /* * icm710_get_freq * Assumes rig!=NULL, freq!=NULL * The M710 does not respond to queries so we keep our own copy of things as a virtual rig response */ int icm710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { *freq = ((struct icm710_priv_data *)STATE(rig)->priv)->rxfreq; return RIG_OK; } int icm710_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; int retval; struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); retval = icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); if (retval != RIG_OK) { return retval; } priv->txfreq = freq; return RIG_OK; } int icm710_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; *freq = priv->txfreq; return RIG_OK; } int icm710_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; /* when disabling split mode */ if (RIG_SPLIT_ON == priv->split && RIG_SPLIT_OFF == split) { int retval = icm710_set_tx_freq(rig, rx_vfo, priv->rxfreq); if (retval != RIG_OK) { return retval; } } priv->split = split; return RIG_OK; } int icm710_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = rx_vfo; return RIG_OK; } /* REM: no way to change passband width ? */ int icm710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const char *pmode; switch (mode) { case RIG_MODE_CW: pmode = MD_CW; break; case RIG_MODE_USB: pmode = MD_USB; break; case RIG_MODE_LSB: pmode = MD_LSB; break; case RIG_MODE_AM: pmode = MD_AM; break; case RIG_MODE_RTTY: pmode = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_MODE, pmode, NULL); } int icm710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { *mode = ((struct icm710_priv_data *)STATE(rig)->priv)->mode; *width = 2200; return RIG_OK; } /* * Rem: The "TX" command will fail on invalid frequencies. */ int icm710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; retval = icmarine_transaction(rig, CMD_PTT, ptt == RIG_PTT_ON ? "TX" : "RX", NULL); if (retval != RIG_OK) { return retval; } priv->ptt = ptt; return RIG_OK; } int icm710_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { *ptt = ((struct icm710_priv_data *)STATE(rig)->priv)->ptt; return RIG_OK; } int icm710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { if (RIG_OP_TUNE != op && RIG_OP_NONE != op) { return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_TUNER, RIG_OP_TUNE == op ? "ON" : "OFF", NULL); } int icm710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, status ? "ON" : "OFF", NULL); break; default: return -RIG_EINVAL; } return retval; } int icm710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char funcbuf[BUFSZ]; int retval; switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, NULL, funcbuf); break; default: return -RIG_EINVAL; } *status = !strcmp(funcbuf, "ON"); return retval; } int icm710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char lvlbuf[BUFSZ]; int retval; unsigned value; struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_AF: value = (unsigned)(val.f * 255); SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", value); retval = icmarine_transaction(rig, CMD_AFGAIN, lvlbuf, NULL); if (retval == RIG_OK) { priv->afgain = value; } break; case RIG_LEVEL_RF: value = (unsigned)(val.f * 9); SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", value); retval = icmarine_transaction(rig, CMD_RFGAIN, lvlbuf, NULL); if (retval == RIG_OK) { priv->rfgain = value; } break; case RIG_LEVEL_RFPOWER: value = (unsigned)(val.f * 2); SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", value); retval = icmarine_transaction(rig, CMD_RFPWR, lvlbuf, NULL); if (retval == RIG_OK) { priv->rfpwr = value; } break; case RIG_LEVEL_AGC: retval = icmarine_transaction(rig, CMD_AGC, RIG_AGC_OFF == val.i ? "OFF" : "ON", NULL); if (retval == RIG_OK) { priv->afgain = val.i; } break; default: return -RIG_EINVAL; } return retval; } int icm710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct icm710_priv_data *priv; priv = (struct icm710_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_AF: val->f = priv->afgain / 255.; break; case RIG_LEVEL_RF: val->f = priv->rfgain / 9.; break; case RIG_LEVEL_RFPOWER: val->f = priv->rfpwr / 3.; break; case RIG_LEVEL_AGC: val->i = priv->agc; break; default: return -RIG_EINVAL; } return -RIG_OK; } /* * initrigs_icm710 is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(icm710) { rig_debug(RIG_DEBUG_VERBOSE, "%s: icm710_init called\n", __func__); rig_register(&icm700pro_caps); rig_register(&icm710_caps); rig_register(&icm802_caps); return RIG_OK; } hamlib-4.6.2/rigs/icmarine/Android.mk0000644000175000017500000000045214752216205014351 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := icm700pro.c icm710.c icm802.c icm803.c \ icmarine.c LOCAL_MODULE := icmarine LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/icmarine/icm803.c0000644000175000017500000001410014752216205013602 00000000000000/* * Hamlib ICOM Marine backend - model IC-M803 (derived from IC-M802) * Modifications by Blaine Kubesh (k5kub) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icmarine.h" #include "idx_builtin.h" #define ICM803_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM803_RX_MODES (ICM803_MODES|RIG_MODE_AM) #define ICM803_FUNC_ALL (RIG_FUNC_NB) #define ICM803_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM803_VFO_ALL (RIG_VFO_A) #define ICM803_VFO_OPS (RIG_OP_TUNE) #define ICM803_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM803_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icmarine_priv_caps icm803_priv_caps = { .default_remote_id = 20, /* default address */ }; struct rig_caps icm803_caps = { RIG_MODEL(RIG_MODEL_IC_M803), .model_name = "IC-M803", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM803_FUNC_ALL, .has_set_func = ICM803_FUNC_ALL, .has_get_level = ICM803_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM803_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM803_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM803_VFO_OPS, .scan_ops = ICM803_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM803_RX_MODES, -1, -1, ICM803_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM803_RX_MODES, -1, -1, ICM803_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM803_MODES, W(20), W(150), ICM803_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM803_RX_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icmarine_cfg_params, .set_conf = icmarine_set_conf, .get_conf = icmarine_get_conf, .priv = (void *)& icm803_priv_caps, .rig_init = icmarine_init, .rig_cleanup = icmarine_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icmarine_set_freq, .get_freq = icmarine_get_freq, .set_split_freq = icmarine_set_tx_freq, .get_split_freq = icmarine_get_tx_freq, .set_split_vfo = icmarine_set_split_vfo, .get_split_vfo = icmarine_get_split_vfo, .set_mode = icmarine_set_mode, .get_mode = icmarine_get_mode, .set_ptt = icmarine_set_ptt, .get_ptt = icmarine_get_ptt, .get_dcd = icmarine_get_dcd, .vfo_op = icmarine_vfo_op, .set_level = icmarine_set_level, .get_level = icmarine_get_level, .set_func = icmarine_set_func, .get_func = icmarine_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icmarine/icm802.c0000644000175000017500000001407414752216205013613 00000000000000/* * Hamlib ICOM Marine backend - description of IC-M802 caps * Copyright (c) 2014-2015 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icmarine.h" #include "idx_builtin.h" #define ICM802_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM802_RX_MODES (ICM802_MODES|RIG_MODE_AM) #define ICM802_FUNC_ALL (RIG_FUNC_NB) #define ICM802_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM802_VFO_ALL (RIG_VFO_A) #define ICM802_VFO_OPS (RIG_OP_TUNE) #define ICM802_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM802_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icmarine_priv_caps icm802_priv_caps = { .default_remote_id = 0x08, /* default address */ }; struct rig_caps icm802_caps = { RIG_MODEL(RIG_MODEL_IC_M802), .model_name = "IC-M802", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM802_FUNC_ALL, .has_set_func = ICM802_FUNC_ALL, .has_get_level = ICM802_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM802_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM802_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM802_VFO_OPS, .scan_ops = ICM802_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM802_RX_MODES, -1, -1, ICM802_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM802_RX_MODES, -1, -1, ICM802_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM802_MODES, W(20), W(150), ICM802_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM802_RX_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icmarine_cfg_params, .set_conf = icmarine_set_conf, .get_conf = icmarine_get_conf, .priv = (void *)& icm802_priv_caps, .rig_init = icmarine_init, .rig_cleanup = icmarine_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icmarine_set_freq, .get_freq = icmarine_get_freq, .set_split_freq = icmarine_set_tx_freq, .get_split_freq = icmarine_get_tx_freq, .set_split_vfo = icmarine_set_split_vfo, .get_split_vfo = icmarine_get_split_vfo, .set_mode = icmarine_set_mode, .get_mode = icmarine_get_mode, .set_ptt = icmarine_set_ptt, .get_ptt = icmarine_get_ptt, .get_dcd = icmarine_get_dcd, .vfo_op = icmarine_vfo_op, .set_level = icmarine_set_level, .get_level = icmarine_get_level, .set_func = icmarine_set_func, .get_func = icmarine_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icmarine/icm700pro.c0000644000175000017500000001436014752216205014327 00000000000000/* * Hamlib ICOM Marine backend - description of IC-M700PRO caps * Copyright (c) 2014-2015 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "icmarine.h" #include "idx_builtin.h" #define ICM700PRO_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_RTTY) #define ICM700PRO_RX_MODES (ICM700PRO_MODES|RIG_MODE_AM) #define ICM700PRO_FUNC_ALL (RIG_FUNC_NB) #define ICM700PRO_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_RAWSTR) #define ICM700PRO_VFO_ALL (RIG_VFO_A) #define ICM700PRO_VFO_OPS (RIG_OP_TUNE) #define ICM700PRO_SCAN_OPS (RIG_SCAN_NONE) /* * TODO calibrate the real values */ #define ICM700PRO_STR_CAL { 2, {{ 0, -60}, { 8, 60}} } static const struct icmarine_priv_caps icm700pro_priv_caps = { .default_remote_id = 2, }; struct rig_caps icm700pro_caps = { RIG_MODEL(RIG_MODEL_IC_M700PRO), .model_name = "IC-M700PRO", .mfg_name = "Icom", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = ICM700PRO_FUNC_ALL, .has_set_func = ICM700PRO_FUNC_ALL, .has_get_level = ICM700PRO_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ICM700PRO_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 8 } }, }, .parm_gran = {}, .str_cal = ICM700PRO_STR_CAL, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(150), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = ICM700PRO_VFO_OPS, .scan_ops = ICM700PRO_SCAN_OPS, .transceive = RIG_TRN_OFF, .bank_qty = 3, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 100, ICM700PRO_RX_MODES, -1, -1, ICM700PRO_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1600), MHz(3) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM700PRO_MODES, W(60), W(60), ICM700PRO_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 100, ICM700PRO_RX_MODES, -1, -1, ICM700PRO_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1600), MHz(3) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(4), MHz(5) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(6), MHz(7) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(8), MHz(9) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(12), MHz(14) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(16), MHz(18) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(18), MHz(20) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(22), MHz(23) - 100, ICM700PRO_MODES, W(150), W(150), ICM700PRO_VFO_ALL, RIG_ANT_1}, {MHz(25), MHz(27.500), ICM700PRO_MODES, W(60), W(60), ICM700PRO_VFO_ALL, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {ICM700PRO_RX_MODES, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.3)}, {RIG_MODE_AM, kHz(14)}, RIG_FLT_END, }, .cfgparams = icmarine_cfg_params, .set_conf = icmarine_set_conf, .get_conf = icmarine_get_conf, .priv = (void *)& icm700pro_priv_caps, .rig_init = icmarine_init, .rig_cleanup = icmarine_cleanup, .rig_open = NULL, .rig_close = NULL, .set_freq = icmarine_set_freq, .get_freq = icmarine_get_freq, .set_split_freq = icmarine_set_tx_freq, .get_split_freq = icmarine_get_tx_freq, .set_split_vfo = icmarine_set_split_vfo, .get_split_vfo = icmarine_get_split_vfo, .set_mode = icmarine_set_mode, .get_mode = icmarine_get_mode, .set_ptt = icmarine_set_ptt, .get_ptt = icmarine_get_ptt, .get_dcd = icmarine_get_dcd, .vfo_op = icmarine_vfo_op, .set_level = icmarine_set_level, .get_level = icmarine_get_level, .set_func = icmarine_set_func, .get_func = icmarine_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/icmarine/icmarine.c0000644000175000017500000004347314752216205014405 00000000000000/* * Hamlib ICOM Marine backend - main file * Copyright (c) 2014-2015 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include #include #include "icmarine.h" /* * NMEA 0183 protocol * * Total message is maximum 82 characters, including '$' and CR+LF. * * Serial setup is 8N1, msb always 0, -> ASCII protocol * * Proprietary Extension Message format: * Byte pos Length Value Description * 0 1 0x24 '$' Start character * 1 1 0x50 'P' Type: Proprietary * 2 3 'ICO' Manufacturer ID * 5 Message Data */ /* CR LF */ #define EOM "\x0d\x0a" #define LF "\x0a" #define BUFSZ 96 #define OFFSET_CMD 13 /* * Protocol stuff */ #define CONTROLLER_ID 90 #if 0 #define MD_LSB "J3E" #define MD_USB "J3E" #define MD_CW "A1A" #define MD_AM "A3E" #else #define MD_LSB "LSB" #define MD_USB "USB" #define MD_CW "CW" #define MD_AM "AM" #endif #define MD_FSK "J2B" #define CMD_TXFREQ "TXF" /* Transmit frequency */ #define CMD_RXFREQ "RXF" /* Receive frequency */ #define CMD_MODE "MODE" /* Mode */ #define CMD_REMOTE "REMOTE" /* Remote */ #define CMD_PTT "TRX" /* PTT */ #define CMD_AFGAIN "AFG" #define CMD_RFGAIN "RFG" #define CMD_RFPWR "TXP" #define CMD_NB "NB" #define CMD_AGC "AGC" #define CMD_TUNER "TUNER" /* Data Output Commands */ #define CMD_SMETER "SIGM" /* S-meter read */ #define CMD_SQLS "SQLS" /* Squelch status */ /* Tokens */ #define TOK_REMOTEID TOKEN_BACKEND(1) int icmarine_transaction(RIG *rig, const char *cmd, const char *param, char *response); const struct confparams icmarine_cfg_params[] = { { TOK_REMOTEID, "remoteid", "Remote ID", "Transceiver's remote ID", "1", RIG_CONF_NUMERIC, { .n = { 1, 99, 1 } } }, { RIG_CONF_END, NULL, } }; /* * Basically, set up *priv */ int icmarine_init(RIG *rig) { struct icmarine_priv_data *priv; const struct icmarine_priv_caps *priv_caps; struct rig_caps *caps; if (!rig || !rig->caps) { return -RIG_EINVAL; } caps = rig->caps; if (!caps->priv) { return -RIG_ECONF; } priv_caps = (const struct icmarine_priv_caps *) caps->priv; STATE(rig)->priv = (struct icmarine_priv_data *)calloc(1, sizeof( struct icmarine_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->remote_id = priv_caps->default_remote_id; priv->split = RIG_SPLIT_OFF; return RIG_OK; } int icmarine_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } #ifdef XXREMOVEDXX // This function not referenced -- doesn't do anything really int icmarine_open(RIG *rig) { char respbuf[BUFSZ + 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); int retval = icmarine_transaction(rig, "REMOTE", "ON", respbuf); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not responding? %s\n", __func__, rigerror(retval)); } return RIG_OK; } #endif int icmarine_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct icmarine_priv_data *priv; priv = (struct icmarine_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: priv->remote_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } int icmarine_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct icmarine_priv_data *priv; priv = (struct icmarine_priv_data *)STATE(rig)->priv; switch (token) { case TOK_REMOTEID: SNPRINTF(val, val_len, "%u", priv->remote_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int icmarine_get_conf(RIG *rig, hamlib_token_t token, char *val) { return icmarine_get_conf2(rig, token, val, 128); } /* * icmarine_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * * cmd: mandatory * param: only 1 optional NMEA parameter, NULL for none (=query) * response: optional (holding BUFSZ bytes) */ int icmarine_transaction(RIG *rig, const char *cmd, const char *param, char *response) { struct icmarine_priv_data *priv; int i, retval; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); char cmdbuf[BUFSZ + 1]; char respbuf[BUFSZ + 1]; char *p; char *strip; int cmd_len; unsigned csum = 0; rig_debug(RIG_DEBUG_TRACE, "%s: cmd='%s', param=%s\n", __func__, cmd, param == NULL ? "NULL" : param); rs = STATE(rig); priv = (struct icmarine_priv_data *)rs->priv; rig_flush(rp); /* command formatting */ SNPRINTF(cmdbuf, BUFSZ, "$PICOA,%02d,%02u,%s", CONTROLLER_ID, priv->remote_id, cmd); cmd_len = strlen(cmdbuf); if (param) { cmd_len += snprintf(cmdbuf + cmd_len, BUFSZ - cmd_len, ",%s", param); } /* NMEA checksum, between '$' and '*' */ for (i = 1; i < cmd_len; i++) { csum = csum ^ (unsigned)cmdbuf[i]; } cmd_len += snprintf(cmdbuf + cmd_len, BUFSZ - cmd_len, "*%02X" EOM, csum); /* I/O */ retval = write_block(rp, (unsigned char *) cmdbuf, cmd_len); if (retval != RIG_OK) { return retval; } /* * Transceiver sends an echo of cmd followed by a CR/LF */ retval = read_string(rp, (unsigned char *) respbuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } /* Minimal length */ if (retval < OFFSET_CMD + 5) { return -RIG_EPROTO; } /* check response */ if (memcmp(respbuf, "$PICOA,", strlen("$PICOA,")) != 0) { return -RIG_EPROTO; } /* TODO: check ID's */ /* if not a query, check for correct as acknowledge */ if (param) { if (memcmp(cmdbuf + OFFSET_CMD, respbuf + OFFSET_CMD, cmd_len - OFFSET_CMD - 5) == 0) { return RIG_OK; } else { return -RIG_ERJCTED; } } /* strip from *checksum and after */ strip = strrchr(respbuf, '*'); if (strip) { *strip = 0; } else { rig_debug(RIG_DEBUG_ERR, "%s: checksum not in response? response='%s'\n", __func__, respbuf); return -RIG_EPROTO; } p = strrchr(respbuf, ','); if (p) { strncpy(response, p + 1, BUFSZ); } else { return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: returning response='%s'\n", __func__, response == NULL ? "NULL" : response); return RIG_OK; } int icmarine_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; struct icmarine_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); priv = (struct icmarine_priv_data *)STATE(rig)->priv; SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); /* no error reporting upon TXFREQ failure */ if (RIG_SPLIT_OFF == priv->split) { icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); } return icmarine_transaction(rig, CMD_RXFREQ, freqbuf, NULL); } /* * icmarine_get_freq * Assumes rig!=NULL, freq!=NULL */ int icmarine_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char freqbuf[BUFSZ] = ""; double d; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_RXFREQ, NULL, freqbuf); if (retval != RIG_OK) { return retval; } if (freqbuf[0] == '\0') { *freq = 0; } else { if (sscanf(freqbuf, "%lf", &d) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: sscanf('%s') failed\n", __func__, freqbuf); return -RIG_EPROTO; } *freq = (freq_t)(d * MHz(1)); } return RIG_OK; } int icmarine_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); SNPRINTF(freqbuf, sizeof(freqbuf), "%.6f", freq / MHz(1)); return icmarine_transaction(rig, CMD_TXFREQ, freqbuf, NULL); } int icmarine_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char freqbuf[BUFSZ] = ""; double d; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_TXFREQ, NULL, freqbuf); if (retval != RIG_OK) { return retval; } if (freqbuf[0] == '\0') { *freq = 0; } else { if (sscanf(freqbuf, "%lf", &d) != 1) { return -RIG_EPROTO; } *freq = (freq_t)(d * MHz(1)); } return RIG_OK; } int icmarine_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo) { struct icmarine_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); priv = (struct icmarine_priv_data *)STATE(rig)->priv; /* when disabling split mode */ if (RIG_SPLIT_ON == priv->split && RIG_SPLIT_OFF == split) { freq_t freq; if (RIG_OK == icmarine_get_freq(rig, rx_vfo, &freq)) { icmarine_set_tx_freq(rig, rx_vfo, freq); } } priv->split = split; return RIG_OK; } int icmarine_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo) { struct icmarine_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); priv = (struct icmarine_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = rx_vfo; return RIG_OK; } /* REM: no way to change passband width ? */ int icmarine_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const char *pmode; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (mode) { case RIG_MODE_CW: pmode = MD_CW; break; case RIG_MODE_USB: pmode = MD_USB; break; case RIG_MODE_LSB: pmode = MD_LSB; break; case RIG_MODE_AM: pmode = MD_AM; break; case RIG_MODE_RTTY: pmode = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_MODE, pmode, NULL); } int icmarine_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; char modebuf[BUFSZ]; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_MODE, NULL, modebuf); if (retval != RIG_OK) { return retval; } if (!memcmp(modebuf, MD_LSB, strlen(MD_LSB))) { *mode = RIG_MODE_LSB; } else if (!memcmp(modebuf, MD_USB, strlen(MD_USB))) { *mode = RIG_MODE_USB; } else if (!memcmp(modebuf, MD_CW, strlen(MD_CW))) { *mode = RIG_MODE_CW; } else if (!memcmp(modebuf, MD_AM, strlen(MD_AM))) { *mode = RIG_MODE_AM; } else if (!memcmp(modebuf, MD_FSK, strlen(MD_FSK))) { *mode = RIG_MODE_RTTY; } else { retval = -RIG_EPROTO; } if (retval == RIG_OK) { *width = rig_passband_normal(rig, *mode); } return retval; } /* * Rem: The "TX" command will fail on invalid frequencies. */ int icmarine_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_PTT, ptt == RIG_PTT_ON ? "TX" : "RX", NULL); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: transaction failed\n", __func__); return retval; } return RIG_OK; } int icmarine_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_PTT, NULL, pttbuf); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: transaction failed\n", __func__); return retval; } if (strncmp(pttbuf, "TX", 2) == 0) { *ptt = RIG_PTT_ON; } else if (strncmp(pttbuf, "RX", 2) == 0) { *ptt = RIG_PTT_OFF; } else { rig_debug(RIG_DEBUG_ERR, "%s: invalid pttbuf='%s'\n", __func__, pttbuf); retval = -RIG_EPROTO; } return retval; } int icmarine_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); retval = icmarine_transaction(rig, CMD_SQLS, NULL, dcdbuf); if (retval != RIG_OK) { return retval; } if (!strcmp(dcdbuf, "OPEN")) { *dcd = RIG_DCD_ON; } else if (!strcmp(dcdbuf, "CLOSE")) { *dcd = RIG_DCD_OFF; } else { retval = -RIG_EPROTO; } return retval; } int icmarine_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); if (RIG_OP_TUNE != op && RIG_OP_NONE != op) { return -RIG_EINVAL; } return icmarine_transaction(rig, CMD_TUNER, RIG_OP_TUNE == op ? "ON" : "OFF", NULL); } int icmarine_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, status ? "ON" : "OFF", NULL); break; default: return -RIG_EINVAL; } return retval; } int icmarine_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char funcbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (func) { case RIG_FUNC_NB: retval = icmarine_transaction(rig, CMD_NB, NULL, funcbuf); break; default: return -RIG_EINVAL; } *status = !strcmp(funcbuf, "ON"); return retval; } int icmarine_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char lvlbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (level) { case RIG_LEVEL_AF: SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", (unsigned)(val.f * 255)); retval = icmarine_transaction(rig, CMD_AFGAIN, lvlbuf, NULL); break; case RIG_LEVEL_RF: SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", (unsigned)(val.f * 9)); retval = icmarine_transaction(rig, CMD_RFGAIN, lvlbuf, NULL); break; case RIG_LEVEL_RFPOWER: SNPRINTF(lvlbuf, sizeof(lvlbuf), "%u", 1 + (unsigned)(val.f * 2)); retval = icmarine_transaction(rig, CMD_RFPWR, lvlbuf, NULL); break; case RIG_LEVEL_AGC: retval = icmarine_transaction(rig, CMD_AGC, RIG_AGC_OFF == val.i ? "OFF" : "ON", NULL); break; default: return -RIG_EINVAL; } return retval; } int icmarine_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[BUFSZ]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s:\n", __func__); switch (level) { case RIG_LEVEL_RAWSTR: retval = icmarine_transaction(rig, CMD_SMETER, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] < '0' || lvlbuf[0] > '9') { return -RIG_EPROTO; } val->i = lvlbuf[0] - '0'; break; case RIG_LEVEL_AF: retval = icmarine_transaction(rig, CMD_AFGAIN, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } val->f = atof(lvlbuf) / 255.; break; case RIG_LEVEL_RF: retval = icmarine_transaction(rig, CMD_RFGAIN, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] < '0' || lvlbuf[0] > '9') { return -RIG_EPROTO; } val->f = (float)(lvlbuf[0] - '0') / 9.; break; case RIG_LEVEL_RFPOWER: retval = icmarine_transaction(rig, CMD_RFPWR, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } if (lvlbuf[0] < '1' || lvlbuf[0] > '3') { return -RIG_EPROTO; } val->f = (float)(lvlbuf[0] - '1') / 3.; break; case RIG_LEVEL_AGC: retval = icmarine_transaction(rig, CMD_AGC, NULL, lvlbuf); if (retval != RIG_OK) { return retval; } val->i = !strcmp(lvlbuf, "ON") ? RIG_AGC_SLOW : RIG_AGC_OFF; break; default: return -RIG_EINVAL; } return retval; } /* * initrigs_icmarine is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(icmarine) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&icm700pro_caps); rig_register(&icm710_caps); rig_register(&icm802_caps); rig_register(&icm803_caps); return RIG_OK; } hamlib-4.6.2/rigs/icmarine/icm710.h0000644000175000017500000000636714752216205013624 00000000000000/* * Hamlib ICOM M710 backend - main header * Copyright (c) 2014-2015 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICM710_H #define _ICM710_H 1 #include #include "hamlib/rig.h" struct icm710_priv_caps { unsigned char default_remote_id; /* the remote default equipment's ID */ }; /* The M710 does not support queries */ /* So we keep a copy of settings in priv to support get functions */ /* The priv settings only reflect what has been previously set */ /* So get's will return 0 until the value has been set */ struct icm710_priv_data { unsigned char remote_id; /* the remote equipment's ID */ split_t split; /* current split mode */ freq_t rxfreq, txfreq; mode_t mode; ptt_t ptt; unsigned afgain; unsigned rfgain; unsigned rfpwr; unsigned agc; }; extern const struct confparams icm710_cfg_params[]; int icm710_init(RIG *rig); int icm710_cleanup(RIG *rig); int icm710_open(RIG *rig); int icm710_close(RIG *rig); int icm710_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int icm710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icm710_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq); int icm710_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icm710_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo); int icm710_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo); int icm710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icm710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int icm710_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int icm710_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int icm710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int icm710_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int icm710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int icm710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int icm710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int icm710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int icm710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int icm710_set_parm(RIG *rig, setting_t parm, value_t val); int icm710_get_parm(RIG *rig, setting_t parm, value_t *val); int icm710_set_conf(RIG *rig, hamlib_token_t token, const char *val); int icm710_get_conf(RIG *rig, hamlib_token_t token, char *val); int icm710_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len); extern struct rig_caps icm700pro_caps; extern struct rig_caps icm710_caps; extern struct rig_caps icm802_caps; #endif /* _ICM710_H */ hamlib-4.6.2/rigs/icmarine/icmarine.h0000644000175000017500000000614214752216205014402 00000000000000/* * Hamlib ICOM Marine backend - main header * Copyright (c) 2014-2015 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ICMARINE_H #define _ICMARINE_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20181007" struct icmarine_priv_caps { unsigned char default_remote_id; /* the remote default equipment's ID */ }; struct icmarine_priv_data { unsigned char remote_id; /* the remote equipment's ID */ split_t split; /* current split mode */ }; extern const struct confparams icmarine_cfg_params[]; int icmarine_transaction(RIG *rig, const char *cmd, const char *param, char *response); int icmarine_init(RIG *rig); int icmarine_cleanup(RIG *rig); int icmarine_open(RIG *rig); int icmarine_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int icmarine_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icmarine_set_tx_freq(RIG *rig, vfo_t vfo, freq_t freq); int icmarine_get_tx_freq(RIG *rig, vfo_t vfo, freq_t *freq); int icmarine_set_split_vfo(RIG *rig, vfo_t rx_vfo, split_t split, vfo_t tx_vfo); int icmarine_get_split_vfo(RIG *rig, vfo_t rx_vfo, split_t *split, vfo_t *tx_vfo); int icmarine_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int icmarine_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int icmarine_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int icmarine_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int icmarine_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int icmarine_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int icmarine_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int icmarine_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int icmarine_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int icmarine_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int icmarine_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int icmarine_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int icmarine_set_parm(RIG *rig, setting_t parm, value_t val); int icmarine_get_parm(RIG *rig, setting_t parm, value_t *val); int icmarine_set_conf(RIG *rig, hamlib_token_t token, const char *val); int icmarine_get_conf(RIG *rig, hamlib_token_t token, char *val); int icmarine_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len); extern struct rig_caps icm700pro_caps; extern struct rig_caps icm710_caps; extern struct rig_caps icm802_caps; extern struct rig_caps icm803_caps; #endif /* _ICMARINE_H */ hamlib-4.6.2/rigs/anytone/0000755000175000017500000000000014752216245012411 500000000000000hamlib-4.6.2/rigs/anytone/Makefile.am0000644000175000017500000000023214752216205014356 00000000000000ANYTONESRC = anytone.c d578.c anytone.h noinst_LTLIBRARIES = libhamlib-anytone.la libhamlib_anytone_la_SOURCES = $(ANYTONESRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/anytone/Makefile.in0000644000175000017500000005240714752216215014403 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/anytone ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_anytone_la_LIBADD = am__objects_1 = anytone.lo d578.lo am_libhamlib_anytone_la_OBJECTS = $(am__objects_1) libhamlib_anytone_la_OBJECTS = $(am_libhamlib_anytone_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/anytone.Plo ./$(DEPDIR)/d578.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_anytone_la_SOURCES) DIST_SOURCES = $(libhamlib_anytone_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ANYTONESRC = anytone.c d578.c anytone.h noinst_LTLIBRARIES = libhamlib-anytone.la libhamlib_anytone_la_SOURCES = $(ANYTONESRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/anytone/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/anytone/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-anytone.la: $(libhamlib_anytone_la_OBJECTS) $(libhamlib_anytone_la_DEPENDENCIES) $(EXTRA_libhamlib_anytone_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_anytone_la_OBJECTS) $(libhamlib_anytone_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anytone.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d578.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/anytone.Plo -rm -f ./$(DEPDIR)/d578.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/anytone.Plo -rm -f ./$(DEPDIR)/d578.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/anytone/Android.mk0000644000175000017500000000042414752216205014236 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := anytone.c d578.c LOCAL_MODULE := anytone LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := $(LOCAL_SHARED_LIBRARIES) -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/anytone/d578.c0000644000175000017500000000652314752216205013166 00000000000000// --------------------------------------------------------------------------- // Anytone D578UVIII // --------------------------------------------------------------------------- // // d578.c // // Created by Michael Black W9MDB // Copyright © 2023, Michael Black W9MDB. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "anytone.h" #define D578_VFO (RIG_VFO_A|RIG_VFO_B) #define D578_MODES (RIG_MODE_USB|RIG_MODE_AM) struct rig_caps anytone_d578_caps = { RIG_MODEL(RIG_MODEL_ATD578UVIII), .model_name = "D578A", .mfg_name = "AnyTone", .version = BACKEND_VER ".0", .copyright = "Michael Black W9MDB: GNU LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .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_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = 0, .rx_range_list1 = { { MHz(108), MHz(174), D578_MODES, -1, -1, D578_VFO }, { MHz(144), MHz(148), D578_MODES, -1, -1, D578_VFO }, { MHz(222), MHz(225), D578_MODES, -1, -1, D578_VFO }, { MHz(420), MHz(450), D578_MODES, -1, -1, D578_VFO }, RIG_FRNG_END, }, .tx_range_list1 = { { MHz(144), MHz(148), D578_MODES, W(1), W(55), D578_VFO }, { MHz(222), MHz(225), D578_MODES, W(1), W(40), D578_VFO }, { MHz(420), MHz(450), D578_MODES, W(1), W(25), D578_VFO }, RIG_FRNG_END, }, .rig_init = anytone_init, .rig_cleanup = anytone_cleanup, .rig_open = anytone_open, .rig_close = anytone_close, .get_vfo = anytone_get_vfo, .set_vfo = anytone_set_vfo, .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 }; // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.2/rigs/anytone/anytone.c0000644000175000017500000003175214752216205014156 00000000000000// --------------------------------------------------------------------------- // AnyTone D578 Hamlib Backend // --------------------------------------------------------------------------- // // d578.c // // Created by Michael Black W9MDB // Copyright © 2023 Michael Black W9MDB. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // --------------------------------------------------------------------------- // SYSTEM INCLUDES // --------------------------------------------------------------------------- #include #include #include #include #include // --------------------------------------------------------------------------- // HAMLIB INCLUDES // --------------------------------------------------------------------------- #include #include "serial.h" #include "misc.h" #include "register.h" #include "riglist.h" // --------------------------------------------------------------------------- // ANYTONE INCLUDES // --------------------------------------------------------------------------- #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) { int retval = RIG_OK; rig_register(&anytone_d578_caps); return retval; } // --------------------------------------------------------------------------- // proberig_anytone // --------------------------------------------------------------------------- DECLARE_PROBERIG_BACKEND(anytone) { int retval = RIG_OK; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 1; port->retry = 1; retval = serial_open(port); if (retval != RIG_OK) { retval = -RIG_EIO; } return retval; } // AnyTone needs a keep-alive to emulate the MIC // Apparently to keep the rig from getting stuck in PTT if mic disconnects void *anytone_thread(void *vrig) { RIG *rig = (RIG *)vrig; hamlib_port_t *rp = RIGPORT(rig); anytone_priv_data_t *p = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: anytone_thread started\n", __func__); p->runflag = 1; while (p->runflag) { 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; rig_get_debug(&debug_level_save); if (rig_need_debug(RIG_DEBUG_CACHE) == 0) { rig_set_debug(RIG_DEBUG_WARN); // only show WARN debug otherwise too verbose } write_block(rp, (unsigned char *)c, strlen(c)); char buf[32]; read_block(rp, (unsigned char *)buf, 22); if (rig_need_debug(RIG_DEBUG_CACHE) == 0) { rig_set_debug(debug_level_save); } MUTEX_UNLOCK(p->priv.mutex); hl_usleep(1000 * 1000); // 1-second loop } return NULL; } // --------------------------------------------------------------------------- // anytone_send // --------------------------------------------------------------------------- int anytone_send(RIG *rig, unsigned char *cmd, int cmd_len) { int retval = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); RETURNFUNC(retval); } // --------------------------------------------------------------------------- // anytone_receive // --------------------------------------------------------------------------- int anytone_receive(RIG *rig, unsigned char *buf, int buf_len, int expected) { int retval = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; // retval = read_string(rp, (unsigned char *) buf, buf_len, // NULL, 0, 0, expected); retval = read_block(rp, buf, expected); if (retval > 0) { retval = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s: read %d byte=0x%02x\n", __func__, retval, buf[0]); } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // anytone_transaction // --------------------------------------------------------------------------- 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 = STATE(rig)->priv; ENTERFUNC; retval = anytone_send(rig, cmd, cmd_len); if (retval == RIG_OK && expected_len != 0) { int len = anytone_receive(rig, reply, reply_len, expected_len); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): rx len=%d\n", __func__, __LINE__, len); } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_init // --------------------------------------------------------------------------- int anytone_init(RIG *rig) { int retval = RIG_OK; ENTERFUNC; if (rig != NULL) { anytone_priv_data_ptr p = NULL; // Get new Priv Data p = calloc(1, sizeof(anytone_priv_data_t)); if (p == NULL) { retval = -RIG_ENOMEM; RETURNFUNC(retval); } else { STATE(rig)->priv = p; p->vfo_curr = RIG_VFO_NONE; #ifdef HAVE_PTHREAD pthread_mutex_init(&p->mutex, NULL); #endif } } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_cleanup // --------------------------------------------------------------------------- int anytone_cleanup(RIG *rig) { int retval = RIG_OK; if (rig == NULL) { return -RIG_EARG; } ENTERFUNC; free(STATE(rig)->priv); STATE(rig)->priv = NULL; RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_open // --------------------------------------------------------------------------- int anytone_open(RIG *rig) { int retval = RIG_OK; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; unsigned char cmd[] = { 0x2B, 0x41, 0x44, 0x41, 0x54, 0x41, 0x3A, 0x30, 0x30, 0x2C, 0x30, 0x30, 0x31, 0x0d, 0x0a, 'a', 0x0d, 0x0a }; write_block(rp, 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(rp, (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 int err = pthread_create(&id, NULL, anytone_thread, (void *)rig); if (err) { rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, strerror(errno)); RETURNFUNC(-RIG_EINTERNAL); } RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_close // --------------------------------------------------------------------------- int anytone_close(RIG *rig) { int retval = RIG_OK; ENTERFUNC; char *cmd = "+ADATA:00,000\r\n"; anytone_transaction(rig, (unsigned char *)cmd, strlen(cmd), NULL, 0, 0); RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_get_vfo // --------------------------------------------------------------------------- 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[] = { "+ADATA06:00,001",0x41, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x06 }; ENTERFUNC; const anytone_priv_data_ptr p = (anytone_priv_data_ptr) STATE(rig)->priv; unsigned char reply[512]; 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 }; 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]); } p->vfo_curr = *vfo; RETURNFUNC(retval); } // --------------------------------------------------------------------------- // Function anytone_set_vfo // --------------------------------------------------------------------------- int anytone_set_vfo(RIG *rig, vfo_t vfo) { ENTERFUNC; RETURNFUNC(RIG_OK); } // --------------------------------------------------------------------------- // Function anytone_get_ptt // --------------------------------------------------------------------------- int anytone_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval = RIG_OK; ENTERFUNC; anytone_priv_data_t *p = STATE(rig)->priv; *ptt = p->ptt; RETURNFUNC(retval); } // --------------------------------------------------------------------------- // anytone_set_ptt // --------------------------------------------------------------------------- int anytone_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval = RIG_OK; ENTERFUNC; //char buf[8] = { 0x41, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x06 }; 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 = " (unsigned char*)+ADATA:00,023\r\nV\r\n"; } MUTEX_LOCK(p->mutex); anytone_transaction(rig, pttcmd, sizeof(ptton), NULL, 0, 0); anytone_priv_data_t *p = STATE(rig)->priv; p->ptt = ptt; MUTEX_UNLOCK(p->mutex); RETURNFUNC(retval); } int anytone_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char cmd[32]; int retval; hamlib_port_t *rp = RIGPORT(rig); 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; if (vfo == RIG_VFO_B) { cmd[16] = 0x2d; } int retry = 2; MUTEX_LOCK(p->priv.mutex); rig_flush(rp); do { write_block(rp, (unsigned char *)cmd, 25); unsigned char buf[512]; retval = read_block(rp, 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]; hamlib_port_t *rp = RIGPORT(rig); 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(rp); write_block(rp, (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(rp, (unsigned char *)cmd, bytes); MUTEX_UNLOCK(p->priv.mutex); return -RIG_ENIMPL; } // --------------------------------------------------------------------------- // END OF FILE // --------------------------------------------------------------------------- hamlib-4.6.2/rigs/anytone/anytone.h0000644000175000017500000000230014752216205014146 00000000000000#ifndef _ANYTONE_H #define _ANYTONE_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20231001" #define ANYTONE_RESPSZ 64 extern struct rig_caps anytone_d578_caps; #ifdef PTHREAD #include #define MUTEX(var) static pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER #define MUTEX_LOCK(var) pthread_mutex_lock(var) #define MUTEX_UNLOCK(var) pthread_mutex_unlock(var) #else #define MUTEX(var) #define MUTEX_LOCK(var) #define MUTEX_UNLOCK(var) #endif typedef struct _anytone_priv_data { ptt_t ptt; vfo_t vfo_curr; int runflag; // thread control char buf[64]; pthread_mutex_t mutex; } anytone_priv_data_t, * anytone_priv_data_ptr; extern int anytone_init(RIG *rig); extern int anytone_cleanup(RIG *rig); extern int anytone_open(RIG *rig); extern int anytone_close(RIG *rig); extern int anytone_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); 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 */ hamlib-4.6.2/rigs/winradio/0000755000175000017500000000000014752216244012547 500000000000000hamlib-4.6.2/rigs/winradio/NOTES0000644000175000017500000000253314752216205013302 00000000000000Mail from , 02/06/01 Stephane mentioned the hamlib project to the linradio.sourceforge.net developers a few weeks ago. I believe my reply was routed to /dev/null@shell1.sourceforge.net. Anyway I have put some notes and early untested code at: http://linradio.sourceforge.net/hamlib.html Here are some winradio-specific issues: - Winradios are simple (henceforth cheap) receivers. The software driver does a lot of work that you would normally expect to see in an embedded controller. The driver is about 100KB of C. - Receivers come with ISA, PCMCIA and RS232 interfaces. - The protocol varies a lot across the model range. - Most models barely have an internal state. They can't even tell which frequency they are tuned to. - With most models, frequency sweeping must be done in software. This requires real-time tricks with RS232 (currently suboptimal). - High-end models have a DSP (not supported with Linux). We are currently providing two abstractions for all of this: - A kernel module which provides /dev/winradioX devices and ioctl API (radio_ioctl.h). - A user-mode driver which has problems with security (being root to use ISA receivers) and RS232 performance. The best approach is to create a hamlib-X.Y.Z/winradio/winradio.c file that wraps our ioctl API (toolkit/driver/radio_ioctl.h) into a "struct rig_caps". hamlib-4.6.2/rigs/winradio/Makefile.am0000644000175000017500000000067314752216205014526 00000000000000WRSRC = wr1000.c wr1500.c wr1550.c wr3100.c wr3150.c wr3500.c wr3700.c \ g303.c g305.c \ winradio.c winradio.h linradio/radio_ioctl.h linradio/wrapi.h if G313_LINUX_GNU WRSRC += g313-posix.c linradio/wrg313api.c linradio/wrg313api.h libhamlib_winradio_la_LIBADD = $(DL_LIBS) endif if G313_WINDOWS WRSRC += g313-win.c endif noinst_LTLIBRARIES = libhamlib-winradio.la libhamlib_winradio_la_SOURCES = $(WRSRC) EXTRA_DIST = NOTES Android.mk hamlib-4.6.2/rigs/winradio/winradio.c0000644000175000017500000001743614752216205014457 00000000000000/* * Hamlib WiNRADiO backend - main file for interface through /dev/winradio API * Copyright (C) 2001 pab@users.sourceforge.net * Derived from hamlib code (C) 2000-2009 Stephane Fillod. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "winradio.h" /* config.h */ #include /* String function definitions */ #ifdef HAVE_SYS_IOCTL_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "register.h" #ifdef WINRADIO_IOCTL #include #include #define DEFAULT_WINRADIO_PATH "/dev/winradio0" #define WINRADIO_MODES RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_LSB | RIG_MODE_USB | RIG_MODE_WFM | RIG_MODE_FM int wr_rig_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); rp->type.rig = RIG_PORT_DEVICE; strncpy(rp->pathname, DEFAULT_WINRADIO_PATH, HAMLIB_FILPATHLEN - 1); return RIG_OK; } int wr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long f; if (freq > GHz(4.2)) { return -RIG_EINVAL; } f = (unsigned long)freq; if (ioctl(RIGPORT(rig)->fd, RADIO_SET_FREQ, &f)) { return -RIG_EINVAL; } return RIG_OK; } int wr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { unsigned long f; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_FREQ, &f) < 0) { return -RIG_EINVAL; } *freq = (freq_t)f; return RIG_OK; } int wr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned long m; switch (mode) { case RIG_MODE_AM: m = RMD_AM; break; case RIG_MODE_CW: m = RMD_CW; break; case RIG_MODE_LSB: m = RMD_LSB; break; case RIG_MODE_USB: m = RMD_USB; break; case RIG_MODE_WFM: m = RMD_FMW; break; case RIG_MODE_FM: switch (width) { case RIG_PASSBAND_NORMAL: case (int)kHz(17): case (int)kHz(15): m = RMD_FMN; break; case (int)kHz(6): m = RMD_FM6; break; case (int)kHz(50): m = RMD_FMM; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (ioctl(RIGPORT(rig)->fd, RADIO_SET_MODE, &m)) { return -RIG_EINVAL; } return RIG_OK; } int wr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { unsigned long m; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_MODE, &m)) { return -RIG_EINVAL; } *width = RIG_PASSBAND_NORMAL; switch (m) { case RMD_CW: *mode = RIG_MODE_CW; break; case RMD_AM: *mode = RIG_MODE_AM; break; case RMD_FMN: *mode = RIG_MODE_FM; break; /* 15kHz or 17kHz on WR-3100 */ case RMD_FM6: *mode = RIG_MODE_FM; break; /* 6kHz */ case RMD_FMM: *mode = RIG_MODE_FM; break; /* 50kHz */ case RMD_FMW: *mode = RIG_MODE_WFM; break; case RMD_LSB: *mode = RIG_MODE_LSB; break; case RMD_USB: *mode = RIG_MODE_USB; break; default: return -RIG_EINVAL; } if (*width == RIG_PASSBAND_NORMAL) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } int wr_set_powerstat(RIG *rig, powerstat_t status) { unsigned long p = 1; p = status == RIG_POWER_ON ? 1 : 0; if (ioctl(RIGPORT(rig)->fd, RADIO_SET_POWER, &p)) { return -RIG_EINVAL; } return RIG_OK; } int wr_get_powerstat(RIG *rig, powerstat_t *status) { unsigned long p; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_POWER, &p)) { return -RIG_EINVAL; } *status = p ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int wr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { switch (func) { case RIG_FUNC_FAGC: { unsigned long v = status ? 1 : 0; if (ioctl(RIGPORT(rig)->fd, RADIO_SET_AGC, &v)) { return -RIG_EINVAL; } return RIG_OK; } default: return -RIG_EINVAL; } } int wr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { switch (func) { case RIG_FUNC_FAGC: { unsigned long v; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_AGC, &v)) { return -RIG_EINVAL; } *status = v; return RIG_OK; } default: return -RIG_EINVAL; } } int wr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { hamlib_port_t *rp = RIGPORT(rig); switch (level) { case RIG_LEVEL_AF: { unsigned long v; if (ioctl(rp->fd, RADIO_GET_MAXVOL, &v)) { return -RIG_EINVAL; } v *= val.f; if (ioctl(rp->fd, RADIO_SET_VOL, &v)) { return -RIG_EINVAL; } return RIG_OK; } case RIG_LEVEL_ATT: { unsigned long v = val.i ? 1 : 0; if (ioctl(rp->fd, RADIO_SET_ATTN, &v)) { return -RIG_EINVAL; } return RIG_OK; } case RIG_LEVEL_IF: { long v = val.i; if (ioctl(rp->fd, RADIO_SET_IFS, &v)) { return -RIG_EINVAL; } return RIG_OK; } case RIG_LEVEL_RF: { long v = val.f * 100; /* iMaxIFGain on wHWVer > RHV_3150 */ if (ioctl(rp->fd, RADIO_SET_IFG, &v)) { return -RIG_EINVAL; } return RIG_OK; } default: return -RIG_EINVAL; } } int wr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { hamlib_port_t *rp = RIGPORT(rig); switch (level) { case RIG_LEVEL_AF: { unsigned long v, mv; if (ioctl(rp->fd, RADIO_GET_MAXVOL, &mv)) { return -RIG_EINVAL; } if (ioctl(rp->fd, RADIO_GET_VOL, &v)) { return -RIG_EINVAL; } val->f = (float)v / mv; return RIG_OK; } case RIG_LEVEL_ATT: { unsigned long v; if (ioctl(rp->fd, RADIO_GET_VOL, &v)) { return -RIG_EINVAL; } val->i = v ? STATE(rig)->attenuator[0] : 0; return RIG_OK; } case RIG_LEVEL_STRENGTH: { unsigned long v; if (ioctl(rp->fd, RADIO_GET_SS, &v)) { return -RIG_EINVAL; } val->i = v - 60; /* 0..120, Hamlib assumes S9 = 0dB */ return RIG_OK; } case RIG_LEVEL_IF: { long v; if (ioctl(rp->fd, RADIO_GET_IFS, &v)) { return -RIG_EINVAL; } val->i = v; return RIG_OK; } case RIG_LEVEL_RF: { long v; if (ioctl(rp->fd, RADIO_GET_IFG, &v)) { return -RIG_EINVAL; } val->f = (float)v / 100; /* iMaxIFGain on wHWVer > RHV_3150 */ return RIG_OK; } default: return -RIG_EINVAL; } } /* * FIXME: static buf does not allow reentrancy! */ const char *wr_get_info(RIG *rig) { static char buf[100]; if (ioctl(RIGPORT(rig)->fd, RADIO_GET_DESCR, buf) < 0) { return "?"; } return buf; } #endif /* WINRADIO_IOCTL */ DECLARE_INITRIG_BACKEND(winradio) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); #ifdef WINRADIO_IOCTL rig_register(&wr1000_caps); rig_register(&wr1500_caps); rig_register(&wr1550_caps); rig_register(&wr3100_caps); rig_register(&wr3150_caps); rig_register(&wr3500_caps); rig_register(&wr3700_caps); #endif /* WINRADIO_IOCTL */ /* Receivers with DLL only available under Windows */ #ifdef _WIN32 #ifdef __CYGWIN__ rig_register(&g303_caps); rig_register(&g305_caps); #endif #endif /* Available on Linux and MS Windows */ #ifndef OTHER_POSIX rig_register(&g313_caps); #endif return RIG_OK; } hamlib-4.6.2/rigs/winradio/Makefile.in0000644000175000017500000006125414752216216014543 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @G313_LINUX_GNU_TRUE@am__append_1 = g313-posix.c linradio/wrg313api.c linradio/wrg313api.h @G313_WINDOWS_TRUE@am__append_2 = g313-win.c subdir = rigs/winradio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = @G313_LINUX_GNU_TRUE@libhamlib_winradio_la_DEPENDENCIES = \ @G313_LINUX_GNU_TRUE@ $(am__DEPENDENCIES_1) am__libhamlib_winradio_la_SOURCES_DIST = wr1000.c wr1500.c wr1550.c \ wr3100.c wr3150.c wr3500.c wr3700.c g303.c g305.c winradio.c \ winradio.h linradio/radio_ioctl.h linradio/wrapi.h \ g313-posix.c linradio/wrg313api.c linradio/wrg313api.h \ g313-win.c am__dirstamp = $(am__leading_dot)dirstamp @G313_LINUX_GNU_TRUE@am__objects_1 = g313-posix.lo \ @G313_LINUX_GNU_TRUE@ linradio/wrg313api.lo @G313_WINDOWS_TRUE@am__objects_2 = g313-win.lo am__objects_3 = wr1000.lo wr1500.lo wr1550.lo wr3100.lo wr3150.lo \ wr3500.lo wr3700.lo g303.lo g305.lo winradio.lo \ $(am__objects_1) $(am__objects_2) am_libhamlib_winradio_la_OBJECTS = $(am__objects_3) libhamlib_winradio_la_OBJECTS = $(am_libhamlib_winradio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/g303.Plo ./$(DEPDIR)/g305.Plo \ ./$(DEPDIR)/g313-posix.Plo ./$(DEPDIR)/g313-win.Plo \ ./$(DEPDIR)/winradio.Plo ./$(DEPDIR)/wr1000.Plo \ ./$(DEPDIR)/wr1500.Plo ./$(DEPDIR)/wr1550.Plo \ ./$(DEPDIR)/wr3100.Plo ./$(DEPDIR)/wr3150.Plo \ ./$(DEPDIR)/wr3500.Plo ./$(DEPDIR)/wr3700.Plo \ linradio/$(DEPDIR)/wrg313api.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_winradio_la_SOURCES) DIST_SOURCES = $(am__libhamlib_winradio_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ WRSRC = wr1000.c wr1500.c wr1550.c wr3100.c wr3150.c wr3500.c wr3700.c \ g303.c g305.c winradio.c winradio.h linradio/radio_ioctl.h \ linradio/wrapi.h $(am__append_1) $(am__append_2) @G313_LINUX_GNU_TRUE@libhamlib_winradio_la_LIBADD = $(DL_LIBS) noinst_LTLIBRARIES = libhamlib-winradio.la libhamlib_winradio_la_SOURCES = $(WRSRC) EXTRA_DIST = NOTES Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/winradio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/winradio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } linradio/$(am__dirstamp): @$(MKDIR_P) linradio @: > linradio/$(am__dirstamp) linradio/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) linradio/$(DEPDIR) @: > linradio/$(DEPDIR)/$(am__dirstamp) linradio/wrg313api.lo: linradio/$(am__dirstamp) \ linradio/$(DEPDIR)/$(am__dirstamp) libhamlib-winradio.la: $(libhamlib_winradio_la_OBJECTS) $(libhamlib_winradio_la_DEPENDENCIES) $(EXTRA_libhamlib_winradio_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_winradio_la_OBJECTS) $(libhamlib_winradio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f linradio/*.$(OBJEXT) -rm -f linradio/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g303.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g305.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g313-posix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g313-win.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/winradio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr1000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr1500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr1550.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3150.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wr3700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@linradio/$(DEPDIR)/wrg313api.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf linradio/.libs linradio/_libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f linradio/$(DEPDIR)/$(am__dirstamp) -rm -f linradio/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/g303.Plo -rm -f ./$(DEPDIR)/g305.Plo -rm -f ./$(DEPDIR)/g313-posix.Plo -rm -f ./$(DEPDIR)/g313-win.Plo -rm -f ./$(DEPDIR)/winradio.Plo -rm -f ./$(DEPDIR)/wr1000.Plo -rm -f ./$(DEPDIR)/wr1500.Plo -rm -f ./$(DEPDIR)/wr1550.Plo -rm -f ./$(DEPDIR)/wr3100.Plo -rm -f ./$(DEPDIR)/wr3150.Plo -rm -f ./$(DEPDIR)/wr3500.Plo -rm -f ./$(DEPDIR)/wr3700.Plo -rm -f linradio/$(DEPDIR)/wrg313api.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/g303.Plo -rm -f ./$(DEPDIR)/g305.Plo -rm -f ./$(DEPDIR)/g313-posix.Plo -rm -f ./$(DEPDIR)/g313-win.Plo -rm -f ./$(DEPDIR)/winradio.Plo -rm -f ./$(DEPDIR)/wr1000.Plo -rm -f ./$(DEPDIR)/wr1500.Plo -rm -f ./$(DEPDIR)/wr1550.Plo -rm -f ./$(DEPDIR)/wr3100.Plo -rm -f ./$(DEPDIR)/wr3150.Plo -rm -f ./$(DEPDIR)/wr3500.Plo -rm -f ./$(DEPDIR)/wr3700.Plo -rm -f linradio/$(DEPDIR)/wrg313api.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/winradio/winradio.h0000644000175000017500000000434714752216205014461 00000000000000/* * Hamlib WiNRADiO backend - main header * Copyright (c) 2000-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _WINRADIO_H #define _WINRADIO_H 1 #include "hamlib/config.h" #define BACKEND_VER "20110822" /* * So far, only Linux has Linradio support through ioctl, * until someone port it to some other OS... */ #ifdef HAVE_LINUX_IOCTL_H #define WINRADIO_IOCTL #endif #include int wr_rig_init(RIG *rig); int wr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int wr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int wr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int wr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int wr_set_powerstat(RIG *rig, powerstat_t status); int wr_get_powerstat(RIG *rig, powerstat_t *status); int wr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int wr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int wr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int wr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); const char *wr_get_info(RIG *rig); extern struct rig_caps wr1000_caps; extern struct rig_caps wr1500_caps; extern struct rig_caps wr1550_caps; extern struct rig_caps wr3100_caps; extern struct rig_caps wr3150_caps; extern struct rig_caps wr3500_caps; extern struct rig_caps wr3700_caps; extern struct rig_caps g303_caps; extern struct rig_caps g305_caps; #if defined( _WIN32) || !defined(OTHER_POSIX) extern struct rig_caps g313_caps; #endif #endif /* _WINRADIO_H */ hamlib-4.6.2/rigs/winradio/wr1550.c0000644000175000017500000001003114752216205013566 00000000000000/* * Hamlib WiNRADiO backend - WR1550 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR1550_FUNC RIG_FUNC_NONE #define WR1550_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR1550_LEVEL (WR1550_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR1550_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr1550_caps = { RIG_MODEL(RIG_MODEL_WR1550), .model_name = "WR-1550", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR1550_FUNC, .has_set_func = WR1550_FUNC, .has_get_level = WR1550_LEVEL, .has_set_level = WR1550_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR1550_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR1550_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR1550_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR1550_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.2/rigs/winradio/wr1000.c0000644000175000017500000000762314752216205013571 00000000000000/* * Hamlib WiNRADiO backend - WR1000 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR1000_FUNC 0 #define WR1000_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR1000_LEVEL (WR1000_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR1000_MODES (RIG_MODE_AM | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr1000_caps = { RIG_MODEL(RIG_MODEL_WR1000), .model_name = "WR-1000", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR1000_FUNC, .has_set_func = WR1000_FUNC, .has_get_level = WR1000_LEVEL, .has_set_level = WR1000_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(500), .endf = MHz(1300), .modes = WR1000_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1300), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(500), .endf = MHz(824), .modes = WR1000_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR1000_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1300), .modes = WR1000_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {WR1000_MODES | RIG_MODE_WFM, 100}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(17)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.2/rigs/winradio/Android.mk0000644000175000017500000000055314752216205014400 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := wr1000.c wr1500.c wr1550.c wr3100.c wr3150.c wr3500.c wr3700.c \ g303.c g313.c g305.c winradio.c linradio/wrg313api.c LOCAL_MODULE := winradio LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/winradio/wr1500.c0000644000175000017500000001003114752216205013561 00000000000000/* * Hamlib WiNRADiO backend - WR1500 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR1500_FUNC RIG_FUNC_NONE #define WR1500_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR1500_LEVEL (WR1500_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR1500_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr1500_caps = { RIG_MODEL(RIG_MODEL_WR1500), .model_name = "WR-1500", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR1500_FUNC, .has_set_func = WR1500_FUNC, .has_get_level = WR1500_LEVEL, .has_set_level = WR1500_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR1500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR1500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR1500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR1500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(17)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.2/rigs/winradio/g313-posix.c0000644000175000017500000004255214752216205014455 00000000000000/* * Hamlib WiNRADiO backend - WR-G313 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include #include "config.h" #ifdef HAVE_DLFCN_H # include #endif #include #include "winradio.h" #include "linradio/wrg313api.h" #define G313_FUNC RIG_FUNC_NONE #define G313_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G313_MODES (RIG_MODE_USB) #define TOK_SHM_AUDIO 0x150901 #define TOK_SHM_IF 0x150902 #define TOK_SHM_SPECTRUM 0x150903 #define FIFO_PATHNAME_SIZE 64 const struct confparams g313_cfg_params[] = { { TOK_SHM_AUDIO, "audio_path", "audio path name", "POSIX shared memory path name to the audio ringbuffer", "", RIG_CONF_STRING, }, { TOK_SHM_IF, "if_path", "I/F path name", "POSIX shared memory path name to the I/F ringbuffer", "", RIG_CONF_STRING, }, { TOK_SHM_SPECTRUM, "spectrum_path", "spectrum path name", "POSIX shared memory path name to the spectrum ringbuffer", "", RIG_CONF_STRING, }, { RIG_CONF_END, NULL, } }; struct g313_fifo_data { int fd; char path[FIFO_PATHNAME_SIZE]; }; struct g313_priv_data { void *hWRAPI; int hRadio; int Opened; struct g313_fifo_data if_buf; struct g313_fifo_data audio_buf; struct g313_fifo_data spectrum_buf; }; static void g313_audio_callback(short *buffer, int count, void *arg); static void g313_if_callback(short *buffer, int count, void *arg); static void g313_spectrum_callback(float *buffer, int count, void *arg); void *g313_init_api(void) { void *hWRAPI = dlopen("wrg313api.so", RTLD_LAZY); if (hWRAPI == 0) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to load G313 shared library wrg313api.so\n", __func__); return 0; } if (InitAPI(hWRAPI) == 0) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to initialise G313 api\n", __func__); return 0; } return hWRAPI; } int g313_init(RIG *rig) { struct g313_priv_data *priv; priv = (struct g313_priv_data *)calloc(1, sizeof(struct g313_priv_data)); if (!priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } memset(priv, 0, sizeof(struct g313_priv_data)); priv->hWRAPI = g313_init_api(); if (priv->hWRAPI) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Initialised G313 API\n", __func__); } /* otherwise try again when open rig */ STATE(rig)->priv = (void *)priv; return RIG_OK; } int g313_open(RIG *rig) { int ret; struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; RADIO_DESC *List; int Count; void *audio_callback = g313_audio_callback; void *if_callback = g313_if_callback; void *spectrum_callback = g313_spectrum_callback; if (priv->hWRAPI == 0) /* might not be done yet, must be done now! */ { priv->hWRAPI = g313_init_api(); if (priv->hWRAPI) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Initialised G313 API\n", __func__); } else { return -RIG_EIO; /* can't go any further */ } } if (priv->Opened) { return RIG_OK; } ret = GetDeviceList(&List, &Count); if (ret < 0 || Count == 0) { return -RIG_EIO; } /* Open Winradio receiver handle (default to first device?) */ rig_debug(RIG_DEBUG_VERBOSE, "%s: found %d rigs 0 is %s\n", __func__, Count, List[0].Path); if (RIGPORT(rig)->pathname[0]) { priv->hRadio = OpenDevice(RIGPORT(rig)->pathname); } else { priv->hRadio = OpenDevice(List[0].Path); } DestroyDeviceList(List); if (priv->hRadio < 0) { return -RIG_EIO; /* huh! */ } rig_debug(RIG_DEBUG_VERBOSE, "%s: Opened G313\n", __func__); /* Make sure the receiver is switched on */ SetPower(priv->hRadio, 1); priv->audio_buf.fd = open(priv->audio_buf.path, O_WRONLY | O_NONBLOCK); rig_debug(RIG_DEBUG_VERBOSE, "%s: audio path %s fifo: %d\n", __func__, priv->audio_buf.path, priv->audio_buf.fd); if (priv->audio_buf.fd == -1) { audio_callback = NULL; } priv->if_buf.fd = open(priv->if_buf.path, O_WRONLY | O_NONBLOCK); rig_debug(RIG_DEBUG_VERBOSE, "%s: if path %s fifo: %d\n", __func__, priv->if_buf.path, priv->if_buf.fd); if (priv->if_buf.fd == -1) { if_callback = NULL; } priv->spectrum_buf.fd = open(priv->spectrum_buf.path, O_WRONLY | O_NONBLOCK); rig_debug(RIG_DEBUG_VERBOSE, "%s: spectrum path %s fifo: %d\n", __func__, priv->spectrum_buf.path, priv->spectrum_buf.fd); if (priv->spectrum_buf.fd == -1) { spectrum_callback = NULL; } ret = StartStreaming(priv->hRadio, audio_callback, if_callback, spectrum_callback, priv); if (ret) { return -RIG_EIO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: told G313 to start streaming audio: %d, if: %d, spec: %d\n", __func__, audio_callback ? 1 : 0, if_callback ? 1 : 0, spectrum_callback ? 1 : 0); priv->Opened = 1; return RIG_OK; } int g313_close(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; if (!priv->Opened) { return RIG_OK; } priv->Opened = 0; /* rig_debug(RIG_DEBUG_VERBOSE, "%s: stop streaming\n", __func__); StopStreaming(priv->hRadio); req.tv_sec=0; req.tv_nsec=500000000L; nanosleep(&req, NULL); */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Closing G313\n", __func__); CloseDevice(priv->hRadio); return RIG_OK; } int g313_cleanup(RIG *rig) { struct g313_priv_data *priv; if (!rig) { return -RIG_EINVAL; } priv = (struct g313_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: close fifos\n", __func__); if (priv->audio_buf.fd >= 0) { close(priv->audio_buf.fd); } if (priv->if_buf.fd >= 0) { close(priv->if_buf.fd); } if (priv->spectrum_buf.fd) { close(priv->spectrum_buf.fd); } rig_debug(RIG_DEBUG_VERBOSE, "%s: Uninitialising G313 API\n", __func__); if (priv->hWRAPI) { dlclose(priv->hWRAPI); } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int g313_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: %u\n", __func__, (unsigned int)freq); ret = SetFrequency(priv->hRadio, (unsigned int)(freq)); ret = ret == 0 ? RIG_OK : -RIG_EIO; return ret; } int g313_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; unsigned int f; int ret = GetFrequency(priv->hRadio, &f); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d f: %u\n", __func__, ret, f); if (ret) { return -RIG_EIO; } *freq = (freq_t)f; return RIG_OK; } int g313_set_powerstat(RIG *rig, powerstat_t status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int p = status == RIG_POWER_ON ? 1 : 0; int ret = SetPower(priv->hRadio, p); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d state: %d\n", __func__, ret, p); return ret == 0 ? RIG_OK : -RIG_EIO; } int g313_get_powerstat(RIG *rig, powerstat_t *status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int p; int ret = GetPower(priv->hRadio, &p); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d state: %d\n", __func__, ret, p); if (ret) { return -RIG_EIO; } *status = p ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g313_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = SetAttenuator(priv->hRadio, val.i != 0 ? 1 : 0); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Attenuator: %d\n", __func__, ret, val.i); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = SetAGC(priv->hRadio, agc); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d AGC: %d\n", __func__, ret, val.i); break; case RIG_LEVEL_RF: ret = SetIFGain(priv->hRadio, (int)(val.f * 100)); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Gain: %f\n", __func__, ret, val.f); break; default: return -RIG_EINVAL; } return ret == 0 ? RIG_OK : -RIG_EIO; } int g313_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; int value; unsigned int uvalue; double dbl; unsigned char ch; switch (level) { case RIG_LEVEL_ATT: ret = GetAttenuator(priv->hRadio, &value); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Attenuator: %d\n", __func__, ret, value); if (ret) { return -RIG_EIO; } val->i = value ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: ret = GetAGC(priv->hRadio, &value); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d AGC: %d\n", __func__, ret, value); if (ret) { return -RIG_EIO; } switch (value) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_RF: ret = GetIFGain(priv->hRadio, &uvalue); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Gain: %u\n", __func__, ret, uvalue); if (ret) { return -RIG_EIO; } val->f = ((float)uvalue) / 100.0; break; case RIG_LEVEL_STRENGTH: ret = GetSignalStrength(priv->hRadio, &dbl); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d sigstr: %f\n", __func__, ret, dbl); if (ret) { return -RIG_EIO; } val->i = ((int)dbl / 1.0) + 73; break; case RIG_LEVEL_RAWSTR: ret = GetRawSignalStrength(priv->hRadio, &ch); rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d Raw Sigstr: %u\n", __func__, ret, (unsigned int)ch); if (ret) { return -RIG_EIO; } val->i = ch; break; default: return -RIG_EINVAL; } return RIG_OK; } static const char *g313_get_info(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; static RADIO_INFO info; int ret; info.Size = sizeof(RADIO_INFO); ret = GetRadioInfo(priv->hRadio, &info); if (ret) { return NULL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: ret: %d sernum: %s\n", __func__, ret, info.SerNum); return info.SerNum; } int g313_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; size_t len = strlen(val); switch (token) { case TOK_SHM_AUDIO: if (len > (FIFO_PATHNAME_SIZE - 1)) { rig_debug(RIG_DEBUG_WARN, "%s: set audio_path %.4095s is too long\n", __func__, val); return -RIG_EINVAL; } memset(priv->audio_buf.path, 0, FIFO_PATHNAME_SIZE); strcpy(priv->audio_buf.path, val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set audio_path %s\n", __func__, priv->audio_buf.path); break; case TOK_SHM_IF: if (len > (FIFO_PATHNAME_SIZE - 1)) { rig_debug(RIG_DEBUG_WARN, "%s: set if_path %.4095s is too long\n", __func__, val); return -RIG_EINVAL; } memset(priv->if_buf.path, 0, FIFO_PATHNAME_SIZE); strcpy(priv->if_buf.path, val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set if_path %s\n", __func__, priv->if_buf.path); break; case TOK_SHM_SPECTRUM: if (len > (FIFO_PATHNAME_SIZE - 1)) { rig_debug(RIG_DEBUG_WARN, "%s: set spectrum_path %.4095s is too long\n", __func__, val); return -RIG_EINVAL; } memset(priv->spectrum_buf.path, 0, FIFO_PATHNAME_SIZE); strcpy(priv->spectrum_buf.path, val); rig_debug(RIG_DEBUG_VERBOSE, "%s: set spectrum_path %s\n", __func__, priv->spectrum_buf.path); } return RIG_OK; } int g313_get_conf(RIG *rig, hamlib_token_t token, char *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; switch (token) { case TOK_SHM_AUDIO: strcpy(val, priv->audio_buf.path); break; case TOK_SHM_IF: strcpy(val, priv->if_buf.path); break; case TOK_SHM_SPECTRUM: strcpy(val, priv->spectrum_buf.path); } return RIG_OK; } /* no need to check return from write - if not all can be written, accept overruns */ static void g313_audio_callback(short *buffer, int count, void *arg) { struct g313_priv_data *priv = (struct g313_priv_data *)arg; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(priv->audio_buf.fd, buffer, count * sizeof(short)); #pragma GCC diagnostic pop } static void g313_if_callback(short *buffer, int count, void *arg) { struct g313_priv_data *priv = (struct g313_priv_data *)arg; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" write(priv->if_buf.fd, buffer, count * sizeof(short)); #pragma GCC diagnostic pop } static void g313_spectrum_callback(float *buffer, int count, void *arg) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-result" struct g313_priv_data *priv = (struct g313_priv_data *)arg; write(priv->spectrum_buf.fd, buffer, count * sizeof(float)); #pragma GCC diagnostic pop } struct rig_caps g313_caps = { RIG_MODEL(RIG_MODEL_G313), .model_name = "WR-G313", .mfg_name = "Winradio", .version = "20191224.0", .copyright = "LGPL", /* This wrapper, not the G313 shared library or driver */ .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G313_FUNC, .has_set_func = G313_FUNC, .has_get_level = G313_LEVEL, .has_set_level = RIG_LEVEL_SET(G313_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G313_MODES, 1}, RIG_TS_END, }, .filters = { {G313_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = g313_cfg_params, .set_conf = g313_set_conf, .get_conf = g313_get_conf, .rig_init = g313_init, .rig_cleanup = g313_cleanup, .rig_open = g313_open, .rig_close = g313_close, .set_freq = g313_set_freq, .get_freq = g313_get_freq, .set_powerstat = g313_set_powerstat, .get_powerstat = g313_get_powerstat, .set_level = g313_set_level, .get_level = g313_get_level, .get_info = g313_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/winradio/g303.c0000644000175000017500000002730714752216205013315 00000000000000/* * Hamlib WiNRADiO backend - WR-G303 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef _WIN32 #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif /* * Winradio G3 capabilities. * * TODO: rig_probe, rig_scan */ #define WRG3DLL "wrg3api.dll" #define G303_FUNC RIG_FUNC_NONE #define G303_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G303_MODES (RIG_MODE_USB) /* FIXME? */ static int g3_init(RIG *rig); static int g3_cleanup(RIG *rig); static int g3_open(RIG *rig); static int g3_close(RIG *rig); static int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int g3_set_powerstat(RIG *rig, powerstat_t status); static int g3_get_powerstat(RIG *rig, powerstat_t *status); static int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *g3_get_info(RIG *rig); /* #pragma pack(1) // set byte packing */ typedef struct { int bLength; char szSerNum[9]; char szProdName[9]; DWORD dwMinFreq; DWORD dwMaxFreq; BYTE bNumBands; DWORD dwBandFreq[16]; DWORD dwLOfreq; BYTE bNumVcos; DWORD dwVcoFreq[8]; WORD wVcoDiv[8]; BYTE bVcoBits[8]; DWORD dwRefClk1; DWORD dwRefClk2; BYTE IF1DAC[8]; } __attribute__((packed)) RADIO_INFO; /* #pragma pack() // set back the default packing */ /* Some type definitions needed for dll access */ typedef int (__stdcall *FNCOpenRadioDevice)(int iDeviceNum); typedef BOOL (__stdcall *FNCCloseRadioDevice)(int hRadio); typedef BOOL (__stdcall *FNCG3SetFrequency)(int hRadio, DWORD dwFreq); typedef DWORD (__stdcall *FNCG3GetFrequency)(int hRadio); typedef BOOL (__stdcall *FNCSetPower)(int hRadio, BOOL rPower); typedef BOOL (__stdcall *FNCGetPower)(int hRadio); typedef BOOL (__stdcall *FNCSetAtten)(int hRadio, BOOL rAtten); typedef BOOL (__stdcall *FNCGetAtten)(int hRadio); typedef BOOL (__stdcall *FNCSetAGC)(int hRadio, int rAGC); typedef int (__stdcall *FNCGetAGC)(int hRadio); typedef BOOL (__stdcall *FNCSetIFGain)(int hRadio, int rIFGain); typedef int (__stdcall *FNCGetIFGain)(int hRadio); typedef int (__stdcall *FNCGetSignalStrengthdBm)(int hRadio); typedef int (__stdcall *FNCGetRawSignalStrength)(int hRadio); typedef BOOL (__stdcall *FNCG3GetInfo)(int hRadio, RADIO_INFO *info); struct g3_priv_data { HMODULE dll; int hRadio; FNCOpenRadioDevice OpenRadioDevice; FNCCloseRadioDevice CloseRadioDevice; FNCG3SetFrequency G3SetFrequency; FNCG3GetFrequency G3GetFrequency; FNCSetPower SetPower; FNCGetPower GetPower; FNCSetAtten SetAtten; FNCGetAtten GetAtten; FNCSetAGC SetAGC; FNCGetAGC GetAGC; FNCSetIFGain SetIFGain; FNCGetIFGain GetIFGain; FNCGetSignalStrengthdBm GetSignalStrengthdBm; FNCGetRawSignalStrength GetRawSignalStrength; FNCG3GetInfo G3GetInfo; }; struct rig_caps g303_caps = { RIG_MODEL(RIG_MODEL_G303), .model_name = "WR-G303", .mfg_name = "Winradio", .version = "0.2.1", .copyright = "LGPL", /* This wrapper, not the G3 DLL */ .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G303_FUNC, .has_set_func = G303_FUNC, .has_get_level = G303_LEVEL, .has_set_level = RIG_LEVEL_SET(G303_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G303_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G303_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G303_MODES, 1}, RIG_TS_END, }, .filters = { {G303_MODES, kHz(12)}, RIG_FLT_END, }, .rig_init = g3_init, .rig_cleanup = g3_cleanup, .rig_open = g3_open, .rig_close = g3_close, .set_freq = g3_set_freq, .get_freq = g3_get_freq, .set_powerstat = g3_set_powerstat, .get_powerstat = g3_get_powerstat, .set_level = g3_set_level, .get_level = g3_get_level, .get_info = g3_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int g3_init(RIG *rig) { struct g3_priv_data *priv; STATE(rig)->priv = (struct g3_priv_data *)calloc(1, sizeof(struct g3_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* Try to load required dll */ priv->dll = LoadLibrary(WRG3DLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, WRG3DLL); free(priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->OpenRadioDevice = (FNCOpenRadioDevice) GetProcAddress(priv->dll, "OpenRadioDevice"); priv->CloseRadioDevice = (FNCCloseRadioDevice) GetProcAddress(priv->dll, "CloseRadioDevice"); priv->G3SetFrequency = (FNCG3SetFrequency) GetProcAddress(priv->dll, "SetFrequency"); priv->G3GetFrequency = (FNCG3GetFrequency) GetProcAddress(priv->dll, "GetFrequency"); priv->SetPower = (FNCSetPower) GetProcAddress(priv->dll, "SetPower"); priv->GetPower = (FNCGetPower) GetProcAddress(priv->dll, "GetPower"); priv->SetAtten = (FNCSetAtten) GetProcAddress(priv->dll, "SetAtten"); priv->GetAtten = (FNCGetAtten) GetProcAddress(priv->dll, "GetAtten"); priv->SetAGC = (FNCSetAGC) GetProcAddress(priv->dll, "SetAGC"); priv->GetAGC = (FNCGetAGC) GetProcAddress(priv->dll, "GetAGC"); priv->SetIFGain = (FNCSetIFGain) GetProcAddress(priv->dll, "SetIFGain"); priv->GetIFGain = (FNCGetIFGain) GetProcAddress(priv->dll, "GetIFGain"); priv->GetSignalStrengthdBm = (FNCGetSignalStrengthdBm) GetProcAddress(priv->dll, "GetSignalStrengthdBm"); priv->GetRawSignalStrength = (FNCGetRawSignalStrength) GetProcAddress(priv->dll, "GetRawSignalStrength"); priv->G3GetInfo = (FNCG3GetInfo) GetProcAddress(priv->dll, "G3GetInfo"); return RIG_OK; } int g3_open(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int device_num; device_num = atoi(RIGPORT(rig)->pathname); /* Open Winradio receiver handle */ priv->hRadio = priv->OpenRadioDevice(device_num); if (priv->hRadio == 0) { return -RIG_EIO; /* huh! */ } /* Make sure the receiver is switched on */ priv->SetPower(priv->hRadio, TRUE); return RIG_OK; } int g3_close(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; priv->CloseRadioDevice(priv->hRadio); return RIG_OK; } int g3_cleanup(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; /* Clean up the dll access */ if (priv) { FreeLibrary(priv->dll); } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->G3SetFrequency(priv->hRadio, (DWORD)(freq)); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->G3GetFrequency(priv->hRadio); return *freq != 0 ? RIG_OK : -RIG_EIO; } int g3_set_powerstat(RIG *rig, powerstat_t status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->SetPower(priv->hRadio, status == RIG_POWER_ON ? TRUE : FALSE); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_powerstat(RIG *rig, powerstat_t *status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->GetPower(priv->hRadio); *status = ret == TRUE ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = priv->SetAtten(priv->hRadio, val.i != 0 ? TRUE : FALSE); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = priv->SetAGC(priv->hRadio, agc); break; case RIG_LEVEL_RF: ret = priv->SetIFGain(priv->hRadio, (int)(val.f * 100)); break; default: return -RIG_EINVAL; } ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = RIG_OK; switch (level) { case RIG_LEVEL_ATT: val->i = priv->GetAtten(priv->hRadio) ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: switch (priv->GetAGC(priv->hRadio)) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; case -1: ret = -RIG_EIO; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_STRENGTH: val->i = priv->GetSignalStrengthdBm(priv->hRadio) / 10 + 73; break; case RIG_LEVEL_RAWSTR: val->i = priv->GetRawSignalStrength(priv->hRadio); break; default: return -RIG_EINVAL; } return ret; } static const char *g3_get_info(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; static RADIO_INFO info; info.bLength = sizeof(RADIO_INFO); if (priv->G3GetInfo(priv->hRadio, &info) == FALSE) { return NULL; } return info.szSerNum; } #endif /* _WIN32 */ hamlib-4.6.2/rigs/winradio/g305.c0000644000175000017500000002730614752216205013316 00000000000000/* * Hamlib WiNRADiO backend - WR-G305 description * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef _WIN32 #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif /* * Winradio G3 capabilities. * Cloned from G303 * * TODO: rig_probe, rig_scan */ #define WRG3DLL "wrg3api.dll" #define G305_FUNC RIG_FUNC_NONE #define G305_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G305_MODES (RIG_MODE_USB) /* FIXME? */ static int g3_init(RIG *rig); static int g3_cleanup(RIG *rig); static int g3_open(RIG *rig); static int g3_close(RIG *rig); static int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int g3_set_powerstat(RIG *rig, powerstat_t status); static int g3_get_powerstat(RIG *rig, powerstat_t *status); static int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *g3_get_info(RIG *rig); /* #pragma pack(1) // set byte packing */ typedef struct { int bLength; char szSerNum[9]; char szProdName[9]; DWORD dwMinFreq; DWORD dwMaxFreq; BYTE bNumBands; DWORD dwBandFreq[16]; DWORD dwLOfreq; BYTE bNumVcos; DWORD dwVcoFreq[8]; WORD wVcoDiv[8]; BYTE bVcoBits[8]; DWORD dwRefClk1; DWORD dwRefClk2; BYTE IF1DAC[8]; } __attribute__((packed)) RADIO_INFO; /* #pragma pack() // set back the default packing */ /* Some type definitions needed for dll access */ typedef int (__stdcall *FNCOpenRadioDevice)(int iDeviceNum); typedef BOOL (__stdcall *FNCCloseRadioDevice)(int hRadio); typedef BOOL (__stdcall *FNCG3SetFrequency)(int hRadio, DWORD dwFreq); typedef DWORD (__stdcall *FNCG3GetFrequency)(int hRadio); typedef BOOL (__stdcall *FNCSetPower)(int hRadio, BOOL rPower); typedef BOOL (__stdcall *FNCGetPower)(int hRadio); typedef BOOL (__stdcall *FNCSetAtten)(int hRadio, BOOL rAtten); typedef BOOL (__stdcall *FNCGetAtten)(int hRadio); typedef BOOL (__stdcall *FNCSetAGC)(int hRadio, int rAGC); typedef int (__stdcall *FNCGetAGC)(int hRadio); typedef BOOL (__stdcall *FNCSetIFGain)(int hRadio, int rIFGain); typedef int (__stdcall *FNCGetIFGain)(int hRadio); typedef int (__stdcall *FNCGetSignalStrengthdBm)(int hRadio); typedef int (__stdcall *FNCGetRawSignalStrength)(int hRadio); typedef BOOL (__stdcall *FNCG3GetInfo)(int hRadio, RADIO_INFO *info); struct g3_priv_data { HMODULE dll; int hRadio; FNCOpenRadioDevice OpenRadioDevice; FNCCloseRadioDevice CloseRadioDevice; FNCG3SetFrequency G3SetFrequency; FNCG3GetFrequency G3GetFrequency; FNCSetPower SetPower; FNCGetPower GetPower; FNCSetAtten SetAtten; FNCGetAtten GetAtten; FNCSetAGC SetAGC; FNCGetAGC GetAGC; FNCSetIFGain SetIFGain; FNCGetIFGain GetIFGain; FNCGetSignalStrengthdBm GetSignalStrengthdBm; FNCGetRawSignalStrength GetRawSignalStrength; FNCG3GetInfo G3GetInfo; }; struct rig_caps g305_caps = { RIG_MODEL(RIG_MODEL_G305), .model_name = "WR-G305", .mfg_name = "Winradio", .version = "0.2.1", .copyright = "LGPL", /* This wrapper, not the G3 DLL */ .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G305_FUNC, .has_set_func = G305_FUNC, .has_get_level = G305_LEVEL, .has_set_level = RIG_LEVEL_SET(G305_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G305_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G305_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G305_MODES, 1}, RIG_TS_END, }, .filters = { {G305_MODES, kHz(12)}, RIG_FLT_END, }, .rig_init = g3_init, .rig_cleanup = g3_cleanup, .rig_open = g3_open, .rig_close = g3_close, .set_freq = g3_set_freq, .get_freq = g3_get_freq, .set_powerstat = g3_set_powerstat, .get_powerstat = g3_get_powerstat, .set_level = g3_set_level, .get_level = g3_get_level, .get_info = g3_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int g3_init(RIG *rig) { struct g3_priv_data *priv; STATE(rig)->priv = (struct g3_priv_data *)calloc(1, sizeof(struct g3_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* Try to load required dll */ priv->dll = LoadLibrary(WRG3DLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, WRG3DLL); free(priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->OpenRadioDevice = (FNCOpenRadioDevice) GetProcAddress(priv->dll, "OpenRadioDevice"); priv->CloseRadioDevice = (FNCCloseRadioDevice) GetProcAddress(priv->dll, "CloseRadioDevice"); priv->G3SetFrequency = (FNCG3SetFrequency) GetProcAddress(priv->dll, "SetFrequency"); priv->G3GetFrequency = (FNCG3GetFrequency) GetProcAddress(priv->dll, "GetFrequency"); priv->SetPower = (FNCSetPower) GetProcAddress(priv->dll, "SetPower"); priv->GetPower = (FNCGetPower) GetProcAddress(priv->dll, "GetPower"); priv->SetAtten = (FNCSetAtten) GetProcAddress(priv->dll, "SetAtten"); priv->GetAtten = (FNCGetAtten) GetProcAddress(priv->dll, "GetAtten"); priv->SetAGC = (FNCSetAGC) GetProcAddress(priv->dll, "SetAGC"); priv->GetAGC = (FNCGetAGC) GetProcAddress(priv->dll, "GetAGC"); priv->SetIFGain = (FNCSetIFGain) GetProcAddress(priv->dll, "SetIFGain"); priv->GetIFGain = (FNCGetIFGain) GetProcAddress(priv->dll, "GetIFGain"); priv->GetSignalStrengthdBm = (FNCGetSignalStrengthdBm) GetProcAddress(priv->dll, "GetSignalStrengthdBm"); priv->GetRawSignalStrength = (FNCGetRawSignalStrength) GetProcAddress(priv->dll, "GetRawSignalStrength"); priv->G3GetInfo = (FNCG3GetInfo) GetProcAddress(priv->dll, "G3GetInfo"); return RIG_OK; } int g3_open(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int device_num; device_num = atoi(RIGPORT(rig)->pathname); /* Open Winradio receiver handle */ priv->hRadio = priv->OpenRadioDevice(device_num); if (priv->hRadio == 0) { return -RIG_EIO; /* huh! */ } /* Make sure the receiver is switched on */ priv->SetPower(priv->hRadio, TRUE); return RIG_OK; } int g3_close(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; priv->CloseRadioDevice(priv->hRadio); return RIG_OK; } int g3_cleanup(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; if (priv) { /* Clean up the dll access */ FreeLibrary(priv->dll); free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int g3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->G3SetFrequency(priv->hRadio, (DWORD)(freq)); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->G3GetFrequency(priv->hRadio); return *freq != 0 ? RIG_OK : -RIG_EIO; } int g3_set_powerstat(RIG *rig, powerstat_t status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->SetPower(priv->hRadio, status == RIG_POWER_ON ? TRUE : FALSE); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_powerstat(RIG *rig, powerstat_t *status) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = priv->GetPower(priv->hRadio); *status = ret == TRUE ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = priv->SetAtten(priv->hRadio, val.i != 0 ? TRUE : FALSE); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = priv->SetAGC(priv->hRadio, agc); break; case RIG_LEVEL_RF: ret = priv->SetIFGain(priv->hRadio, (int)(val.f * 100)); break; default: return -RIG_EINVAL; } ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; int ret; ret = RIG_OK; switch (level) { case RIG_LEVEL_ATT: val->i = priv->GetAtten(priv->hRadio) ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: switch (priv->GetAGC(priv->hRadio)) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; case -1: ret = -RIG_EIO; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_STRENGTH: val->i = priv->GetSignalStrengthdBm(priv->hRadio) / 10 + 73; break; case RIG_LEVEL_RAWSTR: val->i = priv->GetRawSignalStrength(priv->hRadio); break; default: return -RIG_EINVAL; } return ret; } static const char *g3_get_info(RIG *rig) { struct g3_priv_data *priv = (struct g3_priv_data *)STATE(rig)->priv; static RADIO_INFO info; info.bLength = sizeof(RADIO_INFO); if (priv->G3GetInfo(priv->hRadio, &info) == FALSE) { return NULL; } return info.szSerNum; } #endif /* _WIN32 */ hamlib-4.6.2/rigs/winradio/wr3100.c0000644000175000017500000001003114752216205013557 00000000000000/* * Hamlib WiNRADiO backend - WR3100 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3100_FUNC RIG_FUNC_NONE #define WR3100_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR3100_LEVEL (WR3100_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3100_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3100_caps = { RIG_MODEL(RIG_MODEL_WR3100), .model_name = "WR-3100", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3100_FUNC, .has_set_func = WR3100_FUNC, .has_get_level = WR3100_LEVEL, .has_set_level = WR3100_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR3100_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3100_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3100_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR3100_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(17)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.2/rigs/winradio/linradio/0000755000175000017500000000000014752216244014350 500000000000000hamlib-4.6.2/rigs/winradio/linradio/radio_ioctl.h0000644000175000017500000000375614752216205016741 00000000000000/* ioctl API for radio devices. * (C) 1997 Michael McCormack * * Adapted for wrkit and newer winradio receivers. * (C) 1999-2000 */ #ifndef RADIO_H #define RADIO_H #include /* define ioctl() numbers for the radio */ #define RADIO_ID 0x8C /* See linux/Documentation/ioctl-number.txt */ #define RADIO_GET_POWER _IOR(RADIO_ID,0x00,long) #define RADIO_SET_POWER _IOW(RADIO_ID,0x01,long) #define RADIO_GET_MODE _IOR(RADIO_ID,0x02,long) #define RADIO_SET_MODE _IOW(RADIO_ID,0x03,long) #define RADIO_GET_MUTE _IOR(RADIO_ID,0x04,long) #define RADIO_SET_MUTE _IOW(RADIO_ID,0x05,long) #define RADIO_GET_ATTN _IOR(RADIO_ID,0x06,long) #define RADIO_SET_ATTN _IOW(RADIO_ID,0x07,long) #define RADIO_GET_VOL _IOR(RADIO_ID,0x08,long) #define RADIO_SET_VOL _IOW(RADIO_ID,0x09,long) #define RADIO_GET_FREQ _IOR(RADIO_ID,0x0a,long) /* Hz */ #define RADIO_SET_FREQ _IOW(RADIO_ID,0x0b,long) #define RADIO_GET_BFO _IOR(RADIO_ID,0x0c,long) /* Hz */ #define RADIO_SET_BFO _IOW(RADIO_ID,0x0d,long) /* #define RADIO_GET_SSAM _IOR(RADIO_ID,0x0e,long) #define RADIO_GET_SSFMN _IOR(RADIO_ID,0x0f,long) #define RADIO_GET_SSFMW1 _IOR(RADIO_ID,0x10,long) #define RADIO_GET_SSFMW2 _IOR(RADIO_ID,0x11,long) */ #define RADIO_GET_SS _IOR(RADIO_ID,0x12,long) /* 0..120 */ #define RADIO_GET_IFS _IOR(RADIO_ID,0x13,long) /* Hz */ #define RADIO_SET_IFS _IOW(RADIO_ID,0x14,long) #define RADIO_GET_DESCR _IOR(RADIO_ID,0x15,char[256]) #define RADIO_GET_AGC _IOR(RADIO_ID,0x16,long) #define RADIO_SET_AGC _IOW(RADIO_ID,0x17,long) #define RADIO_GET_IFG _IOR(RADIO_ID,0x18,long) #define RADIO_SET_IFG _IOW(RADIO_ID,0x19,long) /* Someone forgot 0x1A-0x1F ? */ #define RADIO_GET_MAXVOL _IOR(RADIO_ID,0x20,long) #define RADIO_GET_MAXIFG _IOR(RADIO_ID,0x21,long) /* radio modes */ typedef enum { RADIO_CW = 0, RADIO_AM = 1, RADIO_FMN = 2, RADIO_FMW = 3, RADIO_LSB = 4, RADIO_USB = 5, RADIO_FMM = 6, RADIO_FM6 = 7, } radio_mode; #endif /* RADIO_H */ hamlib-4.6.2/rigs/winradio/linradio/wrg313api.h0000644000175000017500000001341614752216205016163 00000000000000#ifndef __WRG313_API_H__ #define __WRG313_API_H__ #include #define WRG3APINAME "wrg313api" #define RADIOMODE_AM 0 #define RADIOMODE_SAM 1 #define RADIOMODE_LSB 2 #define RADIOMODE_USB 3 #define RADIOMODE_DSB 4 #define RADIOMODE_ISB 5 #define RADIOMODE_CW 6 #define RADIOMODE_FMN 7 #define AGC_NONE 0 #define AGC_SLOW 1 #define AGC_MEDIUM 2 #define AGC_FAST 3 #define INTERFACE_PCI 0 #define INTERFACE_USB 1 #pragma pack(push,1) typedef struct { __u32 Size; char SerNum[9]; char Model[9]; __u32 MinFreq; __u32 MaxFreq; __u8 NumBands; __u32 BandFreq[16]; __u32 LOFreq; __u8 NumVcos; __u32 VcoFreq[8]; __u16 VcoDiv[8]; __u8 VcoBits[8]; __u32 RefClk1; __u32 RefClk2; __u8 IF1DAC[8]; __s32 AGCstart; __s32 AGCmid; __s32 AGCend; __s32 DropLevel; __s32 RSSItop; __s32 RSSIref; __s32 RxGain; } RADIO_INFO; typedef struct { char Path[64]; __u8 Interface; RADIO_INFO Info; } RADIO_DESC; #pragma pack(pop) #ifdef __cplusplus extern "C" { #endif typedef void (*IF_CALLBACK)(__s16 *Buffer,int Count,void *Context); typedef void (*SPECTRUM_CALLBACK)(float *Spectrum,int Count,void *Context); typedef void (*AUDIO_CALLBACK)(__s16 *AudioBuffer,int Count,void *UserData); typedef int (*OPEN_DEVICE)(const char *DeviceName); typedef void (*CLOSE_DEVICE)(int hRadio); typedef int (*SET_POWER)(int hRadio,int Power); typedef int (*GET_POWER)(int hRadio,int *Power); typedef int (*GET_FREQUENCY)(int hRadio,unsigned int *Frequency); typedef int (*SET_FREQUENCY)(int hRadio,unsigned int Frequency); typedef int (*GET_RADIO_INFO)(int hRadio,RADIO_INFO *Info); typedef int (*GET_RSSI)(int hRadio,int *RSSI); typedef int (*GET_AGC)(int hRadio,int *AGC); typedef int (*SET_AGC)(int hRadio,int AGC); typedef int (*SET_IF_GAIN)(int hRadio,unsigned int Gain); typedef int (*GET_IF_GAIN)(int hRadio,unsigned int *Gain); typedef int (*SET_SOFT_AGC)(int hRadio,int AGC); typedef int (*GET_SOFT_AGC)(int hRadio,int *AGC); typedef int (*SET_VOLUME)(int hRadio,unsigned int Volume); typedef int (*GET_VOLUME)(int hRadio,unsigned int *Volume); typedef int (*SET_MODE)(int hRadio,int Mode); typedef int (*GET_MODE)(int hRadio,int *Mode); typedef int (*SET_IF_SHIFT)(int hRadio,int IFShift); typedef int (*GET_IF_SHIFT)(int hRadio,int *IFShift); typedef int (*SET_IF_BANDWIDTH)(int hRadio,unsigned int IFBandwidth); typedef int (*GET_IF_BANDWIDTH)(int hRadio,unsigned int *IFBandwidth); typedef int (*GET_DEVICE_LIST)(RADIO_DESC **List,int *Count); typedef void (*DESTROY_DEVICE_LIST)(RADIO_DESC *List); typedef int (*SET_ATTENUATOR)(int hRadio,int Attennutator); typedef int (*GET_ATTENUATOR)(int hRadio,int *Attenuator); typedef int (*START_STREAMING)(int hRadio,AUDIO_CALLBACK AudioCallback,IF_CALLBACK IFCallback,SPECTRUM_CALLBACK SpectrumCallback,void *Context); typedef int (*STOP_STREAMING)(int hRadio); typedef int (*GET_RAW_SIGNAL_STRENGTH)(int hRadio,unsigned char *Raw); typedef int (*GET_SIGNAL_STRENGTH)(int hRadio,double *SignalStrength); typedef int (*IS_DEVICE_CONNECTED)(int hRadio); typedef int (*GET_INTERFACE)(int hRadio,int *Interface); typedef int (*SET_CW_TONE)(int hRadio,unsigned int Frequency); typedef int (*GET_CW_TONE)(int hRadio,unsigned int *Frequency); typedef int (*SET_FM_AF_SQUELCH_LEVEL)(int hRadio,unsigned int Level); typedef int (*GET_FM_AF_SQUELCH_LEVEL)(int hRadio,unsigned int *Level); typedef int (*SET_NOTCH_FILTER)(int hRadio,int Active,int Frequency,unsigned int Bandwidth); typedef int (*GET_NOTCH_FILTER)(int hRadio,int *Active,int *Frequency,unsigned int *Bandwidth); typedef int (*SET_NOISE_BLANKER)(int hRadio,int Active,unsigned int Threshold); typedef int (*GET_NOISE_BLANKER)(int hRadio,int *Active,unsigned int *Threshold); typedef int (*SET_ISB_AUDIO_CHANNEL)(int hRadio,unsigned int Channel); typedef int (*GET_ISB_AUDIO_CHANNEL)(int hRadio,unsigned int *Channel); typedef int (*LOAD_CALIBRATION_FILE)(int hRadio,const char *Path); typedef int (*RESET_CALIBRATION)(int hRadio); typedef unsigned int (*GET_API_VERSION)(void); #ifdef __cplusplus }; #endif extern OPEN_DEVICE OpenDevice; extern CLOSE_DEVICE CloseDevice; extern SET_POWER SetPower; extern GET_POWER GetPower; extern SET_FREQUENCY SetFrequency; extern GET_FREQUENCY GetFrequency; extern GET_RADIO_INFO GetRadioInfo; extern GET_RSSI GetRSSI; extern GET_AGC GetAGC; extern SET_AGC SetAGC; extern SET_IF_GAIN SetIFGain; extern GET_IF_GAIN GetIFGain; extern SET_SOFT_AGC SetSoftAGC; extern GET_SOFT_AGC GetSoftAGC; extern SET_VOLUME SetVolume; extern GET_VOLUME GetVolume; extern SET_MODE SetMode; extern GET_MODE GetMode; extern SET_IF_SHIFT SetIFShift; extern GET_IF_SHIFT GetIFShift; extern SET_IF_BANDWIDTH SetIFBandwidth; extern GET_IF_BANDWIDTH GetIFBandwidth; extern GET_DEVICE_LIST GetDeviceList; extern DESTROY_DEVICE_LIST DestroyDeviceList; extern SET_ATTENUATOR SetAttenuator; extern GET_ATTENUATOR GetAttenuator; extern START_STREAMING StartStreaming; extern STOP_STREAMING StopStreaming; extern GET_RAW_SIGNAL_STRENGTH GetRawSignalStrength; extern GET_SIGNAL_STRENGTH GetSignalStrength; extern IS_DEVICE_CONNECTED IsDeviceConnected; extern GET_INTERFACE GetInterface; extern SET_CW_TONE SetCWTone; extern GET_CW_TONE GetCWTone; extern SET_FM_AF_SQUELCH_LEVEL SetFMAFSquelchLevel; extern GET_FM_AF_SQUELCH_LEVEL GetFMAFSquelchLevel; extern SET_NOTCH_FILTER SetNotchFilter; extern GET_NOTCH_FILTER GetNotchFilter; extern SET_NOISE_BLANKER SetNoiseBlanker; extern GET_NOISE_BLANKER GetNoiseBlanker; extern SET_ISB_AUDIO_CHANNEL SetISBAudioChannel; extern GET_ISB_AUDIO_CHANNEL GetISBAudioChannel; extern LOAD_CALIBRATION_FILE LoadCalibrationFile; extern RESET_CALIBRATION ResetCalibration; extern GET_API_VERSION GetAPIVersion; int InitAPI(void *hWRAPI); void UninitAPI(void); #endif hamlib-4.6.2/rigs/winradio/linradio/wrapi.h0000644000175000017500000001374414752216205015571 00000000000000/****************************************************************************/ /* Low-level receiver interface code. */ /* Copyright (C) 2000 WiNRADiO Communications. */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; Version 2, June 1991. */ /* */ /* This program is distributed in the hope that it will be useful, but */ /* WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ /* General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, */ /* USA. */ /****************************************************************************/ #ifndef _WRAPI_H_ #define _WRAPI_H_ #ifdef __cplusplus extern "C" { #endif /* WiNRADiO Information Features (capabilities) */ #define RIF_USVERSION 0x00000001 /* set if hardware is US version */ #define RIF_DSP 0x00000002 /* set if DSP is present */ #define RIF_LSBUSB 0x00000004 /* set if receiver as CW/LSB/USB instead of SSB */ #define RIF_CWIFSHIFT 0x00000008 /* set if receiver uses IFShift in CW (not BFOOffset) */ #define RIF_AGC 0x00000100 /* set if receiver supports AGC on/off */ #define RIF_IFGAIN 0x00000200 /* set if receiver has manual IF gain control */ /* WiNRADiO Modes */ #define RMD_CW 0 #define RMD_AM 1 #define RMD_FMN 2 #define RMD_FMW 3 #define RMD_LSB 4 #define RMD_USB 5 #define RMD_FMM 6 /* 50kHz FM */ #define RMD_FM6 7 /* 6kHz FMN */ /* WiNRADiO Hardware Versions */ #define RHV_1000a 0x0100 /* older WR-1000 series */ #define RHV_1000b 0x010a /* current WR-1000 series */ #define RHV_1500 0x0132 #define RHV_1550 0x0137 /* new WR-1550 receiver */ #define RHV_3000 0x0200 /* Spectrum Monitor series */ #define RHV_3100 0x020a #define RHV_3150 0x020f /* new WR-3150 receiver */ #define RHV_3200 0x0214 #define RHV_3500 0x0232 #define RHV_3700 0x0246 #define RHV_2000 0x0300 /* frequency x10 multiplier (ie. 2-20 GHz maximum support) */ #define RFQ_X10 0x80000000L /* WiNRADiO Hardware Interfaces */ #define RHI_ISA 0 #define RHI_SERIAL 1 #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif typedef unsigned long DWORD; typedef int BOOL; typedef unsigned int UINT; typedef unsigned char BYTE; typedef unsigned short WORD; typedef float FLOAT; typedef FLOAT *PFLOAT; typedef BOOL *PBOOL; typedef BOOL *LPBOOL; typedef BYTE *PBYTE; typedef BYTE *LPBYTE; typedef int *PINT; typedef int *LPINT; typedef UINT *PUINT; typedef UINT *LPUINT; typedef WORD *PWORD; typedef WORD *LPWORD; typedef long *LPLONG; typedef DWORD *PDWORD; typedef DWORD *LPDWORD; typedef void *LPVOID; typedef int *MODELIST; typedef MODELIST *LPMODELIST; typedef struct _RADIOINFO { DWORD dwSize; /* size of structure (must be set before calling GetRadioDeviceInfo) */ DWORD dwFeatures; /* bit flags for extra features (RIF_XXX) */ WORD wAPIVer; /* driver version */ WORD wHWVer; /* hardware version (RHV_XXX) */ DWORD dwMinFreq; /* minimum frequency receiver can tune to */ DWORD dwMaxFreq; /* maximum frequency receiver can tune to */ int iFreqRes; /* resolution of receiver in Hz */ int iNumModes; /* number of modes that can be set */ int iMaxVolume; /* maximum volume level */ int iMaxBFO; /* maximum BFO offset range (+/- in Hz) */ int iMaxFMScanRate; /* maximum scan rate for FM scanning/sweeping */ int iMaxAMScanRate; /* maximum scan rate for AM scanning/sweeping */ int iHWInterface; /* physical interface radio is connected to (RHI_XXX) */ int iDeviceNum; /* logical radio device number */ int iNumSources; /* number of selectable audio sources */ int iMaxIFShift; /* maximum IF shift */ DWORD dwWaveFormats; /* bit array of supported rec/play formats (RWF_XXX) */ int iDSPSources; /* number of selectable DSP input sources */ LPMODELIST lpSupportedModes; /* list of available modes (length specified by iNumModes) */ DWORD dwMaxFreqkHz; /* same as dwMaxFreq, but in kHz */ char szDeviceName[64]; /* not used in DOSRADIO */ int iMaxIFGain; /* the maximum manual IF gain level */ char descr[80]; /* Description (PB) */ } RADIOINFO, *PRADIOINFO, *LPRADIOINFO; int OpenRadioDevice(WORD); BOOL CloseRadioDevice(int); int GetRadioDeviceInfo(int, LPRADIOINFO); int GetSignalStrength(int); BOOL SetFrequency(int, DWORD); BOOL SetMode(int, int); BOOL SetVolume(int, int); BOOL SetAtten(int, BOOL); BOOL SetMute(int, BOOL); BOOL SetPower(int, BOOL); BOOL SetBFOOffset(int, int); BOOL SetIFShift(int, int); BOOL SetAGC(int, BOOL); BOOL SetIFGain(int, int); DWORD GetFrequency(int); int GetMode(int); int GetMaxVolume(int); int GetVolume(int); BOOL GetAtten(int); BOOL GetMute(int); BOOL GetPower(int); int GetBFOOffset(int); int GetIFShift(int); BOOL GetAGC(int); int GetMaxIFGain(int); int GetIFGain(int); char *GetDescr(int); #ifdef __cplusplus } #endif #ifdef __KERNEL__ /* Hooks called when rescheduling */ extern void (*yield_hook)(); extern void (*reenter_hook)(); #endif #endif hamlib-4.6.2/rigs/winradio/linradio/wrg313api.c0000644000175000017500000001342014752216205016151 00000000000000#if (!defined(_WIN32) || !defined(__CYGWIN__)) #include #include "config.h" #ifdef HAVE_DLFCN_H # include #endif #include "wrg313api.h" OPEN_DEVICE OpenDevice = 0; CLOSE_DEVICE CloseDevice = 0; SET_POWER SetPower = 0; GET_POWER GetPower = 0; SET_FREQUENCY SetFrequency = 0; GET_FREQUENCY GetFrequency = 0; GET_RADIO_INFO GetRadioInfo = 0; GET_RSSI GetRSSI = 0; GET_AGC GetAGC = 0; SET_AGC SetAGC = 0; SET_IF_GAIN SetIFGain = 0; GET_IF_GAIN GetIFGain = 0; SET_SOFT_AGC SetSoftAGC = 0; GET_SOFT_AGC GetSoftAGC = 0; SET_VOLUME SetVolume = 0; GET_VOLUME GetVolume = 0; SET_MODE SetMode = 0; GET_MODE GetMode = 0; GET_DEVICE_LIST GetDeviceList = 0; DESTROY_DEVICE_LIST DestroyDeviceList = 0; SET_ATTENUATOR SetAttenuator = 0; GET_ATTENUATOR GetAttenuator = 0; SET_IF_SHIFT SetIFShift = 0; GET_IF_SHIFT GetIFShift = 0; SET_IF_BANDWIDTH SetIFBandwidth = 0; GET_IF_BANDWIDTH GetIFBandwidth = 0; START_STREAMING StartStreaming = 0; STOP_STREAMING StopStreaming = 0; GET_RAW_SIGNAL_STRENGTH GetRawSignalStrength = 0; GET_SIGNAL_STRENGTH GetSignalStrength = 0; IS_DEVICE_CONNECTED IsDeviceConnected = 0; GET_INTERFACE GetInterface = 0; SET_CW_TONE SetCWTone = 0; GET_CW_TONE GetCWTone = 0; SET_FM_AF_SQUELCH_LEVEL SetFMAFSquelchLevel = 0; GET_FM_AF_SQUELCH_LEVEL GetFMAFSquelchLevel = 0; SET_NOTCH_FILTER SetNotchFilter = 0; GET_NOTCH_FILTER GetNotchFilter = 0; SET_NOISE_BLANKER SetNoiseBlanker = 0; GET_NOISE_BLANKER GetNoiseBlanker = 0; SET_ISB_AUDIO_CHANNEL SetISBAudioChannel = 0; GET_ISB_AUDIO_CHANNEL GetISBAudioChannel = 0; LOAD_CALIBRATION_FILE LoadCalibrationFile = 0; RESET_CALIBRATION ResetCalibration = 0; GET_API_VERSION GetAPIVersion = 0; int InitAPI(void *hWRAPI) { if (hWRAPI == NULL) { return 0; } GetAPIVersion = (GET_API_VERSION)dlsym(hWRAPI, "GetAPIVersion"); OpenDevice = (OPEN_DEVICE)dlsym(hWRAPI, "OpenDevice"); CloseDevice = (CLOSE_DEVICE)dlsym(hWRAPI, "CloseDevice"); SetPower = (SET_POWER)dlsym(hWRAPI, "SetPower"); GetPower = (GET_POWER)dlsym(hWRAPI, "GetPower"); SetFrequency = (SET_FREQUENCY)dlsym(hWRAPI, "SetFrequency"); GetFrequency = (GET_FREQUENCY)dlsym(hWRAPI, "GetFrequency"); GetRadioInfo = (GET_RADIO_INFO)dlsym(hWRAPI, "GetRadioInfo"); GetRSSI = (GET_RSSI)dlsym(hWRAPI, "GetRSSI"); GetAGC = (GET_AGC)dlsym(hWRAPI, "GetAGC"); SetAGC = (SET_AGC)dlsym(hWRAPI, "SetAGC"); SetIFGain = (SET_IF_GAIN)dlsym(hWRAPI, "SetIFGain"); GetIFGain = (GET_IF_GAIN)dlsym(hWRAPI, "GetIFGain"); GetDeviceList = (GET_DEVICE_LIST)dlsym(hWRAPI, "GetDeviceList"); DestroyDeviceList = (DESTROY_DEVICE_LIST)dlsym(hWRAPI, "DestroyDeviceList"); SetSoftAGC = (SET_SOFT_AGC)dlsym(hWRAPI, "SetSoftAGC"); GetSoftAGC = (GET_SOFT_AGC)dlsym(hWRAPI, "GetSoftAGC"); GetVolume = (GET_VOLUME)dlsym(hWRAPI, "GetVolume"); SetVolume = (SET_VOLUME)dlsym(hWRAPI, "SetVolume"); SetMode = (SET_MODE)dlsym(hWRAPI, "SetMode"); GetMode = (GET_MODE)dlsym(hWRAPI, "GetMode"); SetIFShift = (SET_IF_SHIFT)dlsym(hWRAPI, "SetIFShift"); GetIFShift = (GET_IF_SHIFT)dlsym(hWRAPI, "GetIFShift"); SetIFBandwidth = (SET_IF_BANDWIDTH)dlsym(hWRAPI, "SetIFBandwidth"); GetIFBandwidth = (GET_IF_BANDWIDTH)dlsym(hWRAPI, "GetIFBandwidth"); StartStreaming = (START_STREAMING)dlsym(hWRAPI, "StartStreaming"); StopStreaming = (STOP_STREAMING)dlsym(hWRAPI, "StopStreaming"); SetAttenuator = (SET_ATTENUATOR)dlsym(hWRAPI, "SetAttenuator"); GetAttenuator = (GET_ATTENUATOR)dlsym(hWRAPI, "GetAttenuator"); IsDeviceConnected = (IS_DEVICE_CONNECTED)dlsym(hWRAPI, "IsDeviceConnected"); GetInterface = (GET_INTERFACE)dlsym(hWRAPI, "GetInterface"); GetRawSignalStrength = (GET_RAW_SIGNAL_STRENGTH)dlsym(hWRAPI, "GetRawSignalStrength"); GetSignalStrength = (GET_SIGNAL_STRENGTH)dlsym(hWRAPI, "GetSignalStrength"); SetCWTone = (SET_CW_TONE)dlsym(hWRAPI, "SetCWTone"); GetCWTone = (GET_CW_TONE)dlsym(hWRAPI, "GetCWTone"); SetFMAFSquelchLevel = (SET_FM_AF_SQUELCH_LEVEL)dlsym(hWRAPI, "SetFMAFSquelchLevel"); GetFMAFSquelchLevel = (GET_FM_AF_SQUELCH_LEVEL)dlsym(hWRAPI, "GetFMAFSquelchLevel"); SetNotchFilter = (SET_NOTCH_FILTER)dlsym(hWRAPI, "SetNotchFilter"); GetNotchFilter = (GET_NOTCH_FILTER)dlsym(hWRAPI, "GetNotchFilter"); SetNoiseBlanker = (SET_NOISE_BLANKER)dlsym(hWRAPI, "SetNoiseBlanker"); GetNoiseBlanker = (GET_NOISE_BLANKER)dlsym(hWRAPI, "GetNoiseBlanker"); SetISBAudioChannel = (SET_ISB_AUDIO_CHANNEL)dlsym(hWRAPI, "SetISBAudioChannel"); GetISBAudioChannel = (GET_ISB_AUDIO_CHANNEL)dlsym(hWRAPI, "GetISBAudioChannel"); LoadCalibrationFile = (LOAD_CALIBRATION_FILE)dlsym(hWRAPI, "LoadCalibrationFile"); ResetCalibration = (RESET_CALIBRATION)dlsym(hWRAPI, "ResetCalibration"); if (!GetAPIVersion || !OpenDevice || !CloseDevice || !SetPower || !GetPower || !GetFrequency || !SetFrequency || !GetRadioInfo || !GetRSSI || !GetAGC || !SetAGC || !GetIFGain || !SetIFGain || !SetSoftAGC || !GetSoftAGC || !SetVolume || !GetVolume || !GetMode || !SetMode || !GetDeviceList || !DestroyDeviceList || !ResetCalibration || !StartStreaming || !StopStreaming || !LoadCalibrationFile || !SetAttenuator || !GetAttenuator || !GetSignalStrength || !SetIFShift || !SetIFBandwidth || !GetIFBandwidth || !GetIFShift || !GetRawSignalStrength || !IsDeviceConnected || !GetInterface || !SetCWTone || !GetCWTone || !SetFMAFSquelchLevel || !GetFMAFSquelchLevel || !SetNotchFilter || !GetNotchFilter || !SetNoiseBlanker || !GetNoiseBlanker || !SetISBAudioChannel || !GetISBAudioChannel) { return 0; } return 1; } #endif /* not _WIN32 or __CYGWIN__ */ hamlib-4.6.2/rigs/winradio/wr3700.c0000644000175000017500000001017314752216205013574 00000000000000/* * Hamlib WiNRADiO backend - WR3700 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3700_FUNC RIG_FUNC_FAGC #define WR3700_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_IF | RIG_LEVEL_RF) #define WR3700_LEVEL (WR3700_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3700_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3700_caps = { RIG_MODEL(RIG_MODEL_WR3700), .model_name = "WR-3700", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3700_FUNC, .has_set_func = WR3700_FUNC, .has_get_level = WR3700_LEVEL, .has_set_level = WR3700_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = GHz(4), .modes = WR3700_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = GHz(4), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3700_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3700_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = GHz(4), .modes = WR3700_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_FM, kHz(50)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = wr_set_func, .get_func = wr_get_func, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.2/rigs/winradio/wr3500.c0000644000175000017500000001020114752216205013562 00000000000000/* * Hamlib WiNRADiO backend - WR3500 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3500_FUNC RIG_FUNC_FAGC #define WR3500_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF | RIG_LEVEL_IF | RIG_LEVEL_RF) #define WR3500_LEVEL (WR3500_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3500_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3500_caps = { RIG_MODEL(RIG_MODEL_WR3500), .model_name = "WR-3500", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3500_FUNC, .has_set_func = WR3500_FUNC, .has_get_level = WR3500_LEVEL, .has_set_level = WR3500_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = GHz(2.6), .modes = WR3500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = GHz(2.6), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3500_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = GHz(2.6), .modes = WR3500_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(6)}, {RIG_MODE_FM, kHz(50)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = wr_set_func, .get_func = wr_get_func, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.2/rigs/winradio/g313-win.c0000644000175000017500000004372314752216205014111 00000000000000/* * Hamlib WiNRADiO backend - WR-G313 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #define G313_FUNC RIG_FUNC_NONE #define G313_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) #define G313_MODES (RIG_MODE_USB) #if defined (_WIN32) || !defined(OTHER_POSIX) #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif /* * Winradio G3 capabilities. * * TODO: rig_probe, rig_scan */ #define WAVEOUT_SOUNDCARDID 0x150901 const struct confparams g313_cfg_params[] = { { WAVEOUT_SOUNDCARDID, "wodeviceid", "WaveOut Device ID", "Sound card device ID for playing IF signal from receiver", "-1", RIG_CONF_NUMERIC, { .n = { -3, 32, 1 } } }, { RIG_CONF_END, NULL, } }; #define WRG313DLL "wrg3130api.dll" #define G313_FUNC RIG_FUNC_NONE #define G313_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AGC | RIG_LEVEL_RF | RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR) static int g313_init(RIG *rig); static int g313_cleanup(RIG *rig); static int g313_open(RIG *rig); static int g313_close(RIG *rig); static int g313_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int g313_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int g313_set_powerstat(RIG *rig, powerstat_t status); static int g313_get_powerstat(RIG *rig, powerstat_t *status); static int g313_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int g313_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *g313_get_info(RIG *rig); int g313_set_conf(RIG *rig, hamlib_token_t token, const char *val); int g313_get_conf(RIG *rig, hamlib_token_t token, char *val); /* #pragma pack(1) // set byte packing */ typedef struct { int bLength; char szSerNum[9]; char szProdName[9]; DWORD dwMinFreq; DWORD dwMaxFreq; BYTE bNumBands; DWORD dwBandFreq[16]; DWORD dwLOfreq; BYTE bNumVcos; DWORD dwVcoFreq[8]; WORD wVcoDiv[8]; BYTE bVcoBits[8]; DWORD dwRefClk1; DWORD dwRefClk2; BYTE IF1DAC[8]; } __attribute__((packed)) RADIO_INFO; /* #pragma pack() // set back the default packing */ /* Some type definitions needed for dll access */ typedef int (__stdcall *FNCOpenRadioDevice)(int iDeviceNum); typedef BOOL (__stdcall *FNCCloseRadioDevice)(int hRadio); typedef BOOL (__stdcall *FNCG3SetFrequency)(int hRadio, DWORD dwFreq); typedef DWORD (__stdcall *FNCG3GetFrequency)(int hRadio); typedef BOOL (__stdcall *FNCSetPower)(int hRadio, BOOL rPower); typedef BOOL (__stdcall *FNCGetPower)(int hRadio); typedef BOOL (__stdcall *FNCSetAtten)(int hRadio, BOOL rAtten); typedef BOOL (__stdcall *FNCGetAtten)(int hRadio); typedef BOOL (__stdcall *FNCSetAGC)(int hRadio, int rAGC); typedef int (__stdcall *FNCGetAGC)(int hRadio); typedef BOOL (__stdcall *FNCSetIFGain)(int hRadio, int rIFGain); typedef int (__stdcall *FNCGetIFGain)(int hRadio); typedef int (__stdcall *FNCGetSignalStrengthdBm)(int hRadio); typedef int (__stdcall *FNCGetRawSignalStrength)(int hRadio); typedef BOOL (__stdcall *FNCG3GetInfo)(int hRadio, RADIO_INFO *info); typedef MMRESULT(__stdcall *TwaveOutGetDevCaps)(UINT_PTR uDeviceID, LPWAVEOUTCAPS pwoc, UINT cbwoc); typedef UINT(__stdcall *TwaveOutGetNumDevs)(void); typedef HANDLE(__stdcall *TStartWaveOut)(LONG hRadio, LONG WaveOutDeviceIndex); typedef void (__stdcall *TStopWaveOut)(HANDLE hWaveOut); struct g313_priv_data { HMODULE dll; int hRadio; FNCOpenRadioDevice OpenRadioDevice; FNCCloseRadioDevice CloseRadioDevice; FNCG3SetFrequency G3SetFrequency; FNCG3GetFrequency G3GetFrequency; FNCSetPower SetPower; FNCGetPower GetPower; FNCSetAtten SetAtten; FNCGetAtten GetAtten; FNCSetAGC SetAGC; FNCGetAGC GetAGC; FNCSetIFGain SetIFGain; FNCGetIFGain GetIFGain; FNCGetSignalStrengthdBm GetSignalStrengthdBm; FNCGetRawSignalStrength GetRawSignalStrength; FNCG3GetInfo G3GetInfo; HMODULE WinMM; TwaveOutGetDevCaps waveOutGetDevCaps; TwaveOutGetNumDevs waveOutGetNumDevs; HMODULE hWRG313WO; int WaveOutDeviceID; HANDLE hWaveOut; TStartWaveOut StartWaveOut; TStopWaveOut StopWaveOut; int Opened; }; struct rig_caps g313_caps = { RIG_MODEL(RIG_MODEL_G313), .model_name = "WR-G313", .mfg_name = "Winradio", .version = "20191204.0", .copyright = "LGPL", /* This wrapper, not the G313 DLL */ .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_NONE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = G313_FUNC, .has_set_func = G313_FUNC, .has_get_level = G313_LEVEL, .has_set_level = RIG_LEVEL_SET(G313_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .rx_range_list1 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(9), .endf = MHz(30), .modes = G313_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {G313_MODES, 1}, RIG_TS_END, }, .filters = { {G313_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = g313_cfg_params, .set_conf = g313_set_conf, .get_conf = g313_get_conf, .rig_init = g313_init, .rig_cleanup = g313_cleanup, .rig_open = g313_open, .rig_close = g313_close, .set_freq = g313_set_freq, .get_freq = g313_get_freq, .set_powerstat = g313_set_powerstat, .get_powerstat = g313_get_powerstat, .set_level = g313_set_level, .get_level = g313_get_level, .get_info = g313_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int g313_init(RIG *rig) { struct g313_priv_data *priv; STATE(rig)->priv = (struct g313_priv_data *)calloc(1, sizeof( struct g313_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->WaveOutDeviceID = -1; priv->Opened = 0; priv->hWaveOut = NULL; priv->WinMM = LoadLibrary("WinMM.dll"); if (priv->WinMM == NULL) { free(priv); return -RIG_EIO; } priv->hWRG313WO = LoadLibrary("WRG313WO.dll"); if (priv->hWRG313WO == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary WRG313WO.dll\n", __func__); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; } priv->StartWaveOut = (TStartWaveOut)GetProcAddress(priv->hWRG313WO, "StartWaveOut"); priv->StopWaveOut = (TStopWaveOut)GetProcAddress(priv->hWRG313WO, "StopWaveOut"); if (!priv->StartWaveOut || !priv->StopWaveOut) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to load valid WRG313WO.dll library\n", __func__); FreeLibrary(priv->hWRG313WO); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; } /* Try to load required dll */ priv->dll = LoadLibrary(WRG313DLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, WRG313DLL); FreeLibrary(priv->hWRG313WO); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->OpenRadioDevice = (FNCOpenRadioDevice) GetProcAddress(priv->dll, "OpenRadioDevice"); priv->CloseRadioDevice = (FNCCloseRadioDevice) GetProcAddress(priv->dll, "CloseRadioDevice"); priv->G3SetFrequency = (FNCG3SetFrequency) GetProcAddress(priv->dll, "SetFrequency"); priv->G3GetFrequency = (FNCG3GetFrequency) GetProcAddress(priv->dll, "GetFrequency"); priv->SetPower = (FNCSetPower) GetProcAddress(priv->dll, "SetPower"); priv->GetPower = (FNCGetPower) GetProcAddress(priv->dll, "GetPower"); priv->SetAtten = (FNCSetAtten) GetProcAddress(priv->dll, "SetAtten"); priv->GetAtten = (FNCGetAtten) GetProcAddress(priv->dll, "GetAtten"); priv->SetAGC = (FNCSetAGC) GetProcAddress(priv->dll, "SetAGC"); priv->GetAGC = (FNCGetAGC) GetProcAddress(priv->dll, "GetAGC"); priv->SetIFGain = (FNCSetIFGain) GetProcAddress(priv->dll, "SetIFGain"); priv->GetIFGain = (FNCGetIFGain) GetProcAddress(priv->dll, "GetIFGain"); priv->GetSignalStrengthdBm = (FNCGetSignalStrengthdBm) GetProcAddress(priv->dll, "GetSignalStrengthdBm"); priv->GetRawSignalStrength = (FNCGetRawSignalStrength) GetProcAddress(priv->dll, "GetRawSignalStrength"); priv->G3GetInfo = (FNCG3GetInfo) GetProcAddress(priv->dll, "G3GetInfo"); if (!priv->OpenRadioDevice || !priv->CloseRadioDevice || !priv->G3SetFrequency || !priv->G3GetFrequency || !priv->SetPower || !priv->GetPower || !priv->SetAtten || !priv->GetAtten || !priv->SetAGC || !priv->GetAGC || !priv->SetIFGain || !priv->GetIFGain || !priv->GetSignalStrengthdBm || !priv->GetRawSignalStrength) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to load valid %s library\n", __func__, WRG313DLL); FreeLibrary(priv->dll); FreeLibrary(priv->hWRG313WO); FreeLibrary(priv->WinMM); free(priv); return -RIG_EIO; } priv->waveOutGetDevCaps = (TwaveOutGetDevCaps)GetProcAddress(priv->WinMM, "waveOutGetDevCapsA"); priv->waveOutGetNumDevs = (TwaveOutGetNumDevs)GetProcAddress(priv->WinMM, "waveOutGetNumDevs"); return RIG_OK; } int g313_findVSC(struct g313_priv_data *priv) { int OutIndex; WAVEOUTCAPS Caps; int Count; int i; OutIndex = -1; Count = priv->waveOutGetNumDevs(); for (i = 0; i < Count; i++) { if (priv->waveOutGetDevCaps(i, &Caps, sizeof(Caps)) == MMSYSERR_NOERROR) { if (strncmp(Caps.szPname, "WiNRADiO Virtual Sound Card", 27) == 0) { OutIndex = i; break; } } } return OutIndex; } int g313_open(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int device_num; int Count; int id; device_num = atoi(RIGPORT(rig)->pathname); Count = priv->waveOutGetNumDevs(); if (Count == 0) { return -RIG_EIO; } if (priv->WaveOutDeviceID == -2) { id = g313_findVSC(priv); } else { id = priv->WaveOutDeviceID; } /* Open Winradio receiver handle */ priv->hRadio = priv->OpenRadioDevice(device_num); if (priv->hRadio == 0) { return -RIG_EIO; /* huh! */ } /* Make sure the receiver is switched on */ priv->SetPower(priv->hRadio, TRUE); if (id > -3) { priv->hWaveOut = priv->StartWaveOut(priv->hRadio, id); if (priv->hWaveOut == NULL) { priv->CloseRadioDevice(priv->hRadio); return -RIG_EIO; } } else { priv->hWaveOut = NULL; } priv->Opened = 1; return RIG_OK; } int g313_close(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; if (!priv->Opened) { return RIG_OK; } priv->Opened = 0; if (priv->hWaveOut) { priv->StopWaveOut(priv->hWaveOut); } priv->CloseRadioDevice(priv->hRadio); return RIG_OK; } int g313_cleanup(RIG *rig) { struct g313_priv_data *priv; if (!rig) { return -RIG_EINVAL; } priv = (struct g313_priv_data *)STATE(rig)->priv; /* Clean up the dll access */ FreeLibrary(priv->dll); FreeLibrary(priv->WinMM); FreeLibrary(priv->hWRG313WO); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int g313_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = priv->G3SetFrequency(priv->hRadio, (DWORD)(freq)); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g313_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->G3GetFrequency(priv->hRadio); return *freq != 0 ? RIG_OK : -RIG_EIO; } int g313_set_powerstat(RIG *rig, powerstat_t status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = priv->SetPower(priv->hRadio, status == RIG_POWER_ON ? TRUE : FALSE); ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g313_get_powerstat(RIG *rig, powerstat_t *status) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = priv->GetPower(priv->hRadio); *status = ret == TRUE ? RIG_POWER_ON : RIG_POWER_OFF; return RIG_OK; } int g313_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret, agc; switch (level) { case RIG_LEVEL_ATT: ret = priv->SetAtten(priv->hRadio, val.i != 0 ? TRUE : FALSE); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: agc = 0; break; case RIG_AGC_SLOW: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_FAST: agc = 3; break; default: return -RIG_EINVAL; } ret = priv->SetAGC(priv->hRadio, agc); break; case RIG_LEVEL_RF: ret = priv->SetIFGain(priv->hRadio, (int)(val.f * 100)); break; default: return -RIG_EINVAL; } ret = ret == TRUE ? RIG_OK : -RIG_EIO; return ret; } int g313_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int ret; ret = RIG_OK; switch (level) { case RIG_LEVEL_ATT: val->i = priv->GetAtten(priv->hRadio) ? rig->caps->attenuator[0] : 0; break; case RIG_LEVEL_AGC: switch (priv->GetAGC(priv->hRadio)) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SLOW; break; case 2: val->i = RIG_AGC_MEDIUM; break; case 3: val->i = RIG_AGC_FAST; break; case -1: ret = -RIG_EIO; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_STRENGTH: val->i = priv->GetSignalStrengthdBm(priv->hRadio) / 10 + 73; break; case RIG_LEVEL_RAWSTR: val->i = priv->GetRawSignalStrength(priv->hRadio); break; default: return -RIG_EINVAL; } return ret; } static const char *g313_get_info(RIG *rig) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; static RADIO_INFO info; info.bLength = sizeof(RADIO_INFO); if (priv->G3GetInfo(priv->hRadio, &info) == FALSE) { return NULL; } return info.szSerNum; } int g313_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; int id; switch (token) { case WAVEOUT_SOUNDCARDID: if (val[0] == '0' && val[1] == 'x') { id = strtol(val, (char **)NULL, 16); } else { id = atoi(val); } if (id < -3 || id > 32) { return -RIG_EINVAL; } priv->WaveOutDeviceID = id; if (priv->Opened) { if (id == -2) { id = g313_findVSC(priv); } if (priv->hWaveOut) { priv->StopWaveOut(priv->hWaveOut); } if (id > -3) { priv->hWaveOut = priv->StartWaveOut(priv->hRadio, id); } else { priv->hWaveOut = NULL; } } break; default: return -RIG_EINVAL; } return RIG_OK; } int g313_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct g313_priv_data *priv = (struct g313_priv_data *)STATE(rig)->priv; switch (token) { case WAVEOUT_SOUNDCARDID: SNPRINTF(val, val_len, "%d", priv->WaveOutDeviceID); break; default: return -RIG_EINVAL; } return RIG_OK; } int g313_get_conf(RIG *rig, hamlib_token_t token, char *val) { return g313_get_conf2(rig, token, val, 128); } #endif /* _WIN32 */ hamlib-4.6.2/rigs/winradio/wr3150.c0000644000175000017500000001003114752216205013564 00000000000000/* * Hamlib WiNRADiO backend - WR3150 description * Copyright (c) 2001-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "winradio.h" #ifdef WINRADIO_IOCTL /* * Winradio rigs capabilities. */ #define WR3150_FUNC RIG_FUNC_NONE #define WR3150_SET_LEVEL (RIG_LEVEL_ATT | RIG_LEVEL_AF) #define WR3150_LEVEL (WR3150_SET_LEVEL | RIG_LEVEL_STRENGTH) #define WR3150_MODES (RIG_MODE_AM | RIG_MODE_CW | \ RIG_MODE_USB | RIG_MODE_LSB | RIG_MODE_FM) struct rig_caps wr3150_caps = { RIG_MODEL(RIG_MODEL_WR3150), .model_name = "WR-3150", .mfg_name = "Winradio", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_PCRECEIVER, .port_type = RIG_PORT_DEVICE, .targetable_vfo = 0, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .has_get_func = WR3150_FUNC, .has_set_func = WR3150_FUNC, .has_get_level = WR3150_LEVEL, .has_set_level = WR3150_SET_LEVEL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .transceive = RIG_TRN_OFF, .max_ifshift = kHz(2), .attenuator = { 20, RIG_DBLST_END, }, .rx_range_list1 = { { .startf = kHz(150), .endf = MHz(1500), .modes = WR3150_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(1500), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = MHz(824), .modes = WR3150_MODES, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(30), .endf = MHz(824), .modes = RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(849), .endf = MHz(869), .modes = WR3150_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, { .startf = MHz(894), .endf = MHz(1500), .modes = WR3150_MODES | RIG_MODE_WFM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, 1}, {RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, 10}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.5)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .priv = NULL, /* priv */ .rig_init = wr_rig_init, .set_freq = wr_set_freq, .get_freq = wr_get_freq, .set_mode = wr_set_mode, .get_mode = wr_get_mode, .set_powerstat = wr_set_powerstat, .get_powerstat = wr_get_powerstat, .set_level = wr_set_level, .get_level = wr_get_level, .set_func = NULL, .get_func = NULL, .get_info = wr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* WINRADIO_IOCTL */ hamlib-4.6.2/rigs/prm80/0000755000175000017500000000000014752216243011700 500000000000000hamlib-4.6.2/rigs/prm80/Makefile.am0000644000175000017500000000022014752216205013644 00000000000000PRM80SRC = prm8060.c prm80.c prm80.h noinst_LTLIBRARIES = libhamlib-prm80.la libhamlib_prm80_la_SOURCES = $(PRM80SRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/prm80/Makefile.in0000644000175000017500000005234414752216216013675 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/prm80 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_prm80_la_LIBADD = am__objects_1 = prm8060.lo prm80.lo am_libhamlib_prm80_la_OBJECTS = $(am__objects_1) libhamlib_prm80_la_OBJECTS = $(am_libhamlib_prm80_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/prm80.Plo ./$(DEPDIR)/prm8060.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_prm80_la_SOURCES) DIST_SOURCES = $(libhamlib_prm80_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ PRM80SRC = prm8060.c prm80.c prm80.h noinst_LTLIBRARIES = libhamlib-prm80.la libhamlib_prm80_la_SOURCES = $(PRM80SRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/prm80/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/prm80/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-prm80.la: $(libhamlib_prm80_la_OBJECTS) $(libhamlib_prm80_la_DEPENDENCIES) $(EXTRA_libhamlib_prm80_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_prm80_la_OBJECTS) $(libhamlib_prm80_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prm80.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prm8060.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/prm80.Plo -rm -f ./$(DEPDIR)/prm8060.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/prm80.Plo -rm -f ./$(DEPDIR)/prm8060.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/prm80/Android.mk0000644000175000017500000000040214752216205013523 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := prm8060.c prm80.c LOCAL_MODULE := prm80 LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/prm80/prm8060.c0000644000175000017500000001177414752216205013110 00000000000000/* * Hamlib PRM80 backend - PRM8060 description * Copyright (c) 2010,2021 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "prm80.h" #define PRM8060_ALL_MODES (RIG_MODE_FM) #define PRM8060_FUNC (RIG_FUNC_REV|RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define PRM8060_LEVEL_ALL (RIG_LEVEL_AF|RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER) #define PRM8060_PARM_ALL (RIG_PARM_NONE) // RIG_OP_FROM_VFO RIG_OP_MCL ?? #define PRM8060_VFO_OPS (RIG_OP_NONE) #define PRM8060_VFO (RIG_VFO_MEM) // Calibration done on PRM8070 #define PRM8060_STR_CAL { 15, \ { \ { 0x14, -54 }, /* S0 */ \ { 0x1D, -48 }, /* S1 */ \ { 0x26, -42 }, /* S2 */ \ { 0x33, -36 }, /* S3 */ \ { 0x3F, -30 }, /* S4 */ \ { 0x4D, -24 }, /* S5 */ \ { 0x55, -18 }, /* S6 */ \ { 0x61, -12 }, /* S7 */ \ { 0x68, -6 }, /* S8 */ \ { 0x6C, 0 }, /* S9 */ \ { 0x81, 10 }, /* +10 */ \ { 0x8B, 20 }, /* +20 */ \ { 0x8C, 40 }, /* +40 */ \ { 0x8C, 50 }, /* +50 */ \ { 0xFF, 60 } /* +60 */ \ } } /* * PRM 8060 rig capabilities. * http://prm80.sourceforge.net/ * https://github.com/f4fez/prm80 */ struct rig_caps prm8060_caps = { RIG_MODEL(RIG_MODEL_PRM8060), .model_name = "PRM8060", .mfg_name = "Philips/Simoco", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = PRM8060_FUNC, .has_set_func = PRM8060_FUNC, .has_get_level = PRM8060_LEVEL_ALL | RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_SET(PRM8060_LEVEL_ALL), .has_get_parm = PRM8060_PARM_ALL, .has_set_parm = RIG_PARM_SET(PRM8060_PARM_ALL), .vfo_ops = PRM8060_VFO_OPS, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, PRM80_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146) - kHz(12.5), PRM8060_ALL_MODES, -1, -1, PRM8060_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(144), MHz(146) - kHz(12.5), PRM8060_ALL_MODES, W(5), W(25), PRM8060_VFO}, RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(148) - kHz(12.5), PRM8060_ALL_MODES, -1, -1, PRM8060_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148) - kHz(12.5), PRM8060_ALL_MODES, W(5), W(25), PRM8060_VFO}, RIG_FRNG_END, }, .tuning_steps = { {PRM8060_ALL_MODES, kHz(12.5)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {PRM8060_ALL_MODES, kHz(12.5)}, RIG_FLT_END, }, .str_cal = PRM8060_STR_CAL, .rig_init = prm80_init, .rig_cleanup = prm80_cleanup, .get_mode = prm80_get_mode, .set_freq = prm80_set_freq, .get_freq = prm80_get_freq, .set_split_vfo = prm80_set_split_vfo, .get_split_vfo = prm80_get_split_vfo, .set_split_freq = prm80_set_split_freq, .get_split_freq = prm80_get_split_freq, .set_channel = prm80_set_channel, .get_channel = prm80_get_channel, .set_mem = prm80_set_mem, .get_mem = prm80_get_mem, .set_func = prm80_set_func, .get_func = prm80_get_func, .set_level = prm80_set_level, .get_level = prm80_get_level, .reset = prm80_reset, .get_dcd = prm80_get_dcd, .get_ptt = prm80_get_ptt, .get_info = prm80_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/prm80/prm80.h0000644000175000017500000000520014752216205012732 00000000000000/* * Hamlib PRM80 backend - main header * Copyright (c) 2010,2021 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _PRM80_H #define _PRM80_H 1 #include #include #define BACKEND_VER "20231002.0" #define PRM80_MEM_CAP { \ .freq = 1, \ .rptr_shift = 1, \ .flags = 1, /* lockout */ \ } struct prm80_priv_data { freq_t rx_freq; /* last RX freq set */ freq_t tx_freq; /* last TX freq set */ split_t split; /* emulated split on/off */ struct timeval status_tv; /* date of last "E" command */ char cached_statebuf[32]; /* response of last "E" command */ }; int prm80_init(RIG *rig); int prm80_cleanup(RIG *rig); int prm80_reset(RIG *rig, reset_t reset); int prm80_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int prm80_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int prm80_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int prm80_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int prm80_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int prm80_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int prm80_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int prm80_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int prm80_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int prm80_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int prm80_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int prm80_set_mem(RIG *rig, vfo_t vfo, int ch); int prm80_get_mem(RIG *rig, vfo_t vfo, int *ch); int prm80_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int prm80_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int prm80_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); const char *prm80_get_info(RIG *rig); extern struct rig_caps prm8060_caps; #endif /* _PRM80_H */ hamlib-4.6.2/rigs/prm80/prm80.c0000644000175000017500000007263614752216205012746 00000000000000/* * Hamlib PRM80 backend - main file * Copyright (c) 2010,2021 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "misc.h" #include "serial.h" #include "register.h" #include "idx_builtin.h" #include "prm80.h" #define LF "\x0a" #define BUFSZ 64 // Channel number min and max #define CHAN_MIN 0 #define CHAN_MAX 99 // "E" system state is cached for this time (ms) #define PRM80_CACHE_TIMEOUT 200 // Length (in bytes) of the response to the "E" command #define CMD_E_RSP_LEN 22 #define RX_IF_OFFSET MHz(21.4) // The rig's PLL only deals with freq in Hz divided by this value #define FREQ_DIV 12500. /* V5 based on V4 commands * retrieved from https://github.com/f4fez/prm80 * and https://github.com/f4fez/prm80/blob/master/doc/Computer_commands_V4.md * It used to be from https://sourceforge.net/projects/prm80/ * and https://sourceforge.net/p/prm80/wiki/Computer%20commands%20V4/ MessageVersion: IF TARGET EQ 8060 DB "PRM8060 V4.0" ELSEIF TARGET EQ 8070 DB "PRM8070 V4.0" ENDIF MessageAide: DB "H",0Dh,0Ah DB " Commandes disponibles :",0Dh,0Ah DB " [0] = Reset.",0Dh,0Ah DB " [1] a [5] = Show 80c552 port state P1 to P5.",0Dh,0Ah DB " [C] = Print channels list.",0Dh,0Ah DB " [D] = Set system byte.",0Dh,0Ah DB " [E] = Show system state (Mode-Chan-Chanstate-Sql-Vol-Lock-RX freq-TX freq,RSSI).",0Dh,0Ah DB " [F] = Set squelch.",0Dh,0Ah DB " [H] = Print this help page.",0Dh,0Ah DB " [I] = Erase and init RAM and EEPROM.",0Dh,0Ah DB " [K] = Set lock byte.",0Dh,0Ah DB " [L] = Print latch state.",0Dh,0Ah DB " [M] = Edit external RAM manually.",0Dh,0Ah DB " [N] = Set current channel.",0Dh,0Ah DB " [O] = Set volume.",0Dh,0Ah DB " [P] = Edit/Add channel.",0Dh,0Ah DB " [Q] = Set channels number.",0Dh,0Ah DB " [R] = Set synthetiser frequencies.",0Dh,0Ah DB " [U] = Print 80c552 internal RAM.",0Dh,0Ah DB " [S] = Copy EEPROM to external RAM.",0Dh,0Ah DB " [T] = Set current channel state.",0Dh,0Ah DB " [V] = Print firmware version.",0Dh,0Ah DB " [X] = Copy external RAM to EEPROM.",0Dh,0Ah DB " [Y] = Print first 2 kb from the EEPROM I2C 24c16.",0Dh,0Ah DB " [Z] = Print external RAM ($0000 to $07FF).",0Dh,0Ah,0 */ /* [0] = Reset. [C] = Print channels list. [D] = Set system byte. [E] = Show system state (Mode-Chan-Chanstate-Sql-Vol-Lock-RX freq-TX freq-RSSI). [F] = Set squelch. [H] = Print this help page. [K] = Set lock byte. [N] = Set current channel. [O] = Set volume. [P] = Edit/Add channel. [Q] = Set channels number. [R] = Set synthetiser frequencies. [T] = Set current channel state. [V] = Print firmware version. */ /* * Mode byte, which holds the state of system basic features: b0: Squelch mode is displayed on LCD if true. Channel mode if false. b1: Power level (High or Low mode) b2: Squelch open (Read only) b3: TX mode (Read only) b4: PLL locked (Read only) b5: Long key push (Internal) b6: Key bounce (Internal) b7: Force LCD refresh when set. Automatically cleared. Channel state byte: b0: Shift enable when true b1: Reverse mode when true b2: Positive shift when true. Negative if false b3: Scanning locked out channel if set b4-7: na. Lock byte, which disables user controls when connected to a computer b0: Keys disabled when true b1: TX disabled when true b2: Volume button disabled when true b3: RX disabled when true b4-b7: na. * ********************************************************************* */ static void prm80_force_cache_timeout(RIG *rig) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; rig_force_cache_timeout(&priv->status_tv); } /* * Read a prompt terminated by delimiter, then write an optional string s. */ static int read_prompt_and_send(hamlib_port_t *rigport, char *data, int *data_len, const char *s, const char *delimiter, int space_after_delim) { char buf[BUFSZ]; int buflen, retval; /* no data wanted? flush it anyway by reading it */ if (data == NULL) { data = buf; } buflen = (data_len == NULL) ? sizeof(buf) : *data_len; retval = read_string(rigport, (unsigned char *) data, buflen, delimiter, 1, 0, 1); if (retval < 0) { return retval; } // Place an end of string data[(retval < buflen) ? retval : (buflen - 1)] = '\0'; if (data_len != NULL) { *data_len = retval; } // Read one (dummy) space character after the colon if (space_after_delim) { char spacebuf[4]; retval = read_block(rigport, (unsigned char *) spacebuf, 1); if (retval < 0 && retval != -RIG_ETIMEOUT) { return retval; } } // Here is the answer to the prompt retval = write_block(rigport, (unsigned char *) s, strlen(s)); return retval; } /* * Read a prompt terminated by ": ", then write an optional string s. */ static int read_colon_prompt_and_send(hamlib_port_t *rigport, char *data, int *data_len, const char *s) { return read_prompt_and_send(rigport, data, data_len, s, ":", 1); } /* * Read a prompt terminated by "$" (without space afterwards), * then write an optional string s. */ static int read_dollar_prompt_and_send(hamlib_port_t *rigport, char *data, int *data_len, const char *s) { return read_prompt_and_send(rigport, data, data_len, s, "$", 0); } /* * After each executed command, the rig generally sends "\r\n>" */ static int prm80_wait_for_prompt(hamlib_port_t *rigport) { char buf[BUFSZ * 2]; int retval; // Read up to the '>' prompt and discard content. retval = read_string(rigport, (unsigned char *) buf, sizeof(buf), ">", 1, 0, 1); if (retval < 0) { return retval; } return RIG_OK; } /* * * \param cmd is string of generally one letter (or digit) * \param arg1 is an optional string to send afterwards * \param wait_prompt boolean when non-nul, will wait for "\r\n>" afterwards */ static int prm80_transaction(RIG *rig, const char *cmd, const char *arg1, int wait_prompt) { int retval; hamlib_port_t *rp = RIGPORT(rig); // Get rid of possible prompt sent by the rig rig_flush(rp); // Start with the command retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { return retval; } if (arg1 != NULL) { retval = read_colon_prompt_and_send(rp, NULL, NULL, arg1); if (retval < 0) { return retval; } } if (wait_prompt) { prm80_wait_for_prompt(rp); } return RIG_OK; } int prm80_init(RIG *rig) { if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (void *)calloc(1, sizeof(struct prm80_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } return RIG_OK; } int prm80_cleanup(RIG *rig) { if (rig == NULL) { return -RIG_EINVAL; } free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } /* * prm80_reset * Assumes rig!=NULL */ int prm80_reset(RIG *rig, reset_t reset) { int retval; /* * Reset CPU */ retval = prm80_transaction(rig, "0", NULL, 1); if (retval != RIG_OK) { return retval; } prm80_force_cache_timeout(rig); return RIG_OK; } /* * Convert freq in Hz to the RX PLL value representation with PRM08 firmware */ static unsigned rx_freq_to_pll_value(freq_t rx_freq) { // UHF vs VHF if (rx_freq > MHz(300)) { return (unsigned)((rx_freq - RX_IF_OFFSET) / FREQ_DIV); } else { return (unsigned)((rx_freq + RX_IF_OFFSET) / FREQ_DIV); } } static freq_t pll_value_to_rx_freq(unsigned pll_value) { freq_t rx_freq; rx_freq = (freq_t)pll_value * FREQ_DIV; // UHF vs VHF if (rx_freq > MHz(300)) { rx_freq += RX_IF_OFFSET; } else { rx_freq -= RX_IF_OFFSET; } return rx_freq; } /* * Set RX and TX freq * * See https://github.com/f4fez/prm80/blob/master/doc/Computer_control.md * "Adding a new channel" regarding freq format. */ int prm80_set_rx_tx_freq(RIG *rig, freq_t rx_freq, freq_t tx_freq) { hamlib_port_t *rp = RIGPORT(rig); char rx_freq_buf[BUFSZ]; char tx_freq_buf[BUFSZ]; int rc; // for RX, compute the PLL word without the IF SNPRINTF(rx_freq_buf, sizeof(rx_freq_buf), "%04X", rx_freq_to_pll_value(rx_freq)); SNPRINTF(tx_freq_buf, sizeof(tx_freq_buf), "%04X", (unsigned)(tx_freq / FREQ_DIV)); // The protocol is like this : // "RX frequency : " XXXX // CRLF"TX frequency : " XXXX rc = prm80_transaction(rig, "R", rx_freq_buf, 0); if (rc != RIG_OK) { return rc; } // There's a second line to process after prm80_transaction() rc = read_colon_prompt_and_send(rp, NULL, NULL, tx_freq_buf); if (rc != RIG_OK) { return rc; } // quid timeout in trx waiting for freq ? // NB: the [R] command does not update the checksum of the RAM! prm80_wait_for_prompt(rp); return rc; } /* * Set (RX) freq */ int prm80_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; freq_t tx_freq; int rc; if (priv->split == RIG_SPLIT_OFF) { tx_freq = freq; } else { tx_freq = (priv->tx_freq == 0.) ? freq : priv->tx_freq; } rc = prm80_set_rx_tx_freq(rig, freq, tx_freq); if (rc == RIG_OK) { priv->rx_freq = freq; } prm80_force_cache_timeout(rig); return rc; } /* * Set TX freq depending on emulated split state */ int prm80_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; freq_t rx_freq; int rc; rx_freq = (priv->rx_freq == 0.) ? tx_freq : priv->rx_freq; rc = prm80_set_rx_tx_freq(rig, rx_freq, tx_freq); if (rc == RIG_OK) { priv->tx_freq = tx_freq; } prm80_force_cache_timeout(rig); return rc; } /* * Get RX freq depending on emulated split state */ int prm80_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *freq = chan.freq; priv->tx_freq = chan.tx_freq; return RIG_OK; } /* * Enable/disable Split * * Rem: don't care about vfo */ int prm80_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; priv->split = split; return RIG_OK; } /* * Get Split */ int prm80_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; *split = priv->split; *tx_vfo = RIG_VFO_CURR; return RIG_OK; } /* * Get TX freq */ int prm80_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *tx_freq = chan.tx_freq; priv->rx_freq = chan.freq; return RIG_OK; } /* * Basic helper to ease some generic applications */ int prm80_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { // Can only do FM *mode = RIG_MODE_FM; *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* * prm80_set_mem * Assumes rig!=NULL */ int prm80_set_mem(RIG *rig, vfo_t vfo, int ch) { char chbuf[BUFSZ]; /* [N] = Set current channel. */ if (ch < CHAN_MIN || ch > CHAN_MAX) { return -RIG_EINVAL; } SNPRINTF(chbuf, sizeof(chbuf), "%02u", (unsigned)ch); prm80_force_cache_timeout(rig); // Send command, no answer expected from rig except ">" prompt return prm80_transaction(rig, "N", chbuf, 1); } /* * prm80_get_mem * Assumes rig!=NULL */ int prm80_get_mem(RIG *rig, vfo_t vfo, int *ch) { int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *ch = chan.channel_num; return RIG_OK; } /* * Convert first two hexadecimal digit to integer */ static unsigned hhtoi(const char *p) { char buf[4]; // it has to be hex digits if (!isxdigit(p[0]) || !isxdigit(p[1])) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected content '%s'\n", __func__, p); return 0; } buf[0] = p[0]; buf[1] = p[1]; buf[2] = '\0'; return (unsigned)strtol(buf, NULL, 16); } /** * Get system state [E] from rig into \a statebuf */ static int prm80_do_read_system_state(hamlib_port_t *rigport, char *statebuf) { char *p; int ret; // Get rid of possible prompt sent by the rig rig_flush(rigport); /* [E] = Show system state */ ret = write_block(rigport, (unsigned char *) "E", 1); if (ret < 0) { return (ret); } // The response length is fixed ret = read_block(rigport, (unsigned char *) statebuf, CMD_E_RSP_LEN); if (ret < 0) { return ret; } statebuf[ret] = '\0'; if (ret < CMD_E_RSP_LEN) { rig_debug(RIG_DEBUG_ERR, "%s: len=%d < %d, statebuf='%s'\n", __func__, ret, CMD_E_RSP_LEN, statebuf); return (-RIG_EPROTO); } p = strchr(statebuf, '>'); if (p) { int left_to_read = (p - statebuf) + 1; memmove(statebuf, p + 1, CMD_E_RSP_LEN - left_to_read); ret = read_block(rigport, (unsigned char *) statebuf + CMD_E_RSP_LEN - left_to_read, left_to_read); if (ret < 0) { return ret; } else { statebuf[CMD_E_RSP_LEN] = '\0'; } rig_debug(RIG_DEBUG_WARN, "%s: len=%d, statebuf='%s'\n", __func__, ret, statebuf); } prm80_wait_for_prompt(rigport); return RIG_OK; } /* * Layer to handle the cache to Get system state [E] */ static int prm80_read_system_state(RIG *rig, char *statebuf) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; int ret = RIG_OK; if (rig_check_cache_timeout(&priv->status_tv, PRM80_CACHE_TIMEOUT)) { ret = prm80_do_read_system_state(RIGPORT(rig), statebuf); if (ret == RIG_OK) { strcpy(priv->cached_statebuf, statebuf); /* update cache date */ gettimeofday(&priv->status_tv, NULL); } } else { strcpy(statebuf, priv->cached_statebuf); } return ret; } /* * prm80_get_channel * Assumes rig!=NULL */ int prm80_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { const struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; char statebuf[BUFSZ]; int ret, chanstate, mode_byte, lock_byte; if (chan->vfo == RIG_VFO_MEM) { ret = prm80_set_mem(rig, RIG_VFO_CURR, chan->channel_num); if (ret != RIG_OK) { return ret; } } ret = prm80_read_system_state(rig, statebuf); if (ret != RIG_OK) { return ret; } /* (Mode-Chan-Chanstate-Sql-Vol-Lock-RX freq-TX freq-RSSI). */ /* Examples: 1240080AFF0033F02D40__ or 14000C00FD0079708020__ */ /* Current mode: ; b0: Squelch b1: power ; b2: Squelch open b3: TX ; b4: PLL locked b5: Long press memorize ; b6: Debouncing in effect b7: LCD refresh */ mode_byte = hhtoi(statebuf); chan->mode = RIG_MODE_FM; chan->width = rig_passband_normal(rig, chan->mode); chan->channel_num = hhtoi(statebuf + 2); chan->tx_mode = chan->mode; chan->tx_width = chan->width; /* Chan state: ; b0: shift enabled b1: reverse ; b2: shift + b3: lock out */ chanstate = hhtoi(statebuf + 4) & 0x0f; /* is it rptr_shift or split mode ? */ chan->rptr_shift = (chanstate & 0x01) == 0 ? RIG_RPT_SHIFT_NONE : (chanstate & 0x02) ? RIG_RPT_SHIFT_MINUS : (chanstate & 0x04) ? RIG_RPT_SHIFT_PLUS : RIG_RPT_SHIFT_NONE; chan->flags = (chanstate & 0x08) ? RIG_CHFLAG_SKIP : 0; // squelch is in low nibble chan->levels[LVL_SQL].f = ((float)(hhtoi(statebuf + 6) & 0x0F)) / 15.; // volume is hex "00" .. "10" chan->levels[LVL_AF].f = ((float)hhtoi(statebuf + 8)) / 16.; chan->levels[LVL_RFPOWER].f = (mode_byte & 0x02) ? 1.0 : 0.0; // new in FW V5 chan->levels[LVL_RAWSTR].i = hhtoi(statebuf + 20); chan->funcs = 0; chan->funcs |= (chanstate & 0x02) ? RIG_FUNC_REV : 0; lock_byte = hhtoi(statebuf + 10) & 0x0f; chan->funcs |= (lock_byte & 0x05) ? RIG_FUNC_LOCK : 0; chan->funcs |= (lock_byte & 0x08) ? RIG_FUNC_MUTE : 0; chan->freq = pll_value_to_rx_freq((hhtoi(statebuf + 12) << 8) + hhtoi( statebuf + 14)); chan->tx_freq = ((hhtoi(statebuf + 16) << 8) + hhtoi(statebuf + 18)) * FREQ_DIV; if (chan->rptr_shift != RIG_RPT_SHIFT_NONE) { chan->rptr_offs = chan->tx_freq - chan->freq; chan->split = RIG_SPLIT_OFF; } else { chan->rptr_offs = 0; chan->split = priv->split; // RIG_SPLIT_ON; ? } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_WARN, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_WARN, "%s: need to know if rig updates when channel read or not\n", __func__); //return -RIG_ENIMPL; } return RIG_OK; } /* * prm80_set_channel handles RIG_VFO_MEM and RIG_VFO_CURR */ int prm80_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct prm80_priv_data *priv = (struct prm80_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char buf[BUFSZ]; int ret, chanstate; freq_t tx_freq; if (chan->vfo == RIG_VFO_MEM) { // setting channel without calling set_mem() if (chan->channel_num < CHAN_MIN || chan->channel_num > CHAN_MAX) { return -RIG_EINVAL; } /* [P] = Edit/Add channel */ /* Example Channel to set : 00 PLL value to load : $8020 Channel state : $00 Possibly: "This channel number doesn't exist. Add new channel (Y/N) ? " */ SNPRINTF(buf, sizeof(buf), "%02u", (unsigned)chan->channel_num); ret = prm80_transaction(rig, "P", buf, 0); if (ret != RIG_OK) { return ret; } // Set the RX frequency as PLL word. SNPRINTF(buf, sizeof(buf), "%04X", rx_freq_to_pll_value(chan->freq)); // "PLL value to load : $" ret = read_dollar_prompt_and_send(rp, NULL, NULL, buf); if (ret != RIG_OK) { return ret; } // the channel status byte. switch (chan->rptr_shift) { case RIG_RPT_SHIFT_NONE : chanstate = 0x00; break; case RIG_RPT_SHIFT_MINUS : chanstate = 0x03; break; case RIG_RPT_SHIFT_PLUS : chanstate = 0x05; break; default: chanstate = 0x00; break; } chanstate |= (chan->flags & RIG_CHFLAG_SKIP) ? 0x08 : 0; SNPRINTF(buf, sizeof(buf), "%02X", chanstate); // "Channel state : $" ret = read_dollar_prompt_and_send(rp, NULL, NULL, buf); if (ret != RIG_OK) { return ret; } // Determine if prompt came back (CRLF'>') or have to // handle the possible query from the rig: // "This channel number doesn't exist. Add new channel (Y/N) ? " ret = read_block(rp, (unsigned char *) buf, 3); if (ret < 0) { return ret; } if (ret == 3 && buf[2] == 'T') { // Read the question ret = read_string(rp, (unsigned char *) buf, sizeof(buf), "?", 1, 0, 1); if (ret < 0) { return ret; } // Read extra space ret = read_block(rp, (unsigned char *) buf, 1); if (ret < 0) { return ret; } // Send confirmation ret = write_block(rp, (unsigned char *) "Y", 1); if (ret < 0) { return ret; } } prm80_wait_for_prompt(rp); } else { // assume here chan->vfo == RIG_VFO_CURR // that is the "RAM" VFO not backed by memory tx_freq = (chan->split == RIG_SPLIT_ON) ? chan->tx_freq : chan->freq; ret = prm80_set_rx_tx_freq(rig, chan->freq, tx_freq); if (ret != RIG_OK) { return ret; } priv->split = chan->split; priv->rx_freq = chan->freq; priv->tx_freq = tx_freq; ret = prm80_set_level(rig, vfo, RIG_LEVEL_SQL, chan->levels[LVL_SQL]); if (ret != RIG_OK) { return ret; } ret = prm80_set_level(rig, vfo, RIG_LEVEL_AF, chan->levels[LVL_AF]); if (ret != RIG_OK) { return ret; } #if 0 // Not implemented yet.. ret = prm80_set_level(rig, vfo, RIG_LEVEL_RFPOWER, chan->levels[LVL_RFPOWER]); if (ret != RIG_OK) { return ret; } #endif ret = prm80_set_func(rig, vfo, RIG_FUNC_LOCK, !!(chan->funcs & RIG_FUNC_LOCK)); if (ret != RIG_OK) { return ret; } } prm80_force_cache_timeout(rig); return RIG_OK; } // TODO FUNC_REV through Channel state byte ? // TODO "Read-Modify-Write" (or shadowing in priv area) of the lock bits int prm80_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int ret; if (func & RIG_FUNC_LOCK) { /* Lock keys(b0)/Vol(b2) */ ret = prm80_transaction(rig, "K", (status != 0) ? "05" : "00", 1); } else if (func & RIG_FUNC_MUTE) { /* Lock RX(b3) */ ret = prm80_transaction(rig, "K", (status != 0) ? "08" : "00", 1); } else { ret = -RIG_EINVAL; } prm80_force_cache_timeout(rig); return ret; } int prm80_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } *status = !!(chan.funcs & func); return RIG_OK; } /* * prm80_set_level * Assumes rig!=NULL */ int prm80_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[BUFSZ]; int ret, mode_byte; // do some clamping, all levels are float values. if (val.f < 0.0) { val.f = 0.0; } else if (val.f > 1.0) { val.f = 1.0; } switch (level) { case RIG_LEVEL_AF: // Unlike system state, volume decimal SNPRINTF(buf, sizeof(buf), "%02u", (unsigned)(val.f * 16)); return prm80_transaction(rig, "O", buf, 1); case RIG_LEVEL_SQL: SNPRINTF(buf, sizeof(buf), "%02u", (unsigned)(val.f * 15)); return prm80_transaction(rig, "F", buf, 1); case RIG_LEVEL_RFPOWER: /* Current mode: ; b0: Squelch b1: power ; b2: Squelch open b3: TX ; b4: PLL locked b5: Long press memorize ; b6: Debouncing in effect b7: LCD refresh */ // Perform a "Read-Modify-Write" of the mode_byte ret = prm80_read_system_state(rig, buf); if (ret != RIG_OK) { return ret; } mode_byte = hhtoi(buf); mode_byte &= ~0x02; mode_byte |= (val.f == 0.) ? 0 : 0x02; SNPRINTF(buf, sizeof(buf), "%02X", (unsigned)mode_byte); return prm80_transaction(rig, "D", buf, 1); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } prm80_force_cache_timeout(rig); return RIG_OK; } #ifdef V4_ONLY /* * get_level RIG_LEVEL_RAWSTR */ // cppcheck-suppress unusedFunction static int prm80_get_rawstr_RAM(RIG *rig, value_t *val) { char buf[BUFSZ]; struct rig_state *rs = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); int ret, i; /* [U] = Print 80c552 internal RAM. */ // Send cmd, Wait for colon prompt, but then send nothing ret = prm80_transaction(rig, "U", "", 0); if (ret < 0) { return ret; } // Read CRLF ret = read_string(rp, buf, BUFSZ, "\n", 1, 0, 1); if (ret < 0) { return ret; } // (16 lines of 16 bytes each) // According to prm.a51, the rssi_hold variable is in RAM at RAM+35. // The RAM base is at 030h. #define RSSI_HOLD_ADDR (0x30 + 35) // = 0x53 for (i = 0; i < (RSSI_HOLD_ADDR / 16) + 1; i++) { ret = read_string(rp, buf, BUFSZ, "\n", 1, 0, 1); if (ret < 0) { return ret; } } // A line looks like this // "$50 : 00 01 02 53 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\r\n" val->i = hhtoi(buf + 6 + 3 * (RSSI_HOLD_ADDR % 16)); // discard the remaining content of RAM print for (i = 0; i < (16 - RSSI_HOLD_ADDR / 16) - 1; i++) { read_string(rp, buf, BUFSZ, "\n", 1, 0, 1); } prm80_wait_for_prompt(rp); return RIG_OK; } #endif /* * prm80_get_level * Assumes rig!=NULL */ int prm80_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; channel_t chan; memset(&chan, 0, sizeof(chan)); chan.vfo = RIG_VFO_CURR; ret = prm80_get_channel(rig, vfo, &chan, 0); if (ret != RIG_OK) { return ret; } switch (level) { case RIG_LEVEL_RAWSTR: val->i = chan.levels[LVL_RAWSTR].i; break; case RIG_LEVEL_AF: val->f = chan.levels[LVL_AF].f; break; case RIG_LEVEL_SQL: val->f = chan.levels[LVL_SQL].f; break; case RIG_LEVEL_RFPOWER: val->f = chan.levels[LVL_RFPOWER].f; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int prm80_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char statebuf[BUFSZ]; int ret, mode_byte; ret = prm80_read_system_state(rig, statebuf); if (ret != RIG_OK) { return ret; } mode_byte = hhtoi(statebuf); // TX mode on? *ptt = (mode_byte & 0x08) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } int prm80_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char statebuf[BUFSZ]; int ret, mode_byte; ret = prm80_read_system_state(rig, statebuf); if (ret != RIG_OK) { return ret; } mode_byte = hhtoi(statebuf); // Squelch open? *dcd = (mode_byte & 0x04) ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } // TODO vfo_op : MCL FROM_VFO .. /* * prm80_get_info * Assumes rig!=NULL */ const char *prm80_get_info(RIG *rig) { static char s_buf[BUFSZ]; hamlib_port_t *rp = RIGPORT(rig); char *p; int ret; // Get rid of possible prompt sent by the rig rig_flush(rp); /* [V] = Print firmware version. */ ret = write_block(rp, (unsigned char *) "V", 1); if (ret < 0) { return NULL; } ret = read_string(rp, (unsigned char *) s_buf, BUFSZ, ">", 1, 0, 1); if (ret < 0) { return NULL; } p = strchr(s_buf, '\r'); if (p) { // chomp *p = '\0'; } return s_buf; } /* * initrigs_prm80 is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(prm80) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&prm8060_caps); return RIG_OK; } hamlib-4.6.2/rigs/tapr/0000755000175000017500000000000014752216244011701 500000000000000hamlib-4.6.2/rigs/tapr/tapr.h0000644000175000017500000000211714752216205012736 00000000000000/* * Hamlib TAPR backend - main header * Copyright (c) 2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _TAPR_H #define _TAPR_H 1 #include int tapr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int tapr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern struct rig_caps dsp10_caps; #endif /* _TAPR_H */ hamlib-4.6.2/rigs/tapr/Makefile.am0000644000175000017500000000021014752216205013643 00000000000000TAPRSRC = dsp10.c tapr.c tapr.h noinst_LTLIBRARIES = libhamlib-tapr.la libhamlib_tapr_la_SOURCES = $(TAPRSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/tapr/Makefile.in0000644000175000017500000005227614752216216013701 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/tapr ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_tapr_la_LIBADD = am__objects_1 = dsp10.lo tapr.lo am_libhamlib_tapr_la_OBJECTS = $(am__objects_1) libhamlib_tapr_la_OBJECTS = $(am_libhamlib_tapr_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dsp10.Plo ./$(DEPDIR)/tapr.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_tapr_la_SOURCES) DIST_SOURCES = $(libhamlib_tapr_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TAPRSRC = dsp10.c tapr.c tapr.h noinst_LTLIBRARIES = libhamlib-tapr.la libhamlib_tapr_la_SOURCES = $(TAPRSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/tapr/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/tapr/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-tapr.la: $(libhamlib_tapr_la_OBJECTS) $(libhamlib_tapr_la_DEPENDENCIES) $(EXTRA_libhamlib_tapr_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_tapr_la_OBJECTS) $(libhamlib_tapr_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsp10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tapr.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dsp10.Plo -rm -f ./$(DEPDIR)/tapr.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dsp10.Plo -rm -f ./$(DEPDIR)/tapr.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/tapr/Android.mk0000644000175000017500000000037614752216205013535 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dsp10.c tapr.c LOCAL_MODULE := tapr LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/tapr/tapr.c0000644000175000017500000000476214752216205012741 00000000000000/* * Hamlib TAPR backend - main file * Copyright (c) 2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "register.h" #include "serial.h" #include "tapr.h" #define ESC '$' #define CMD_LEN 6 #define CMD7 7 #define NU1 1 #define NU2 2 #define NU3 3 #define NU4 4 /* * tapr_cmd * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ static int tapr_cmd(RIG *rig, unsigned char cmd, unsigned char c1, unsigned char c2, unsigned char c3, unsigned char c4) { int retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char cmdbuf[CMD_LEN]; rig_flush(rp); cmdbuf[0] = ESC; cmdbuf[1] = cmd; cmdbuf[2] = c1; cmdbuf[3] = c2; cmdbuf[4] = c3; cmdbuf[5] = c4; retval = write_block(rp, cmdbuf, 6); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tapr_set_freq * Assumes rig!=NULL */ int tapr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned int dsp_dph, dsp_deltap_lo, dsp_deltap_hi; int retval; return -RIG_ENIMPL; /* FIXME! */ dsp_dph = (unsigned int)(1.365333333 * (double)(freq - MHz(144) + 15000UL)); dsp_deltap_lo = 0xff & dsp_dph; dsp_deltap_hi = 0xff & (dsp_dph >> 8); retval = tapr_cmd(rig, CMD7, 0, NU1, dsp_deltap_lo, dsp_deltap_hi); return retval; } /* * tapr_set_mode * Assumes rig!=NULL */ int tapr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return -RIG_ENIMPL; } /* * initrigs_tapr is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(tapr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&dsp10_caps); return RIG_OK; } hamlib-4.6.2/rigs/tapr/dsp10.c0000644000175000017500000000707214752216205012717 00000000000000/* * Hamlib TAPR backend - DSP-10 description * Copyright (c) 2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "tapr.h" #define DSP10_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DSP10_FUNC (RIG_FUNC_NONE) #define DSP10_LEVEL_ALL (RIG_LEVEL_NONE) #define DSP10_PARM_ALL (RIG_PARM_NONE) #define DSP10_VFO (RIG_VFO_A) /* * DSP-10 rig capabilities. * * This backend is not working, and is just a call for someone motivated. * Note: The DSP has to be loaded beforehand! * * protocol is documented at (version 2) * http://www.proaxis.com/~boblark/pc_dsp2.txt * * See also: * http://home.teleport.com/~oldaker/dsp10_repository.htm * http://www.proaxis.com/~boblark/dsp10.htm * http://www.tapr.org/tapr/html/Fdsp10.html * * */ struct rig_caps dsp10_caps = { RIG_MODEL(RIG_MODEL_DSP10), .model_name = "DSP-10", .mfg_name = "TAPR", .version = "20061007.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = DSP10_FUNC, .has_set_func = DSP10_FUNC, .has_get_level = DSP10_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DSP10_LEVEL_ALL), .has_get_parm = DSP10_PARM_ALL, .has_set_parm = RIG_PARM_SET(DSP10_PARM_ALL), .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(148), DSP10_MODES, -1, -1, DSP10_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), DSP10_MODES, mW(20), mW(20), DSP10_VFO}, RIG_FRNG_END, }, .tuning_steps = { {DSP10_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.7)}, {RIG_MODE_FM, kHz(8)}, RIG_FLT_END, }, .priv = (void *)NULL, .set_freq = tapr_set_freq, .set_mode = tapr_set_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/racal/0000755000175000017500000000000014752216243012014 500000000000000hamlib-4.6.2/rigs/racal/ra37xx.h0000644000175000017500000000642014752216205013241 00000000000000/* * Hamlib Racal backend - RA37XX header * Copyright (c) 2004-2010 by Stephane Fillod * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RA37XX_H #define _RA37XX_H 1 #include "hamlib/rig.h" #include "racal.h" #undef BACKEND_VER #define BACKEND_VER "20210911" extern const struct confparams ra37xx_cfg_params[]; /* Packet timeout at Master port, 5-9 */ #define RA37XX_TIMEOUT 1000 /* ms */ #define RA37XX_STR_CAL { 13, \ { \ { 97, 86 }, /* 120 dBuV */ \ { 109, 76 }, /* 110 dBuV */ \ { 120, 66 }, /* 100 dBuV */ \ { 132, 56 }, /* 90 dBuV */ \ { 144, 46 }, /* 80 dBuV */ \ { 155, 36 }, /* 70 dBuV */ \ { 167, 26 }, /* 60 dBuV */ \ { 179, 16 }, /* 50 dBuV */ \ { 190, 6 }, /* 40 dBuV */ \ { 202, -4 }, /* 30 dBuV */ \ { 214, -14 }, /* 20 dBuV */ \ { 225, -24 }, /* 10 dBuV */ \ { 255, -34 }, /* 0 dBuV */ \ } } #define RA37XX_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .levels = RIG_LEVEL_AGC|RIG_LEVEL_CWPITCH, \ /* .flags = 1, */ \ } struct ra37xx_priv_data { int receiver_id; }; int ra37xx_set_conf(RIG *rig, hamlib_token_t token, const char *val); int ra37xx_get_conf(RIG *rig, hamlib_token_t token, char *val); int ra37xx_init(RIG *rig); int ra37xx_cleanup(RIG *rig); int ra37xx_open(RIG *rig); int ra37xx_close(RIG *rig); int ra37xx_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int ra37xx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int ra37xx_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int ra37xx_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int ra37xx_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int ra37xx_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int ra37xx_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ra37xx_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); const char* ra37xx_get_info(RIG *rig); int ra37xx_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int ra37xx_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int ra37xx_set_mem(RIG *rig, vfo_t vfo, int ch); int ra37xx_get_mem(RIG *rig, vfo_t vfo, int *ch); int ra37xx_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); int ra37xx_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); #endif /* _RA37XX_H */ hamlib-4.6.2/rigs/racal/Makefile.am0000644000175000017500000000025214752216205013765 00000000000000RACALSRC = ra6790.c ra3702.c ra37xx.c ra37xx.h racal.c racal.h noinst_LTLIBRARIES = libhamlib-racal.la libhamlib_racal_la_SOURCES = $(RACALSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/racal/racal.h0000644000175000017500000000367714752216205013202 00000000000000/* * Hamlib Racal backend - main header * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RACAL_H #define _RACAL_H 1 #include "hamlib/rig.h" #include "token.h" #define BACKEND_VER "20200113" #define TOK_RIGID TOKEN_BACKEND(1) extern const struct confparams racal_cfg_params[]; struct racal_priv_data { unsigned receiver_id; int bfo; float threshold; /* attenuation */ }; int racal_set_conf(RIG *rig, hamlib_token_t token, const char *val); int racal_get_conf(RIG *rig, hamlib_token_t token, char *val); int racal_init(RIG *rig); int racal_cleanup(RIG *rig); int racal_open(RIG *rig); int racal_close(RIG *rig); int racal_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int racal_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int racal_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int racal_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int racal_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int racal_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int racal_reset(RIG *rig, reset_t reset); const char* racal_get_info(RIG *rig); extern struct rig_caps ra6790_caps; extern struct rig_caps ra3702_caps; #endif /* _RACAL_H */ hamlib-4.6.2/rigs/racal/Makefile.in0000644000175000017500000005316214752216216014010 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/racal ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_racal_la_LIBADD = am__objects_1 = ra6790.lo ra3702.lo ra37xx.lo racal.lo am_libhamlib_racal_la_OBJECTS = $(am__objects_1) libhamlib_racal_la_OBJECTS = $(am_libhamlib_racal_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/ra3702.Plo ./$(DEPDIR)/ra37xx.Plo \ ./$(DEPDIR)/ra6790.Plo ./$(DEPDIR)/racal.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_racal_la_SOURCES) DIST_SOURCES = $(libhamlib_racal_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RACALSRC = ra6790.c ra3702.c ra37xx.c ra37xx.h racal.c racal.h noinst_LTLIBRARIES = libhamlib-racal.la libhamlib_racal_la_SOURCES = $(RACALSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/racal/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/racal/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-racal.la: $(libhamlib_racal_la_OBJECTS) $(libhamlib_racal_la_DEPENDENCIES) $(EXTRA_libhamlib_racal_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_racal_la_OBJECTS) $(libhamlib_racal_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ra3702.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ra37xx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ra6790.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/racal.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/ra3702.Plo -rm -f ./$(DEPDIR)/ra37xx.Plo -rm -f ./$(DEPDIR)/ra6790.Plo -rm -f ./$(DEPDIR)/racal.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/ra3702.Plo -rm -f ./$(DEPDIR)/ra37xx.Plo -rm -f ./$(DEPDIR)/ra6790.Plo -rm -f ./$(DEPDIR)/racal.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/racal/Android.mk0000644000175000017500000000042314752216205013642 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ra6790.c ra3702.c racal.c ra37xx.c LOCAL_MODULE := racal LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/racal/racal.c0000644000175000017500000002716514752216205013173 00000000000000/* * Hamlib Racal backend - main file * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "token.h" #include "racal.h" const struct confparams racal_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID", "0", RIG_CONF_NUMERIC, { .n = { 0, 99, 1 } } }, { RIG_CONF_END, NULL, } }; #define BUFSZ 32 #define SOM "$" #define EOM "\x0d" /* CR */ /* * modes */ #define MD_AM 1 #define MD_FM 2 #define MD_MCW 3 /* variable BFO */ #define MD_CW 4 /* BFO center */ #define MD_ISB 5 /* option */ #define MD_LSB 6 #define MD_USB 7 /* * racal_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL * * TODO: Status Response handling with G/T commands */ static int racal_transaction(RIG *rig, const char *cmd, char *data, int *data_len) { const struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char cmdbuf[BUFSZ + 1]; int retval; SNPRINTF(cmdbuf, sizeof(cmdbuf), SOM "%u%s" EOM, priv->receiver_id, cmd); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return retval; } retval = read_string(rp, (unsigned char *) data, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval <= 0) { return retval; } /* strip CR from string */ if (data[retval - 1] == '\x0d') { data[--retval] = '\0'; /* chomp */ } *data_len = retval; return RIG_OK; } int racal_init(RIG *rig) { struct racal_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct racal_priv_data *)calloc(1, sizeof( struct racal_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->receiver_id = 0; priv->bfo = 0; priv->threshold = 0; return RIG_OK; } /* */ int racal_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int racal_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: priv->receiver_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int racal_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%u", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int racal_get_conf(RIG *rig, hamlib_token_t token, char *val) { return racal_get_conf2(rig, token, val, 128); } /* * racal_open * Assumes rig!=NULL */ int racal_open(RIG *rig) { /* Set Receiver to remote control * * TODO: Perform the BITE routine (1mn!) at each open? * TODO: "S5" request values of IF bandwidth filters found? */ return racal_transaction(rig, "S2", NULL, NULL); } /* * racal_close * Assumes rig!=NULL */ int racal_close(RIG *rig) { /* Set Receiver to local control */ return racal_transaction(rig, "S1", NULL, NULL); } /* * racal_set_freq * Assumes rig!=NULL */ int racal_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%0g", (double)(freq / MHz(1))); return racal_transaction(rig, freqbuf, NULL, NULL); } int racal_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; int retval, len; double f; retval = racal_transaction(rig, "TF", freqbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || freqbuf[0] != 'F') { return -RIG_EPROTO; } sscanf(freqbuf + 1, "%lf", &f); *freq = (freq_t)f * MHz(1); return RIG_OK; } /* * racal_set_mode * Assumes rig!=NULL */ int racal_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { const struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; int ra_mode; char buf[BUFSZ]; switch (mode) { case RIG_MODE_CW: ra_mode = (priv->bfo != 0) ? MD_MCW : MD_CW; break; case RIG_MODE_USB: ra_mode = MD_USB; break; case RIG_MODE_LSB: ra_mode = MD_LSB; break; case RIG_MODE_AM: ra_mode = MD_AM; break; case RIG_MODE_AMS: ra_mode = MD_ISB; break; /* TBC */ case RIG_MODE_FM: ra_mode = MD_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } SNPRINTF(buf, sizeof(buf), "D%dI%.0f", ra_mode, (double)(width / kHz(1))); } else { SNPRINTF(buf, sizeof(buf), "D%d", ra_mode); } return racal_transaction(rig, buf, NULL, NULL); } int racal_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char resbuf[BUFSZ], *p; int retval, len; double f; retval = racal_transaction(rig, "TDI", resbuf, &len); if (retval < RIG_OK) { return retval; } p = strchr(resbuf, 'I'); if (len < 3 || resbuf[0] != 'D' || !p) { return -RIG_EPROTO; } switch (resbuf[1] - '0') { case MD_MCW: case MD_CW: *mode = RIG_MODE_CW; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_ISB: *mode = RIG_MODE_AMS; break; /* TBC */ case MD_FM: *mode = RIG_MODE_FM; break; case MD_AM: *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(*mode)); return -RIG_EPROTO; } sscanf(p + 1, "%lf", &f); *width = (pbwidth_t)(f * kHz(1)); return RIG_OK; } /* * racal_set_level * Assumes rig!=NULL */ int racal_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; char cmdbuf[BUFSZ]; int agc; switch (level) { case RIG_LEVEL_RF: /* Manually set threshold */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%d", (int)(val.f * 120)); priv->threshold = val.f; break; case RIG_LEVEL_IF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "B%+0g", ((double)val.i) / kHz(1)); priv->bfo = val.i; break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: agc = 1; break; case RIG_AGC_MEDIUM: agc = 2; break; case RIG_AGC_SLOW: agc = 3; break; case RIG_AGC_USER: agc = 4; break; default: return -RIG_EINVAL; } if (priv->threshold != 0 && agc != 4) { agc += 4; /* with manually set threshold */ } SNPRINTF(cmdbuf, sizeof(cmdbuf), "M%d", agc); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return racal_transaction(rig, cmdbuf, NULL, NULL); } /* * racal_get_level * Assumes rig!=NULL */ int racal_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct racal_priv_data *priv = (struct racal_priv_data *)STATE(rig)->priv; char resbuf[BUFSZ]; int retval, len, att; double f; switch (level) { case RIG_LEVEL_RF: /* Manually set threshold */ retval = racal_transaction(rig, "TA", resbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || resbuf[0] != 'A') { return -RIG_EPROTO; } sscanf(resbuf + 1, "%d", &att); val->f = priv->threshold = (float)att / 120; break; case RIG_LEVEL_IF: retval = racal_transaction(rig, "TB", resbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || resbuf[0] != 'B') { return -RIG_EPROTO; } sscanf(resbuf + 1, "%lf", &f); val->i = priv->bfo = (shortfreq_t)(f * kHz(1)); break; case RIG_LEVEL_AGC: retval = racal_transaction(rig, "TM", resbuf, &len); if (retval < RIG_OK) { return retval; } if (len < 2 || resbuf[0] != 'M') { return -RIG_EPROTO; } switch (resbuf[1] - '0') { case 1: case 5: val->i = RIG_AGC_FAST; break; case 2: case 6: val->i = RIG_AGC_MEDIUM; break; case 3: case 7: val->i = RIG_AGC_SLOW; break; case 4: val->i = RIG_AGC_USER; break; default: return -RIG_EINVAL; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int racal_reset(RIG *rig, reset_t reset) { /* Initiate BITE routine, takes 1 minute! */ return racal_transaction(rig, "S3", NULL, NULL); } const char *racal_get_info(RIG *rig) { static char infobuf[64]; char bitebuf[BUFSZ]; char filterbuf[BUFSZ]; int res_len, retval; /* get BITE results */ retval = racal_transaction(rig, "S6", bitebuf, &res_len); if (retval < 0) { return "IO error"; } if (bitebuf[1] == 'O' && bitebuf[2] == 'K') { bitebuf[3] = '\0'; } else { char *p = strstr(bitebuf, "END"); if (p) { *p = '\0'; } } /* get filters */ retval = racal_transaction(rig, "S5", filterbuf, &res_len); if (retval < 0) { strcpy(filterbuf, "IO error"); } SNPRINTF(infobuf, sizeof(infobuf), "BITE errors: %s, Filters: %s\n", bitebuf + 1, filterbuf); return infobuf; } /* * initrigs_racal is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(racal) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ra6790_caps); rig_register(&ra3702_caps); return RIG_OK; } hamlib-4.6.2/rigs/racal/ra37xx.c0000644000175000017500000004474714752216205013252 00000000000000/* * Hamlib Racal backend - RA37XX main file * Copyright (c) 2004-2010 by Stephane Fillod * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "ra37xx.h" const struct confparams ra37xx_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID, -1 to disable addressing", "-1", RIG_CONF_NUMERIC, { .n = { -1, 9, 1 } } }, { RIG_CONF_END, NULL, } }; /* packet framing, 5-8 */ #define BUFSZ 256 #define SOM "\x0a" /* LF */ #define EOM "\x0d" /* CR */ /* * modes */ #define MD_USB 1 #define MD_LSB 2 #define MD_AM 3 #define MD_FM 4 #define MD_CW 5 #define MD_FSK 6 /* option */ #define MD_ISB_USB 7 #define MD_ISB_LSB 8 #define MD_FSK_NAR 13 /* option */ #define MD_FSK_MED 14 /* option */ #define MD_FSK_WID 15 /* option */ /* * retries are handled by ra37xx_transaction() */ static int ra37xx_one_transaction(RIG *rig, const char *cmd, char *data, int *data_len) { const struct ra37xx_priv_data *priv = (struct ra37xx_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); char cmdbuf[BUFSZ]; char respbuf[BUFSZ]; int retval; int pkt_header_len; struct timeval tv; gettimeofday(&tv, NULL); /* Packet Framing: - no Link Control Character - (optional) 1 Address Character - no Check Character */ if (priv->receiver_id != -1) { pkt_header_len = 2; SNPRINTF(cmdbuf, sizeof(cmdbuf), SOM "%d%s" EOM, priv->receiver_id, cmd); } else { pkt_header_len = 1; SNPRINTF(cmdbuf, sizeof(cmdbuf), SOM "%s" EOM, cmd); } rig_flush(rp); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { return retval; } /* forward COMMAND frame? no data expected */ if (!data || !data_len) { return retval; } do { retval = read_string(rp, (unsigned char *) respbuf, BUFSZ, EOM, strlen(EOM), 0, 1); if (retval < 0) { return retval; } /* drop short/invalid packets */ if (retval <= pkt_header_len + 1 || respbuf[0] != '\x0a') { if (!rig_check_cache_timeout(&tv, rp->timeout)) { continue; } else { return -RIG_EPROTO; } } /* drop other receiver id, and "pause" (empty) packets */ if ((priv->receiver_id != -1 && (respbuf[1] - '0') != priv->receiver_id)) { if (!rig_check_cache_timeout(&tv, rp->timeout)) { continue; } else { return -RIG_ETIMEOUT; } } if (retval >= pkt_header_len + 3 && !memcmp(respbuf + pkt_header_len, "ERR", 3)) { return -RIG_ERJCTED; } if (retval >= pkt_header_len + 5 && !memcmp(respbuf + pkt_header_len, "FAULT", 5)) { return -RIG_ERJCTED; } if (cmd[0] == 'Q' && (retval + pkt_header_len + 1 < strlen(cmd) || cmd[1] != respbuf[pkt_header_len])) { rig_debug(RIG_DEBUG_WARN, "%s: unexpected revertive frame\n", __func__); if (!rig_check_cache_timeout(&tv, rp->timeout)) { continue; } else { return -RIG_ETIMEOUT; } } } while (retval < 0); /* Strip starting LF and ending CR */ memcpy(data, respbuf + pkt_header_len, retval - pkt_header_len - 1); *data_len = retval; return RIG_OK; } static int ra37xx_transaction(RIG *rig, const char *cmd, char *data, int *data_len) { int retval, retry; retry = RIGPORT(rig)->retry; do { retval = ra37xx_one_transaction(rig, cmd, data, data_len); if (retval == RIG_OK) { break; } } while (retry-- > 0); return retval; } int ra37xx_init(RIG *rig) { struct ra37xx_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ra37xx_priv_data *)calloc(1, sizeof( struct ra37xx_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->receiver_id = -1; return RIG_OK; } /* */ int ra37xx_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int ra37xx_set_conf2(RIG *rig, hamlib_token_t token, const char *val, int val_len) { struct ra37xx_priv_data *priv = (struct ra37xx_priv_data *)STATE(rig)->priv; int receiver_id; switch (token) { case TOK_RIGID: receiver_id = atoi(val); if (receiver_id < -1 || receiver_id > 9) { return -RIG_EINVAL; } priv->receiver_id = receiver_id; break; default: return -RIG_EINVAL; } return RIG_OK; } int ra37xx_set_conf(RIG *rig, hamlib_token_t token, const char *val) { return ra37xx_set_conf2(rig, token, val, 128); } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int ra37xx_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct ra37xx_priv_data *priv = (struct ra37xx_priv_data *) STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%d", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int ra37xx_get_conf(RIG *rig, hamlib_token_t token, char *val) { return ra37xx_get_conf2(rig, token, val, 128); } /* * ra37xx_open * Assumes rig!=NULL */ int ra37xx_open(RIG *rig) { /* Set Receiver to remote control */ return ra37xx_transaction(rig, "REM1", NULL, NULL); } /* * ra37xx_close * Assumes rig!=NULL */ int ra37xx_close(RIG *rig) { /* Set Receiver to local control */ return ra37xx_transaction(rig, "REM0", NULL, NULL); } /* * ra37xx_set_freq * Assumes rig!=NULL */ int ra37xx_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; SNPRINTF(freqbuf, sizeof(freqbuf), "F%lu", (unsigned long)freq); return ra37xx_transaction(rig, freqbuf, NULL, NULL); } int ra37xx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[BUFSZ]; int retval, len; double f; retval = ra37xx_transaction(rig, "QF", freqbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(freqbuf + 1, "%lf", &f); *freq = (freq_t)f; return RIG_OK; } /* * ra37xx_set_mode * Assumes rig!=NULL */ int ra37xx_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { //struct ra37xx_priv_data *priv = (struct ra37xx_priv_data*)STATE(rig)->priv; int ra_mode, widthtype, widthnum = 0; char buf[BUFSZ]; switch (mode) { case RIG_MODE_CW: widthtype = 1; ra_mode = MD_CW; break; case RIG_MODE_CWR: widthtype = 2; ra_mode = MD_CW; break; case RIG_MODE_USB: widthtype = 1; ra_mode = MD_USB; break; case RIG_MODE_LSB: widthtype = 2; ra_mode = MD_LSB; break; case RIG_MODE_AM: widthtype = 3; ra_mode = MD_AM; break; case RIG_MODE_FM: widthtype = 3; ra_mode = MD_FM; break; case RIG_MODE_RTTY: widthtype = 3; ra_mode = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } if (width == RIG_PASSBAND_NORMAL) { rig_passband_normal(rig, mode); } rig_debug(RIG_DEBUG_TRACE, "%s: widthtype = %i, widthnum = %i not implemented\n", __func__, widthtype, widthnum); #ifdef XXREMOVEDXX widthtype = 0; /* FIXME: no bandwidth for now */ widthnum = 0; /* width set using 'B', QBCON must be queried firsthand */ #endif #ifdef XXREMOVEDXX SNPRINTF(buf, sizeof(buf), "M%d;B%d,%d", ra_mode, widthtype, widthnum); #else SNPRINTF(buf, sizeof(buf), "M%d", ra_mode); #endif return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[BUFSZ], resbuf[BUFSZ]; int retval, len, ra_mode, widthtype, widthnum; retval = ra37xx_transaction(rig, "QM", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 1, "%d", &ra_mode); switch (ra_mode) { case MD_CW: widthtype = 1; *mode = RIG_MODE_CW; break; case MD_ISB_LSB: case MD_LSB: widthtype = 2; *mode = RIG_MODE_LSB; break; case MD_ISB_USB: case MD_USB: widthtype = 1; *mode = RIG_MODE_USB; break; case MD_FSK_NAR: case MD_FSK_MED: case MD_FSK_WID: case MD_FSK: widthtype = 3; *mode = RIG_MODE_RTTY; break; case MD_FM: widthtype = 3; *mode = RIG_MODE_FM; break; case MD_AM: widthtype = 3; *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(*mode)); return -RIG_EPROTO; } retval = ra37xx_transaction(rig, "QB", resbuf, &len); if (retval != RIG_OK) { return retval; } /* FIXME */ widthnum = 0; SNPRINTF(buf, sizeof(buf), "QBCON%d,%d", widthtype, widthnum); retval = ra37xx_transaction(rig, buf, resbuf, &len); if (retval != RIG_OK) { return retval; } /* TODO: width */ *width = 0; return RIG_OK; } int ra37xx_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[BUFSZ]; switch (func) { case RIG_FUNC_MUTE: SNPRINTF(cmdbuf, sizeof(cmdbuf), "MUTE%d", status ? 1 : 0); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return ra37xx_transaction(rig, cmdbuf, NULL, NULL); } int ra37xx_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char resbuf[BUFSZ]; int retval, len, i; switch (func) { case RIG_FUNC_MUTE: retval = ra37xx_transaction(rig, "QMUTE", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 4, "%d", &i); *status = i == 0 ? 0 : 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } /* * ra37xx_set_level * Assumes rig!=NULL */ int ra37xx_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmdbuf[BUFSZ]; int agc; switch (level) { case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "AFL%d", (int)(val.f * 255)); break; case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "RFAMP%d", val.i ? 1 : 0); break; case RIG_LEVEL_CWPITCH: /* BFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "BFO%d", val.i); break; case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "CORL%d", (int)(val.f * 255)); break; case RIG_LEVEL_RF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "G%d", (int)(val.f * 255)); break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_FAST: agc = 0; break; case RIG_AGC_MEDIUM: agc = 1; break; case RIG_AGC_SLOW: agc = 2; break; case RIG_AGC_USER: agc = 0; break; default: return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "AGC%d,%d", val.i == RIG_AGC_USER ? 1 : 0, agc); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return ra37xx_transaction(rig, cmdbuf, NULL, NULL); } /* * ra37xx_get_level * Assumes rig!=NULL */ int ra37xx_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char resbuf[BUFSZ]; int retval, len, i; switch (level) { case RIG_LEVEL_AF: retval = ra37xx_transaction(rig, "QAFL", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 3, "%d", &i); val->f = ((float)i) / 255; break; case RIG_LEVEL_CWPITCH: retval = ra37xx_transaction(rig, "QBFO", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 3, "%d", &val->i); break; case RIG_LEVEL_PREAMP: retval = ra37xx_transaction(rig, "QRFAMP", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 5, "%d", &i); val->i = i ? STATE(rig)->preamp[0] : 0; break; case RIG_LEVEL_RAWSTR: retval = ra37xx_transaction(rig, "QRFL", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 3, "%d", &val->i); break; case RIG_LEVEL_SQL: retval = ra37xx_transaction(rig, "QCORL", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 4, "%d", &i); val->f = ((float)i) / 255; break; case RIG_LEVEL_RF: retval = ra37xx_transaction(rig, "QG", resbuf, &len); if (retval != RIG_OK) { return retval; } sscanf(resbuf + 1, "%d", &i); val->f = ((float)i) / 255; break; case RIG_LEVEL_AGC: retval = ra37xx_transaction(rig, "QAGC", resbuf, &len); if (retval != RIG_OK) { return retval; } if (resbuf[3] != '0') { val->i = RIG_AGC_USER; break; } switch (resbuf[5]) { case '0': val->i = RIG_AGC_FAST; break; case '1': val->i = RIG_AGC_MEDIUM; break; case '2': val->i = RIG_AGC_SLOW; break; default: return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } const char *ra37xx_get_info(RIG *rig) { static char infobuf[BUFSZ]; int res_len, retval; retval = ra37xx_transaction(rig, "QID", infobuf, &res_len); if (retval != RIG_OK || res_len < 2 || res_len >= BUFSZ) { return NULL; } infobuf[res_len] = '\0'; /* TODO: "QSW"? c.f. 5-43 */ /* skip "ID" */ return infobuf + 2; } int ra37xx_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char buf[BUFSZ]; int i_ant; switch (ant) { case RIG_ANT_1: i_ant = 1 << 0; break; case RIG_ANT_2: i_ant = 1 << 1; break; case RIG_ANT_3: i_ant = 1 << 2; break; case RIG_ANT_4: i_ant = 1 << 3; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported ant %#x", ant); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "ANT%d", i_ant); return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char buf[BUFSZ]; int retval, buflen, ra_ant; retval = ra37xx_transaction(rig, "QANT", buf, &buflen); if (retval != RIG_OK) { return retval; } sscanf(buf + 3, "%d", &ra_ant); if (ra_ant < 0 || ra_ant > 15) { return -RIG_EPROTO; } *ant_curr = ((ra_ant & (1 << 0)) ? RIG_ANT_1 : 0) | ((ra_ant & (1 << 1)) ? RIG_ANT_2 : 0) | ((ra_ant & (1 << 2)) ? RIG_ANT_3 : 0) | ((ra_ant & (1 << 3)) ? RIG_ANT_4 : 0); return RIG_OK; } int ra37xx_set_mem(RIG *rig, vfo_t vfo, int ch) { char buf[BUFSZ]; /* NB: does a RIG_OP_TO_VFO!*/ SNPRINTF(buf, sizeof(buf), "CHAN%d", ch); return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_get_mem(RIG *rig, vfo_t vfo, int *ch) { char buf[BUFSZ]; int retval, buflen; retval = ra37xx_transaction(rig, "QCHAN", buf, &buflen); if (retval != RIG_OK) { return retval; } *ch = atoi(buf + 4); return RIG_OK; } int ra37xx_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { char buf[BUFSZ]; int scantype; switch (scan) { case RIG_SCAN_STOP: scantype = 0; break; case RIG_SCAN_VFO: scantype = 1; break; case RIG_SCAN_MEM: scantype = 2; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported scan %#x", scan); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "SCAN%d,0", scantype); return ra37xx_transaction(rig, buf, NULL, NULL); } int ra37xx_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char buf[BUFSZ]; int ret, ch; switch (op) { case RIG_OP_FROM_VFO: ret = rig_get_mem(rig, vfo, &ch); if (ret < 0) { return ret; } SNPRINTF(buf, sizeof(buf), "STRE%d", ch); return ra37xx_transaction(rig, buf, NULL, NULL); case RIG_OP_TO_VFO: ret = rig_get_mem(rig, vfo, &ch); if (ret < 0) { return ret; } SNPRINTF(buf, sizeof(buf), "CHAN%d", ch); return ra37xx_transaction(rig, buf, NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported op %#x", op); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.2/rigs/racal/ra6790.c0000644000175000017500000000752714752216205013041 00000000000000/* * Hamlib Racal backend - RA6790 description * Copyright (c) 2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "racal.h" /* FIXME: ISB */ #define RA6790_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AMS|RIG_MODE_FM) #define RA6790_FUNC (RIG_FUNC_NONE) #define RA6790_LEVEL_ALL (RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_IF) #define RA6790_PARM_ALL (RIG_PARM_NONE) #define RA6790_VFO (RIG_VFO_A) /* * ra6790 rig capabilities. * * Required A6A1 serial asynchronous interface * */ struct rig_caps ra6790_caps = { RIG_MODEL(RIG_MODEL_RA6790), .model_name = "RA6790/GM", .mfg_name = "Racal", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 9600, .serial_data_bits = 7, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 10, .timeout = 2000, .retry = 3, .has_get_func = RA6790_FUNC, .has_set_func = RA6790_FUNC, .has_get_level = RA6790_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(RA6790_LEVEL_ALL), .has_get_parm = RA6790_PARM_ALL, .has_set_parm = RIG_PARM_SET(RA6790_PARM_ALL), .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(8), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30) - 1, RA6790_MODES, -1, -1, RA6790_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30) - 1, RA6790_MODES, -1, -1, RA6790_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RA6790_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* at -3dB */ {RIG_MODE_SSB, kHz(2.55)}, /* BW2 */ {RA6790_MODES, Hz(300)}, /* BW1 */ {RA6790_MODES, kHz(1)}, /* BW2 */ {RA6790_MODES, kHz(3.2)}, /* BW3 */ {RA6790_MODES, kHz(6)}, /* BW4 */ {RA6790_MODES, kHz(20)}, /* BW5 */ {RA6790_MODES, 0}, /* accept any BW */ RIG_FLT_END, }, .cfgparams = racal_cfg_params, .rig_init = racal_init, .rig_cleanup = racal_cleanup, .rig_open = racal_open, .rig_close = racal_close, .set_conf = racal_set_conf, .get_conf = racal_get_conf, .set_freq = racal_set_freq, .get_freq = racal_get_freq, .set_mode = racal_set_mode, .get_mode = racal_get_mode, .set_level = racal_set_level, .get_level = racal_get_level, .reset = racal_reset, .get_info = racal_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/racal/ra3702.c0000644000175000017500000001101014752216205013005 00000000000000/* * Hamlib Racal backend - RA3702 description * Copyright (c) 2010 by Stephane Fillod * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "ra37xx.h" /* TODO: ISB */ #define RA3702_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define RA3702_FUNC (RIG_FUNC_MUTE) #define RA3702_LEVEL_ALL (RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_CWPITCH|RIG_LEVEL_PREAMP|RIG_LEVEL_SQL|RIG_LEVEL_RAWSTR) #define RA3702_PARM_ALL (RIG_PARM_NONE) #define RA3702_VFO (RIG_VFO_A) #define RA3702_VFO_OPS (RIG_OP_FROM_VFO|RIG_OP_TO_VFO) #define RA3702_SCAN_OPS (RIG_SCAN_STOP|RIG_SCAN_VFO|RIG_SCAN_MEM) /* * ra3702 rig capabilities. * * Required A6A1 serial asynchronous interface * */ struct rig_caps ra3702_caps = { RIG_MODEL(RIG_MODEL_RA3702), .model_name = "RA3702", .mfg_name = "Racal", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 50, .serial_rate_max = 9600, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = RA37XX_TIMEOUT, .retry = 2, .has_get_func = RA3702_FUNC, .has_set_func = RA3702_FUNC, .has_get_level = RA3702_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(RA3702_LEVEL_ALL), .has_get_parm = RA3702_PARM_ALL, .has_set_parm = RIG_PARM_SET(RA3702_PARM_ALL), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .vfo_ops = RA3702_VFO_OPS, .scan_ops = RA3702_SCAN_OPS, .preamp = { 20, RIG_DBLST_END }, /* FIXME */ .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = RA37XX_STR_CAL, .chan_list = { { 0, 99, RIG_MTYPE_MEM, RA37XX_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(15), MHz(30) - 1, RA3702_MODES, -1, -1, RA3702_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(15), MHz(30) - 1, RA3702_MODES, -1, -1, RA3702_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RA3702_MODES, 1}, {RA3702_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* at -3dB */ {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.7)}, {RA3702_MODES, kHz(12)}, {RA3702_MODES, kHz(6)}, {RA3702_MODES, Hz(300)}, {RA3702_MODES, kHz(1)}, {RA3702_MODES, kHz(2.7)}, //{RA3702_MODES, 0}, /* accept any BW */ RIG_FLT_END, }, .cfgparams = ra37xx_cfg_params, .rig_init = ra37xx_init, .rig_cleanup = ra37xx_cleanup, .rig_open = ra37xx_open, .rig_close = ra37xx_close, .set_conf = ra37xx_set_conf, .get_conf = ra37xx_get_conf, .set_freq = ra37xx_set_freq, .get_freq = ra37xx_get_freq, .set_mode = ra37xx_set_mode, .get_mode = ra37xx_get_mode, .set_func = ra37xx_set_func, .get_func = ra37xx_get_func, .set_level = ra37xx_set_level, .get_level = ra37xx_get_level, .set_ant = ra37xx_set_ant, .get_ant = ra37xx_get_ant, .set_mem = ra37xx_set_mem, .get_mem = ra37xx_get_mem, .scan = ra37xx_scan, .vfo_op = ra37xx_vfo_op, .get_info = ra37xx_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kit/0000755000175000017500000000000014752216243011521 500000000000000hamlib-4.6.2/rigs/kit/dwt.c0000644000175000017500000004472614752216205012416 00000000000000/* * Hamlib KIT backend - Digital World Traveller DRM receiver description * Copyright (c) 2005-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #define BACKEND_VER "20200112" /* * Compile only this model if libusb is available * or if .DLL is available under Windows */ #ifdef _WIN32 #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif #include /* * Coding Technologies Digital World Traveller DRM tuner. * * TODO: rig_scan, set/get FM mode (mono/stereo), * get antenna mode (loop/wire), * get low intermediate frequency (LIF) which may vary up to +-667 Hz * and may be additionally increased of up to 2000 Hz */ #define DWTDLL "afgusbfe.dll" /* Some type definitions needed for dll access */ typedef enum _tFrontendMode { eFrontendModeUndefined = 0, eFrontendModeDrm = 1, eFrontendModeAm = 2, eFrontendModeFm = 6, } tFrontendMode; typedef short (__stdcall *FNCFrontendOpen)(void); typedef short (__stdcall *FNCFrontendClose)(void); typedef short (__stdcall *FNCFrontendGetId)(char *id); typedef short (__stdcall *FNCFrontendSetMode)(tFrontendMode mode); typedef tFrontendMode(__stdcall *FNCFrontendGetMode)(void); typedef short (__stdcall *FNCFrontendSetFrequency)(double freq); typedef double (__stdcall *FNCFrontendGetFrequency)(void); typedef short (__stdcall *FNCFrontendGetRfLevel)(void); typedef double (__stdcall *FNCFrontendGetLIF)(void); typedef short (__stdcall *FNCFrontendStartScan)(short ScanMode, double WindowStartFreq, double WindowEndFreq, double DeltaFreq, double StepSize); typedef short (__stdcall *FNCFrontendStopScan)(void); typedef short (__stdcall *FNCFrontendGetScanStatus)(void); typedef short (__stdcall *FNCFrontendSetRfAttenuator)(short n); typedef short (__stdcall *FNCFrontendGetRfAttenuator)(void); typedef short (__stdcall *FNCFrontendSetAntennaMode)(short n); typedef short (__stdcall *FNCFrontendGetAntennaMode)(void); typedef short (__stdcall *FNCFrontendSetFmMode)(short n); typedef short (__stdcall *FNCFrontendGetFmMode)(void); struct dwtdll_priv_data { HMODULE dll; FNCFrontendOpen FrontendOpen; FNCFrontendClose FrontendClose; FNCFrontendGetId FrontendGetId; FNCFrontendSetMode FrontendSetMode; FNCFrontendGetMode FrontendGetMode; FNCFrontendSetFrequency FrontendSetFrequency; FNCFrontendGetFrequency FrontendGetFrequency; FNCFrontendGetRfLevel FrontendGetRfLevel; FNCFrontendGetLIF FrontendGetLIF; FNCFrontendStartScan FrontendStartScan; FNCFrontendStopScan FrontendStopScan; FNCFrontendGetScanStatus FrontendGetScanStatus; FNCFrontendSetRfAttenuator FrontendSetRfAttenuator; FNCFrontendGetRfAttenuator FrontendGetRfAttenuator; FNCFrontendSetAntennaMode FrontendSetAntennaMode; FNCFrontendGetAntennaMode FrontendGetAntennaMode; FNCFrontendSetFmMode FrontendSetFmMode; FNCFrontendGetFmMode FrontendGetFmMode; }; #define DWT_MODES (RIG_MODE_AM|RIG_MODE_USB) /* USB is for DRM */ #define DWT_FUNC (RIG_FUNC_NONE) #define DWT_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_STRENGTH|RIG_LEVEL_RAWSTR) #define DWT_PARM_ALL (RIG_PARM_NONE) #define DWT_VFO (RIG_VFO_A) #define DWT_ANT (RIG_ANT_1) static int dwtdll_init(RIG *rig); static int dwtdll_cleanup(RIG *rig); static int dwtdll_open(RIG *rig); static int dwtdll_close(RIG *rig); static int dwtdll_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int dwtdll_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int dwtdll_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int dwtdll_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int dwtdll_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int dwtdll_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *dwtdll_get_info(RIG *rig); /* * Coding Technologies Digital World Traveller DRM tuner. * * The receiver is controlled via USB, through a Windows DLL. * * see Winradio G303 as an example */ struct rig_caps dwt_caps = { RIG_MODEL(RIG_MODEL_DWT), .model_name = "Digital World Traveller", .mfg_name = "Coding Technologies", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_PCRECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DWT_FUNC, .has_set_func = DWT_FUNC, .has_get_level = DWT_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DWT_LEVEL_ALL), .has_get_parm = DWT_PARM_ALL, .has_set_parm = RIG_PARM_SET(DWT_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 20, RIG_DBLST_END, }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO, DWT_ANT}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO, DWT_ANT}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO, DWT_ANT}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO, DWT_ANT}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DWT_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_USB, kHz(22)}, /* FIXME */ {RIG_MODE_AM, kHz(9)}, /* FIXME */ {RIG_MODE_WFM, kHz(230)}, /* FIXME */ RIG_FLT_END, }, .rig_init = dwtdll_init, .rig_cleanup = dwtdll_cleanup, .rig_open = dwtdll_open, .rig_close = dwtdll_close, .set_freq = dwtdll_set_freq, .get_freq = dwtdll_get_freq, .set_mode = dwtdll_set_mode, .get_mode = dwtdll_get_mode, .set_level = dwtdll_set_level, .get_level = dwtdll_get_level, .get_info = dwtdll_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int dwtdll_init(RIG *rig) { struct dwtdll_priv_data *priv; STATE(rig)->priv = (struct dwtdll_priv_data *)calloc(1, sizeof( struct dwtdll_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* Try to load required dll */ priv->dll = LoadLibrary(DWTDLL); if (!priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, DWTDLL); free(STATE(rig)->priv); return -RIG_EIO; /* huh! */ } /* Get process addresses from dll for function access */ priv->FrontendOpen = (FNCFrontendOpen) GetProcAddress(priv->dll, "FrontendOpen"); priv->FrontendClose = (FNCFrontendClose) GetProcAddress(priv->dll, "FrontendClose"); priv->FrontendGetId = (FNCFrontendGetId) GetProcAddress(priv->dll, "FrontendGetId"); priv->FrontendSetMode = (FNCFrontendSetMode) GetProcAddress(priv->dll, "FrontendSetMode"); priv->FrontendGetMode = (FNCFrontendGetMode) GetProcAddress(priv->dll, "FrontendGetMode"); priv->FrontendSetFrequency = (FNCFrontendSetFrequency) GetProcAddress(priv->dll, "FrontendSetFrequency"); priv->FrontendGetFrequency = (FNCFrontendGetFrequency) GetProcAddress(priv->dll, "FrontendGetFrequency"); priv->FrontendGetRfLevel = (FNCFrontendGetRfLevel) GetProcAddress(priv->dll, "FrontendGetRfLevel"); priv->FrontendGetLIF = (FNCFrontendGetLIF) GetProcAddress(priv->dll, "FrontendGetLIF"); priv->FrontendStartScan = (FNCFrontendStartScan) GetProcAddress(priv->dll, "FrontendStartScan"); priv->FrontendStopScan = (FNCFrontendStopScan) GetProcAddress(priv->dll, "FrontendStopScan"); priv->FrontendGetScanStatus = (FNCFrontendGetScanStatus) GetProcAddress(priv->dll, "FrontendGetScanStatus"); priv->FrontendSetRfAttenuator = (FNCFrontendSetRfAttenuator) GetProcAddress(priv->dll, "FrontendSetRfAttenuator"); priv->FrontendGetRfAttenuator = (FNCFrontendGetRfAttenuator) GetProcAddress(priv->dll, "FrontendGetRfAttenuator"); priv->FrontendSetAntennaMode = (FNCFrontendSetAntennaMode) GetProcAddress(priv->dll, "FrontendSetAntennaMode"); priv->FrontendGetAntennaMode = (FNCFrontendGetAntennaMode) GetProcAddress(priv->dll, "FrontendGetAntennaMode"); priv->FrontendSetFmMode = (FNCFrontendSetFmMode) GetProcAddress(priv->dll, "FrontendSetFmMode"); priv->FrontendGetFmMode = (FNCFrontendGetFmMode) GetProcAddress(priv->dll, "FrontendGetFmMode"); return RIG_OK; } int dwtdll_open(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret; /* Open DWT receiver */ ret = priv->FrontendOpen(); if (ret < 0) { return -RIG_EIO; /* huh! */ } /* default to DRM mode */ ret = priv->FrontendSetMode(eFrontendModeDrm); if (ret < 0) { return -RIG_EIO; /* huh! */ } return RIG_OK; } int dwtdll_close(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret; /* Open DWT receiver */ ret = priv->FrontendClose(); if (ret < 0) { return -RIG_EIO; /* huh! */ } return RIG_OK; } int dwtdll_cleanup(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; /* Clean up the dll access */ if (priv) { FreeLibrary(priv->dll); } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int dwtdll_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret; ret = priv->FrontendSetFrequency((double) freq); return ret < 0 ? -RIG_EIO : RIG_OK; } int dwtdll_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; *freq = (freq_t) priv->FrontendGetFrequency(); return RIG_OK; } int dwtdll_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; tFrontendMode dwtmode; short ret; switch (mode) { case RIG_MODE_USB: dwtmode = eFrontendModeDrm; break; case RIG_MODE_AM: dwtmode = eFrontendModeAm; break; case RIG_MODE_WFM: dwtmode = eFrontendModeFm; break; default: return -RIG_EINVAL; } ret = priv->FrontendSetMode(dwtmode); return ret < 0 ? -RIG_EIO : RIG_OK; } int dwtdll_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; tFrontendMode dwtmode; dwtmode = priv->FrontendGetMode(); switch (dwtmode) { case eFrontendModeDrm: *mode = RIG_MODE_USB; break; case eFrontendModeAm: *mode = RIG_MODE_AM; break; case eFrontendModeFm: *mode = RIG_MODE_WFM; break; default: return -RIG_EPROTO; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } int dwtdll_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; short ret = 0; switch (level) { case RIG_LEVEL_ATT: ret = priv->FrontendSetRfAttenuator(val.i ? 1 : 0); break; default: return -RIG_EINVAL; } return ret < 0 ? -RIG_EIO : RIG_OK; } int dwtdll_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; signed short ret = 0; switch (level) { case RIG_LEVEL_ATT: ret = priv->FrontendGetRfAttenuator(); if (ret < 0) { break; } /* local vs. DX mode */ val->i = ret ? 0 : rig->caps->attenuator[0]; break; case RIG_LEVEL_STRENGTH: /* actual RMS signal strength in dBuV */ ret = priv->FrontendGetRfLevel(); if (ret < 0) { break; } /* return actual RMS signal strength in dBuV, -34 to get dB rel S9 */ val->i = ret - 34; break; case RIG_LEVEL_RAWSTR: /* actual RMS signal strength in dBuV */ ret = priv->FrontendGetRfLevel(); if (ret < 0) { break; } val->i = ret; break; default: return -RIG_EINVAL; } return ret < 0 ? -RIG_EIO : RIG_OK; } static const char *dwtdll_get_info(RIG *rig) { struct dwtdll_priv_data *priv = (struct dwtdll_priv_data *)STATE(rig)->priv; static char info[22]; if (priv->FrontendGetId(info) < 0) { return NULL; } info[21] = '\0'; return info; } #elif defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #include "token.h" #define USB_VID_CT 0x1539 /* AFG Engineering */ #define USB_PID_CT_DWT 0x1730 /* Digital World Traveller */ #define DWT_MODES (RIG_MODE_NONE) #define DWT_FUNC (RIG_FUNC_NONE) #define DWT_LEVEL_ALL (RIG_LEVEL_NONE) #define DWT_PARM_ALL (RIG_PARM_NONE) #define DWT_VFO (RIG_VFO_A) static int dwt_init(RIG *rig); static int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static const char *dwt_get_info(RIG *rig); /* * Coding Technologies Digital World Traveller DRM tuner. * * The receiver is controlled via USB. * * see dsbr100.c as an example */ struct rig_caps dwt_caps = { RIG_MODEL(RIG_MODEL_DWT), .model_name = "Digital World Traveller", .mfg_name = "Coding Technologies", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DWT_FUNC, .has_set_func = DWT_FUNC, .has_get_level = DWT_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DWT_LEVEL_ALL), .has_get_parm = DWT_PARM_ALL, .has_set_parm = RIG_PARM_SET(DWT_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30) - kHz(1), DWT_MODES, -1, -1, DWT_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, DWT_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DWT_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_USB, kHz(22)}, /* FIXME */ {RIG_MODE_AM, kHz(9)}, /* FIXME */ {RIG_MODE_WFM, kHz(230)}, /* FIXME */ RIG_FLT_END, }, .rig_init = dwt_init, .set_freq = dwt_set_freq, .get_info = dwt_get_info, }; int dwt_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); rp->parm.usb.vid = USB_VID_CT; rp->parm.usb.pid = USB_PID_CT_DWT; rp->parm.usb.conf = 1; rp->parm.usb.iface = 0; rp->parm.usb.alt = 0; return RIG_OK; } #define MSG_LEN 16 int dwt_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { libusb_device_handle *udh = RIGPORT(rig)->handle; int request, value, index; unsigned char buf[MSG_LEN] = { 0x4a, 0x00, 0x03, 0x00, 0xff, 0xff, 0x32 }; int requesttype, r; int ifreq = (int)(freq / 1000); /* FIXME */ requesttype = 0x00; request = 0x00; value = 0x00; index = 0x00; buf[8] = ifreq & 0xff; buf[7] = (ifreq >> 8) & 0xff; r = libusb_control_transfer(udh, requesttype, request, value, index, buf, 9, 1000); if (r < 0) { rig_debug(RIG_DEBUG_ERR, "libusb_control_transfer failed: %s\n", libusb_error_name(r)); return -RIG_EIO; } return RIG_OK; } /* Rem: not reentrant */ const char *dwt_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "Dev %04d", desc.bcdDevice); return buf; } #endif /* HAVE_LIBUSB */ hamlib-4.6.2/rigs/kit/elektor507.c0000644000175000017500000010636014752216205013512 00000000000000/* * Hamlib KIT backend - Elektor SDR USB (5/07) receiver description * Copyright (c) 2007-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "token.h" #ifdef _WIN32 #define USE_FTDI_DLL #elif defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #define USE_LIBUSB #endif /* * Compile this model only if libusb is available * or if .DLL is available under Windows */ #if defined(USE_FTDI_DLL) || defined(USE_LIBUSB) static int elektor507_init(RIG *rig); static int elektor507_cleanup(RIG *rig); static int elektor507_open(RIG *rig); static int elektor507_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int elektor507_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int elektor507_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int elektor507_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int elektor507_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); static int elektor507_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); static int elektor507_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int elektor507_get_conf(RIG *rig, hamlib_token_t token, char *val); static const char *elektor507_get_info(RIG *rig); /* * I2C addresses */ #define CY_I2C_RAM_ADR 210 #define CY_I2C_EEPROM_ADR 208 /* * I2C registers */ #define CLKOE_REG 0x09 #define DIV1_REG 0x0c #define DIV2_REG 0x47 #define XTALCTL_REG 0x12 #define CAPLOAD_REG 0x13 #define PUMPCOUNTERS_REG 0x40 #define CLKSRC_REG 0x44 static int cy_update_pll(RIG *rig, unsigned char IICadr); static int i2c_write_regs(RIG *rig, unsigned char IICadr, int reg_count, unsigned char reg_adr, unsigned char reg_val1, unsigned char reg_val2, unsigned char reg_val3); #define i2c_write_reg(rig, IICadr, reg_adr, reg_val) \ i2c_write_regs(rig, IICadr, 1, reg_adr, reg_val, 0, 0) #ifdef USE_FTDI_DLL #ifdef HAVE_WINDOWS_H #include #endif #ifdef HAVE_WINBASE_H #include #endif #include #define ELEKTOR507_DLL "FTD2XX.dll" /* Some type definitions needed for dll access */ typedef enum { FT_OK = 0, FT_INVALID_HANDLE = 1, FT_DEVICE_NOT_FOUND = 2, FT_DEVICE_NOT_OPENED = 3, FT_IO_ERROR = 4, FT_INSUFFICIENT_RESOURCES = 5, FT_INVALID_PARAMETER = 6, FT_SUCCESS = FT_OK, FT_INVALID_BAUD_RATE = 7, FT_DEVICE_NOT_OPENED_FOR_ERASE = 8, FT_DEVICE_NOT_OPENED_FOR_WRITE = 9, FT_FAILED_TO_WRITE_DEVICE = 10, FT_EEPROM_READ_FAILED = 11, FT_EEPROM_WRITE_FAILED = 12, FT_EEPROM_ERASE_FAILED = 13, FT_EEPROM_NOT_PRESENT = 14, FT_EEPROM_NOT_PROGRAMMED = 15, FT_INVALID_ARGS = 16, FT_OTHER_ERROR = 17, } FT_Result; typedef FT_Result(__stdcall *FNCFT_Open)(int Index, unsigned long *ftHandle); typedef FT_Result(__stdcall *FNCFT_Close)(unsigned long ftHandle); typedef FT_Result(__stdcall *FNCFT_SetBitMode)(unsigned long ftHandle, unsigned char Mask, unsigned char Enable); typedef FT_Result(__stdcall *FNCFT_SetBaudRate)(unsigned long ftHandle, unsigned long BaudRate); typedef FT_Result(__stdcall *FNCFT_Write)(unsigned long ftHandle, void *FTOutBuf, unsigned long BufferSize, int *ResultPtr); struct elektor507_extra_priv_data { HMODULE dll; FNCFT_Open FT_Open; FNCFT_Close FT_Close; FNCFT_SetBitMode FT_SetBitMode; FNCFT_SetBaudRate FT_SetBaudRate; FNCFT_Write FT_Write; unsigned long ftHandle; }; #elif defined(USE_LIBUSB) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #define USB_VID_FTDI 0x0403 /* Future Technology Devices International */ #define USB_PID_FTDI_FT232 0x6001 /* FT232R 8-bit FIFO */ #define FTDI_IN_EP 0x02 #define FTDI_USB_WRITE_TIMEOUT 5000 struct elektor507_extra_priv_data { /* empty with libusb */ }; #endif /* defaults */ #define OSCFREQ 10000 /* kHz unit -> MHz(10) */ #define XTAL_CAL 128 #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_XTALCAL TOKEN_BACKEND(2) static const struct confparams elektor507_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency in Hz", "10000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(30), 1 } } }, { TOK_XTALCAL, "xtal_cal", "Xtal Cal", "Crystal calibration", "132", RIG_CONF_NUMERIC, { .n = { 0, 255, 1 } } }, { RIG_CONF_END, NULL, } }; /* * Common data struct */ struct elektor507_priv_data { struct elektor507_extra_priv_data extra_priv; unsigned xtal_cal; /* 0..255 (-150ppm..150ppm) */ unsigned osc_freq; /* kHz */ #define ANT_AUTO RIG_ANT_1 #define ANT_EXT RIG_ANT_2 #define ANT_TEST_CLK RIG_ANT_3 ant_t ant; /* current antenna */ /* CY PLL stuff. * This is Qtotal & Ptotal values here. */ int P, Q, Div1N; /* FTDI comm stuff */ unsigned char FT_port; int Buf_adr; #define FT_OUT_BUFFER_MAX 1024 unsigned char FT_Out_Buffer[FT_OUT_BUFFER_MAX]; }; #ifdef USE_FTDI_DLL int elektor507_init(RIG *rig) { struct elektor507_priv_data *priv; struct elektor507_extra_priv_data *extra_priv; priv = (struct elektor507_priv_data *)calloc(sizeof(struct elektor507_priv_data), 1); if (!priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv->xtal_cal = XTAL_CAL; priv->osc_freq = OSCFREQ; priv->ant = ANT_AUTO; /* DIV1N set to safe default */ priv->Div1N = 8; priv->P = 8; priv->Q = 2; extra_priv = &priv->extra_priv; /* Try to load required dll */ extra_priv->dll = LoadLibrary(ELEKTOR507_DLL); if (!extra_priv->dll) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to LoadLibrary %s\n", __func__, ELEKTOR507_DLL); free(priv); return -RIG_EIO; /* huh! */ } /* * Get process addresses from dll for function access */ /* Open_USB_Device */ extra_priv->FT_Open = (FNCFT_Open) GetProcAddress(extra_priv->dll, "FT_Open"); /* Close_USB_Device */ extra_priv->FT_Close = (FNCFT_Close) GetProcAddress(extra_priv->dll, "FT_Close"); /* Set_USB_Device_BitMode */ extra_priv->FT_SetBitMode = (FNCFT_SetBitMode) GetProcAddress(extra_priv->dll, "FT_SetBitMode"); /* Set_USB_Device_BaudRate */ extra_priv->FT_SetBaudRate = (FNCFT_SetBaudRate) GetProcAddress(extra_priv->dll, "FT_SetBaudRate"); /* Write_USB_Device_Buffer */ extra_priv->FT_Write = (FNCFT_Write) GetProcAddress(extra_priv->dll, "FT_Write"); STATE(rig)->priv = (void *)priv; return RIG_OK; } int elektor507_ftdi_write_data(RIG *rig, void *FTOutBuf, unsigned long BufferSize) { struct elektor507_extra_priv_data *extra_priv = &((struct elektor507_priv_data *)STATE(rig)->priv)->extra_priv; FT_Result ret; int Result; rig_debug(RIG_DEBUG_TRACE, "%s called, %d bytes\n", __func__, (int)BufferSize); /* Open FTDI */ ret = extra_priv->FT_Open(0, &extra_priv->ftHandle); if (ret != FT_OK) { return -RIG_EIO; } ret = extra_priv->FT_SetBitMode(extra_priv->ftHandle, 0xff, 1); if (ret != FT_OK) { return -RIG_EIO; } ret = extra_priv->FT_SetBaudRate(extra_priv->ftHandle, 38400); if (ret != FT_OK) { return -RIG_EIO; } ret = extra_priv->FT_Write(extra_priv->ftHandle, FTOutBuf, BufferSize, &Result); if (ret != FT_OK) { rig_debug(RIG_DEBUG_ERR, "FT_Write failed: %d, Result: %d\n", ret, Result); return -RIG_EIO; } ret = extra_priv->FT_Close(extra_priv->ftHandle); if (ret != FT_OK) { return -RIG_EIO; } return RIG_OK; } int elektor507_cleanup(RIG *rig) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; /* Clean up the dll access */ if (priv) { FreeLibrary(priv->extra_priv.dll); } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } const char *elektor507_get_info(RIG *rig) { static char buf[64]; SNPRINTF(buf, sizeof(buf), "Elektor SDR USB w/ FTDI DLL"); return buf; } #elif defined(USE_LIBUSB) /* * The libusb code is inspired by libftdi: * http://www.intra2net.com/de/produkte/opensource/ftdi/ */ int elektor507_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct elektor507_priv_data *priv; STATE(rig)->priv = (struct elektor507_priv_data *)calloc(sizeof(struct elektor507_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->xtal_cal = XTAL_CAL; priv->osc_freq = OSCFREQ; priv->ant = ANT_AUTO; /* DIV1N set to safe default */ priv->Div1N = 8; priv->P = 8; priv->Q = 2; rp->parm.usb.vid = USB_VID_FTDI; rp->parm.usb.pid = USB_PID_FTDI_FT232; rp->parm.usb.conf = 1; rp->parm.usb.iface = 0; rp->parm.usb.alt = 0; /* necessary ? */ return RIG_OK; } int elektor507_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* Rem: not reentrant */ const char *elektor507_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "USB dev %04d", desc.bcdDevice); return buf; } int elektor507_libusb_setup(RIG *rig) { libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned short index = 0, usb_val; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* Reset the ftdi device */ #if 1 ret = libusb_control_transfer(udh, 0x40, 0, 0, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer reset failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } #endif /* * Enable bitbang mode */ usb_val = 0xff; /* low byte: bitmask */ usb_val |= (0x01 << 8); /* Basic bitbang_mode: 0x01 */ ret = libusb_control_transfer(udh, 0x40, 0x0B, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer bitbangmode failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } /* * Set baudrate * 9600 x4 because of bitbang mode */ usb_val = 49230; /* magic value for 38400 bauds */ index = 0; ret = libusb_control_transfer(udh, 0x40, 3, usb_val, index, NULL, 0, FTDI_USB_WRITE_TIMEOUT); if (ret != 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer baudrate failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } int elektor507_ftdi_write_data(RIG *rig, void *FTOutBuf, unsigned long BufferSize) { libusb_device_handle *udh = RIGPORT(rig)->handle; int ret, actual_length; rig_debug(RIG_DEBUG_TRACE, "%s called, %lu bytes\n", __func__, BufferSize); ret = libusb_bulk_transfer(udh, FTDI_IN_EP, FTOutBuf, BufferSize, &actual_length, FTDI_USB_WRITE_TIMEOUT); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "usb_bulk_write failed: %s\n", libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } #endif /* USE_LIBUSB */ #define ELEKTOR507_MODES (RIG_MODE_USB) /* USB is for SDR */ #define ELEKTOR507_FUNC (RIG_FUNC_NONE) #define ELEKTOR507_LEVEL_ALL (RIG_LEVEL_ATT) #define ELEKTOR507_PARM_ALL (RIG_PARM_NONE) #define ELEKTOR507_VFO (RIG_VFO_A) /* * - Auto-filter antenna (K3) * - External antenna (PC1) * - Internal TEST_CLK (5 MHz) */ #define ELEKTOR507_ANT (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) /* * Elektor SDR USB (5/07) receiver description * * This kit is a QSD based on a CY27EE16ZE PLL. * The receiver is controlled via USB (through FTDI FT232R). * * Original article: * http://www.elektor.com/magazines/2007/may/software-defined-radio.91527.lynkx * * Author (Burkhard Kainka) page, in german: * http://www.b-kainka.de/sdrusb.html */ struct rig_caps elektor507_caps = { RIG_MODEL(RIG_MODEL_ELEKTOR507), .model_name = "Elektor SDR-USB", .mfg_name = "Elektor", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, #ifdef USE_LIBUSB .port_type = RIG_PORT_USB, #else .port_type = RIG_PORT_NONE, #endif .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = ELEKTOR507_FUNC, .has_set_func = ELEKTOR507_FUNC, .has_get_level = ELEKTOR507_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ELEKTOR507_LEVEL_ALL), .has_get_parm = ELEKTOR507_PARM_ALL, .has_set_parm = RIG_PARM_SET(ELEKTOR507_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 10, 20, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(30) - kHz(1), ELEKTOR507_MODES, -1, -1, ELEKTOR507_VFO, ELEKTOR507_ANT}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(30) - kHz(1), ELEKTOR507_MODES, -1, -1, ELEKTOR507_VFO, ELEKTOR507_ANT}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ELEKTOR507_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_USB, kHz(24)}, /* bandpass may be more */ RIG_FLT_END, }, .cfgparams = elektor507_cfg_params, .rig_init = elektor507_init, .rig_cleanup = elektor507_cleanup, .rig_open = elektor507_open, .set_conf = elektor507_set_conf, .get_conf = elektor507_get_conf, .set_freq = elektor507_set_freq, .get_freq = elektor507_get_freq, .set_level = elektor507_set_level, .get_level = elektor507_get_level, .set_ant = elektor507_set_ant, .get_ant = elektor507_get_ant, .get_info = elektor507_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int elektor507_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct elektor507_priv_data *priv; freq_t freq; priv = (struct elektor507_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &freq); priv->osc_freq = freq / kHz(1); break; case TOK_XTALCAL: sscanf(val, "%u", &priv->xtal_cal); break; default: return -RIG_EINVAL; } return RIG_OK; } int elektor507_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct elektor507_priv_data *priv; priv = (struct elektor507_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq * kHz(1)); break; case TOK_XTALCAL: SNPRINTF(val, val_len, "%u", priv->xtal_cal); break; default: return -RIG_EINVAL; } return RIG_OK; } int elektor507_get_conf(RIG *rig, hamlib_token_t token, char *val) { return elektor507_get_conf2(rig, token, val, 128); } int elektor507_open(RIG *rig) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * Setup the FT232R. */ #ifdef USE_LIBUSB ret = elektor507_libusb_setup(rig); if (ret != RIG_OK) { return ret; } #endif /* Init the FT232R port to SCL/SDA high, Mux A0, Att 0 */ priv->FT_port = 0x03; /* * Setup the CY27EE16ZE PLL. */ /* Enable only CLOCK5. CLOCK3 will be on demand in set_ant() */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, CLKOE_REG, 0x20); if (ret != 0) { return ret; } /* DIV1N set to safe default */ priv->Div1N = 8; ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, DIV1_REG, priv->Div1N); if (ret != 0) { return ret; } #if 0 /* Xtal gain setting */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, XTALCTL_REG, 0x32); if (ret != 0) { return ret; } /* CapLoad set to middle */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, CAPLOAD_REG, priv->xtal_cal); if (ret != 0) { return ret; } #endif /* CLKSRC: CLOCK3=DIV2CLK/2, CLOCK5=DIV1CLK/DIV1N */ ret = i2c_write_regs(rig, CY_I2C_RAM_ADR, 3, CLKSRC_REG, 0x02, 0x8e, 0x47); if (ret != 0) { return ret; } /* DIV2SRC from REF */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, DIV2_REG, 0x88); if (ret != 0) { return ret; } return RIG_OK; } #define FREQ_ALGORITHM 3 /* use AC6SL version 3-Aug-2010 */ #if FREQ_ALGORITHM == 1 /* this used to be ORIG_ALGORITHM */ static void find_P_Q_DIV1N(struct elektor507_priv_data *priv, freq_t freq) { int Freq; double Min, VCO; int p, q, q_max; Freq = freq / kHz(1); if (Freq > 19 && Freq < 60) { priv->Div1N = (2500 + Freq / 2) / Freq + 128; priv->P = 1000; priv->Q = 40; return; } else if (Freq > 59 && Freq < 801) { priv->Div1N = 125; priv->P = Freq * 2; priv->Q = 40; return; } else if (Freq > 800 && Freq < 2001) { priv->Div1N = 50; priv->P = Freq; priv->Q = 50; return; } else if (Freq > 2000 && Freq < 4001) { priv->Div1N = 25; } else if (Freq > 4000 && Freq < 10001) { priv->Div1N = 10; } else if (Freq > 10000 && Freq < 20001) { priv->Div1N = 5; } else if (Freq > 20000 && Freq < 30001) { priv->Div1N = 4; } Min = priv->osc_freq; freq /= kHz(1); /* * Q:2..129 * P:8..2055, best 16..1023 (because of Pump) For stable operation: + REF/Qtotal must not fall below 250kHz ( + P*(REF/Qtotal) must not be above 400 MHz or below 100 MHz */ #if 1 q_max = priv->osc_freq / 250; #else q_max = 100; #endif for (q = q_max; q >= 10; q--) { for (p = 500; p <= 2000; p++) { VCO = ((double)priv->osc_freq / q) * p; if (fabs(4 * freq - VCO / priv->Div1N) < Min) { Min = fabs(4 * freq - VCO / priv->Div1N); priv->Q = q; priv->P = p; } } } VCO = ((double)priv->osc_freq / priv->Q) * priv->P; if (VCO < 100e3 || VCO > 400e3) rig_debug(RIG_DEBUG_VERBOSE, "%s: Unstable parameters for VCO=%.1f\n", __func__, VCO); } #endif /* ORIG_ALGORITHM */ #if FREQ_ALGORITHM == 2 /* this used to be default alternative to ORIG_ALGORITHM */ static void find_P_Q_DIV1N(struct elektor507_priv_data *priv, freq_t freq) { double Min, VCO, freq4; int div1n_min, div1n_max; int p, q, div1n, q_max; Min = priv->osc_freq; freq4 = freq * 4 / kHz(1); #define vco_min 100e3 #define vco_max 500e3 /* * Q:2..129 * P:8..2055, best 16..1023 (because of Pump) For stable operation: + REF/Qtotal must not fall below 250kHz ( + P*(REF/Qtotal) must not be above 400 MHz or below 100 MHz */ #if 1 q_max = priv->osc_freq / 250; #else q_max = 100; #endif div1n_min = vco_min / freq4; if (div1n_min < 2) { div1n_min = 2; } else if (div1n_min > 127) { div1n_min = 127; } div1n_max = vco_max / freq4; if (div1n_max > 127) { div1n_max = 127; } else if (div1n_max < 2) { div1n_max = 2; } for (div1n = div1n_min; div1n <= div1n_max; div1n++) { // P/Qtotal = FREQ4*DIV1N/REF // (Q*int(r) + frac(r)*Q)/Q for (q = q_max; q >= 2; q--) { p = q * freq4 * div1n / priv->osc_freq; #if 1 if (p < 16 || p > 1023) { continue; } #endif VCO = ((double)priv->osc_freq / q) * p; #if 1 if (VCO < vco_min || VCO > vco_max) { continue; } #endif if (fabs(freq4 - VCO / div1n) < Min) { Min = fabs(freq4 - VCO / div1n); priv->Div1N = div1n; priv->Q = q; priv->P = p; } } } VCO = ((double)priv->osc_freq / priv->Q) * priv->P; if (VCO < vco_min || VCO > 400e3) rig_debug(RIG_DEBUG_VERBOSE, "%s: Unstable parameters for VCO=%.1f\n", __func__, VCO); } #endif /* default alternative to ORIG_ALGORITHM */ #if FREQ_ALGORITHM == 3 /* AC6SL version 5-Aug-2010 */ /* search valid (P,Q,N) for closest match to requested frequency */ static void find_P_Q_DIV1N( struct elektor507_priv_data *priv, freq_t freq) { #define VCO_MIN 100000000 #define VCO_MAX 400000000 int Ptotal; int Qtotal, Qmax = 40; int Div1N; double PmulREFdivQ; double Ref = priv->osc_freq * 1000.0; double freq4 = freq * 4; double newdelta, delta = fabs((priv->P * (Ref / priv->Q) / priv->Div1N) - freq4); /* For stable operation: Ref/Qtotal must not fall below 250kHz */ /* Qmax = (int) ( Ref / 250000); */ for (Qtotal = 2; Qtotal <= Qmax; Qtotal++) { double REFdivQ = (Ref / Qtotal); /* For stable operation: Ptotal*(Ref/Qtotal) must be ... */ int Pmin = (int)(VCO_MIN / REFdivQ); /* ... >= 100mHz */ int Pmax = (int)(VCO_MAX / REFdivQ); /* ... <= 400mHz */ for (Ptotal = Pmin; Ptotal <= Pmax; Ptotal++) { PmulREFdivQ = Ptotal * REFdivQ; Div1N = (int)((PmulREFdivQ + freq4 / 2) / freq4); if (Div1N < 2) { Div1N = 2; } if (Div1N > 127) { Div1N = 127; } newdelta = fabs((PmulREFdivQ / Div1N) - freq4); if (newdelta < delta) { /* save best (P,Q,N) */ delta = newdelta; priv->P = Ptotal; priv->Q = Qtotal; priv->Div1N = Div1N; } } } } #endif /* AC6SL version 5-Aug-2010 */ int elektor507_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; freq_t final_freq; int ret = 0; if (priv->ant == ANT_AUTO) { int Mux; /* Automatically select appropriate filter */ if (freq <= kHz(1600)) { /* Select A1, low pass, fc=1.6MHz */ Mux = 1; } else { /* Select A2, high pass */ Mux = 2; } priv->FT_port &= 0x63; //0,1 = I2C, 2,3,4=MUX, 5,6=Attenuator priv->FT_port |= Mux << 2; } find_P_Q_DIV1N(priv, freq); /* Compute PLL parameters */ elektor507_get_freq(rig, vfo, &final_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s: Freq=%.0f kHz, delta=%d Hz, Div1N=%d, P=%d, Q=%d, FREQ_ALGORITHM=%d\n", __func__, freq / kHz(1), (int)(final_freq - freq), priv->Div1N, priv->P, priv->Q, FREQ_ALGORITHM); if ((double)priv->osc_freq / priv->Q < 250) rig_debug(RIG_DEBUG_WARN, "%s: Unstable parameters for REF/Qtotal=%.1f\n", __func__, (double)priv->osc_freq / priv->Q); ret = cy_update_pll(rig, CY_I2C_RAM_ADR); return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; double VCO; VCO = ((double)priv->osc_freq * kHz(1)) / priv->Q * priv->P; /* Div by 4 because of QSD */ *freq = (VCO / priv->Div1N) / 4; return RIG_OK; } int elektor507_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret = 0; int att = 0; switch (level) { case RIG_LEVEL_ATT: /* val.i */ /* FTDI: DSR, DCD */ switch (val.i) { case 0: att = 0; break; case 10: att = 1; break; case 20: att = 2; break; default: return -RIG_EINVAL; } priv->FT_port &= 0x1f; priv->FT_port |= (att & 0x3) << 5; ret = elektor507_ftdi_write_data(rig, &priv->FT_port, 1); break; default: return -RIG_EINVAL; } return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { const struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret = 0; switch (level) { case RIG_LEVEL_ATT: switch ((priv->FT_port >> 5) & 3) { case 0: val->i = 0; break; case 1: val->i = 10; break; case 2: val->i = 20; break; default: ret = -RIG_EINVAL; } break; default: return -RIG_EINVAL; } return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret, Mux; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * FTDI: RTS, CTS, DTR * * A4,A5,A6 are not connected * * ANT1->A1/A2, ANT2->A3, ANT3->A7 */ switch (ant) { case RIG_ANT_1: Mux = 0; break; /* Mux will be updated upon next set_freq */ case RIG_ANT_2: Mux = 3; break; /* ANT_EXT */ case RIG_ANT_3: Mux = 7; break; /* ANT_TEST_CLK */ default: return -RIG_EINVAL; } priv->ant = ant; priv->FT_port &= 0x63; //0,1 = I2C, 2,3,4=MUX, 5,6=Attenuator priv->FT_port |= Mux << 2; #if 0 ret = elektor507_ftdi_write_data(rig, &priv->FT_port, 1); #else /* Enable CLOCK3 on demand */ ret = i2c_write_reg(rig, CY_I2C_RAM_ADR, CLKOE_REG, 0x20 | (ant == RIG_ANT_3 ? 0x04 : 0)); #endif return (ret != 0) ? -RIG_EIO : RIG_OK; } int elektor507_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { const struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; *ant_curr = priv->ant; return RIG_OK; } /* * Update the PLL counters */ static int cy_update_pll(RIG *rig, unsigned char IICadr) { const struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int P0, R40, R41, R42; unsigned char Div1N; unsigned char Clk3_src; int Pump; int ret; /* * PLL Pump setting according to table 9 */ if (priv->P < 45) { Pump = 0; } else if (priv->P < 480) { Pump = 1; } else if (priv->P < 640) { Pump = 2; } else if (priv->P < 800) { Pump = 3; } else { Pump = 4; } P0 = priv->P & 0x01; R40 = (((priv->P >> 1) - 4) >> 8) | (Pump << 2) | 0xc0; R41 = ((priv->P >> 1) - 4) & 0xff; R42 = (priv->Q - 2) | (P0 << 7); ret = i2c_write_regs(rig, IICadr, 3, PUMPCOUNTERS_REG, R40, R41, R42); if (ret != 0) { return ret; } switch (priv->Div1N) { case 2: /* Fixed /2 divider option */ Clk3_src = 0x80; Div1N = 8; break; case 3: /* Fixed /3 divider option */ Clk3_src = 0xc0; Div1N = 6; break; default: Div1N = priv->Div1N; Clk3_src = 0x40; } ret = i2c_write_reg(rig, IICadr, DIV1_REG, Div1N); if (ret != 0) { return ret; } /* Set 2 low bits of CLKSRC for CLOCK5. DIV1CLK is set already */ ret = i2c_write_reg(rig, IICadr, CLKSRC_REG + 2, Clk3_src | 0x07); if (ret != 0) { return ret; } return RIG_OK; } static void ftdi_SCL(RIG *rig, int d) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; if (priv->Buf_adr >= FT_OUT_BUFFER_MAX) { return; } /* * FTDI RXD->SCL */ if (d == 0) { priv->FT_port &= ~0x02; } else { priv->FT_port |= 0x02; } priv->FT_Out_Buffer[priv->Buf_adr++] = priv->FT_port; } static void ftdi_SDA(RIG *rig, int d) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; if (priv->Buf_adr >= FT_OUT_BUFFER_MAX) { return; } /* * FTDI TXD->SDA */ if (d == 0) { priv->FT_port &= ~0x01; } else { priv->FT_port |= 0x01; } priv->FT_Out_Buffer[priv->Buf_adr++] = priv->FT_port; } static void ftdi_I2C_Init(RIG *rig) { ftdi_SCL(rig, 1); ftdi_SDA(rig, 1); /* SCL=1, SDA=1 */ } static void ftdi_I2C_Start(RIG *rig) { ftdi_SDA(rig, 0); /* SDA=0 */ ftdi_SCL(rig, 0); /* SCL=0 */ } static void ftdi_I2C_Stop(RIG *rig) { ftdi_SCL(rig, 0); ftdi_SDA(rig, 0); /* SCL=0, SDA=0 */ ftdi_SCL(rig, 1); /* SCL=1 */ ftdi_SDA(rig, 1); /* SDA=1 */ } /* Acknowledge: SCL=0, SDA=0 SCL=1 SCL=0 No Acknowledge: SCL=0, SDA=1 SCL=1 SCL=0 */ static void ftdi_I2C_Write_Byte(RIG *rig, unsigned char c) { int i; for (i = 7; i >= 0; i--) { ftdi_SDA(rig, c & (1 << i)); /* SDA value */ ftdi_SCL(rig, 1); ftdi_SCL(rig, 0); } ftdi_SDA(rig, 1); ftdi_SCL(rig, 1); ftdi_SCL(rig, 0); } int i2c_write_regs(RIG *rig, unsigned char IICadr, int reg_count, unsigned char reg_adr, unsigned char reg_val1, unsigned char reg_val2, unsigned char reg_val3) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret; /* Start with a new buffer */ priv->Buf_adr = 0; ftdi_I2C_Init(rig); ftdi_I2C_Start(rig); ftdi_I2C_Write_Byte(rig, IICadr); ftdi_I2C_Write_Byte(rig, reg_adr); if (reg_count >= 1) { ftdi_I2C_Write_Byte(rig, reg_val1); } if (reg_count >= 2) { ftdi_I2C_Write_Byte(rig, reg_val2); } if (reg_count >= 3) { ftdi_I2C_Write_Byte(rig, reg_val3); } ftdi_I2C_Stop(rig); //usleep(10000); ret = elektor507_ftdi_write_data(rig, priv->FT_Out_Buffer, priv->Buf_adr); if (ret != 0) { return -RIG_EIO; } return 0; } #if 0 static const unsigned char ftdi_code[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x34, 0x08, 0x5a, 0x24/*0x6f*/, 0x00, 0x14, 0x0a, 0x00, 0x08, 0x88, 0x50, 0x04, 0x32, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x2b, 0x17, 0x00, 0xfe, 0xfe, 0x7f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32, 0x10, 0x32 }; int load_ftdi_code(RIG *rig, unsigned char IICadr, const unsigned char code[]) { struct elektor507_priv_data *priv = (struct elektor507_priv_data *) STATE(rig)->priv; int ret; int i, j; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0; i < 16; i++) { /* Start with a new buffer */ priv->Buf_adr = 0; ftdi_I2C_Init(rig); ftdi_I2C_Start(rig); ftdi_I2C_Write_Byte(rig, IICadr); ftdi_I2C_Write_Byte(rig, i * 16); for (j = 0; j < 16; j++) { ftdi_I2C_Write_Byte(rig, code[i * 16 + j]); } ftdi_I2C_Stop(rig); ret = elektor507_ftdi_write_data(rig, priv->FT_Out_Buffer, priv->Buf_adr); if (ret != 0) { return -RIG_EIO; } } return RIG_OK; } #endif #endif /* defined(USE_FTDI_DLL) || defined(USE_LIBUSB) */ hamlib-4.6.2/rigs/kit/Makefile.am0000644000175000017500000000175414752216205013502 00000000000000AM_CFLAGS += $(LIBUSB_CFLAGS) # FIXME: compile usrp only if CXX available KITSRC = elektor304.c drt1.c dwt.c usrp.c elektor507.c dds60.c miniVNA.c \ si570avrusb.c si570avrusb.h funcube.c funcube.h fifisdr.c hiqsdr.c \ kit.c kit.h usrp_impl.h rs_hfiq.c if HAVE_USRP # Append to the already defined AM_CXXFLAGS that exists outside the conditional. AM_CXXFLAGS += $(USRP_CFLAGS) KITSRC += usrp_impl.cc libhamlib_kit_la_LINK = $(CXXLINK) $(libhamlib_kit_la_LDFLAGS) else # automake gets confused and invokes the C++ linker via libtool regardless # of whether or not HAVE_USRP enables the .cc source. This override forces # automake to invoke the C linker as no C++ is involved: libhamlib_kit_la_LINK = $(LINK) $(libhamlib_kit_la_LDFLAGS) endif KITROTSRC = pcrotor.c noinst_LTLIBRARIES = libhamlib-kit.la libhamlib_kit_la_SOURCES = $(KITSRC) $(KITROTSRC) libhamlib_kit_la_LIBADD = $(USRP_LIBS) $(LIBUSB_LIBS) $(MATH_LIBS) EXTRA_DIST = README.funcubedongle Android.mk hamlib-4.6.2/rigs/kit/Makefile.in0000644000175000017500000006647014752216216013523 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_USRP_TRUE@am__append_1 = $(USRP_CFLAGS) @HAVE_USRP_TRUE@am__append_2 = usrp_impl.cc subdir = rigs/kit ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = libhamlib_kit_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__libhamlib_kit_la_SOURCES_DIST = elektor304.c drt1.c dwt.c usrp.c \ elektor507.c dds60.c miniVNA.c si570avrusb.c si570avrusb.h \ funcube.c funcube.h fifisdr.c hiqsdr.c kit.c kit.h usrp_impl.h \ rs_hfiq.c usrp_impl.cc pcrotor.c @HAVE_USRP_TRUE@am__objects_1 = usrp_impl.lo am__objects_2 = elektor304.lo drt1.lo dwt.lo usrp.lo elektor507.lo \ dds60.lo miniVNA.lo si570avrusb.lo funcube.lo fifisdr.lo \ hiqsdr.lo kit.lo rs_hfiq.lo $(am__objects_1) am__objects_3 = pcrotor.lo am_libhamlib_kit_la_OBJECTS = $(am__objects_2) $(am__objects_3) libhamlib_kit_la_OBJECTS = $(am_libhamlib_kit_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/dds60.Plo ./$(DEPDIR)/drt1.Plo \ ./$(DEPDIR)/dwt.Plo ./$(DEPDIR)/elektor304.Plo \ ./$(DEPDIR)/elektor507.Plo ./$(DEPDIR)/fifisdr.Plo \ ./$(DEPDIR)/funcube.Plo ./$(DEPDIR)/hiqsdr.Plo \ ./$(DEPDIR)/kit.Plo ./$(DEPDIR)/miniVNA.Plo \ ./$(DEPDIR)/pcrotor.Plo ./$(DEPDIR)/rs_hfiq.Plo \ ./$(DEPDIR)/si570avrusb.Plo ./$(DEPDIR)/usrp.Plo \ ./$(DEPDIR)/usrp_impl.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = SOURCES = $(libhamlib_kit_la_SOURCES) DIST_SOURCES = $(am__libhamlib_kit_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ $(LIBUSB_CFLAGS) AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ $(am__append_1) AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # FIXME: compile usrp only if CXX available KITSRC = elektor304.c drt1.c dwt.c usrp.c elektor507.c dds60.c \ miniVNA.c si570avrusb.c si570avrusb.h funcube.c funcube.h \ fifisdr.c hiqsdr.c kit.c kit.h usrp_impl.h rs_hfiq.c \ $(am__append_2) @HAVE_USRP_FALSE@libhamlib_kit_la_LINK = $(LINK) $(libhamlib_kit_la_LDFLAGS) @HAVE_USRP_TRUE@libhamlib_kit_la_LINK = $(CXXLINK) $(libhamlib_kit_la_LDFLAGS) KITROTSRC = pcrotor.c noinst_LTLIBRARIES = libhamlib-kit.la libhamlib_kit_la_SOURCES = $(KITSRC) $(KITROTSRC) libhamlib_kit_la_LIBADD = $(USRP_LIBS) $(LIBUSB_LIBS) $(MATH_LIBS) EXTRA_DIST = README.funcubedongle Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .cc .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/kit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/kit/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-kit.la: $(libhamlib_kit_la_OBJECTS) $(libhamlib_kit_la_DEPENDENCIES) $(EXTRA_libhamlib_kit_la_DEPENDENCIES) $(AM_V_GEN)$(libhamlib_kit_la_LINK) $(libhamlib_kit_la_OBJECTS) $(libhamlib_kit_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dds60.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drt1.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elektor304.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elektor507.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fifisdr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/funcube.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hiqsdr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kit.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miniVNA.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcrotor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rs_hfiq.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/si570avrusb.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usrp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usrp_impl.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/dds60.Plo -rm -f ./$(DEPDIR)/drt1.Plo -rm -f ./$(DEPDIR)/dwt.Plo -rm -f ./$(DEPDIR)/elektor304.Plo -rm -f ./$(DEPDIR)/elektor507.Plo -rm -f ./$(DEPDIR)/fifisdr.Plo -rm -f ./$(DEPDIR)/funcube.Plo -rm -f ./$(DEPDIR)/hiqsdr.Plo -rm -f ./$(DEPDIR)/kit.Plo -rm -f ./$(DEPDIR)/miniVNA.Plo -rm -f ./$(DEPDIR)/pcrotor.Plo -rm -f ./$(DEPDIR)/rs_hfiq.Plo -rm -f ./$(DEPDIR)/si570avrusb.Plo -rm -f ./$(DEPDIR)/usrp.Plo -rm -f ./$(DEPDIR)/usrp_impl.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/dds60.Plo -rm -f ./$(DEPDIR)/drt1.Plo -rm -f ./$(DEPDIR)/dwt.Plo -rm -f ./$(DEPDIR)/elektor304.Plo -rm -f ./$(DEPDIR)/elektor507.Plo -rm -f ./$(DEPDIR)/fifisdr.Plo -rm -f ./$(DEPDIR)/funcube.Plo -rm -f ./$(DEPDIR)/hiqsdr.Plo -rm -f ./$(DEPDIR)/kit.Plo -rm -f ./$(DEPDIR)/miniVNA.Plo -rm -f ./$(DEPDIR)/pcrotor.Plo -rm -f ./$(DEPDIR)/rs_hfiq.Plo -rm -f ./$(DEPDIR)/si570avrusb.Plo -rm -f ./$(DEPDIR)/usrp.Plo -rm -f ./$(DEPDIR)/usrp_impl.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile @HAVE_USRP_TRUE@ # Append to the already defined AM_CXXFLAGS that exists outside the conditional. @HAVE_USRP_FALSE@ # automake gets confused and invokes the C++ linker via libtool regardless @HAVE_USRP_FALSE@ # of whether or not HAVE_USRP enables the .cc source. This override forces @HAVE_USRP_FALSE@ # automake to invoke the C linker as no C++ is involved: # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/kit/funcube.c0000644000175000017500000006422314752216205013241 00000000000000/* * Hamlib KIT backend - FUNcube Dongle USB tuner description * Copyright (c) 2009-2011 by Stephane Fillod * * Derived from usbsoftrock-0.5: * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * Author: Stefano Speretta, Innovative Solutions In Space BV * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "misc.h" #define BACKEND_VER "20210830" /* * Compile this model only if libusb is available */ #if defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #include "funcube.h" static int funcube_hid_cmd(RIG *rig, unsigned char *au8BufOut, unsigned char *au8BufIn, int inputSize); static int funcube_init(RIG *rig); static int funcubeplus_init(RIG *rig); static int funcube_cleanup(RIG *rig); static int funcube_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int funcube_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int funcube_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int funcube_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int funcubepro_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int funcubepro_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static const char *funcube_get_info(RIG *rig); static int funcube_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static const struct confparams funcube_cfg_params[] = { { RIG_CONF_END, NULL, } }; // functions used set / read frequency, working on FUNcube version 0 and 1 int set_freq_v0(libusb_device_handle *udh, unsigned int f, int timeout); int set_freq_v1(libusb_device_handle *udh, unsigned int f, int timeout); /* * Common data struct */ struct funcube_priv_data { freq_t freq; /* Hz */ }; /* * FUNcube Dongle description * * Based on Jan Axelson HID examples * http://www.lvr.com/ * */ struct rig_caps funcube_caps = { RIG_MODEL(RIG_MODEL_FUNCUBEDONGLE), .model_name = "FUNcube Dongle", .mfg_name = "AMSAT-UK", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_ATT | RIG_LEVEL_STRENGTH | RIG_LEVEL_PREAMP, .has_set_level = RIG_LEVEL_ATT | RIG_LEVEL_PREAMP, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 5, 10, 15, 20, 25, 30, RIG_DBLST_END, }, .attenuator = { 2, 5, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(50), MHz(2500), RIG_MODE_USB, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_USB, kHz(1)}, RIG_TS_END, }, .filters = { {RIG_MODE_USB, kHz(192)}, RIG_FLT_END, }, .cfgparams = funcube_cfg_params, .rig_init = funcube_init, .rig_cleanup = funcube_cleanup, .set_freq = funcube_set_freq, .get_freq = funcube_get_freq, .get_level = funcube_get_level, .set_level = funcube_set_level, .get_info = funcube_get_info, .get_mode = funcube_get_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps funcubeplus_caps = { RIG_MODEL(RIG_MODEL_FUNCUBEDONGLEPLUS), .model_name = "FUNcube Dongle Pro+", .mfg_name = "AMSAT-UK", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_PREAMP | RIG_LEVEL_RF, // RIG_LEVEL_PREAMP: 10dB=LNAon MixGainOff. 20dB=LNAoff, MixGainOn. 30dB=LNAOn, MixGainOn // RIG_LEVEL_RF 0..1 : IF gain 0 .. 59 dB .has_set_level = RIG_LEVEL_PREAMP | RIG_LEVEL_RF, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { 10, 20, 30, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(1900), RIG_MODE_IQ, -1, -1, RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_IQ, kHz(1)}, RIG_TS_END, }, .filters = { {RIG_MODE_IQ, kHz(192)}, RIG_FLT_END, }, .cfgparams = funcube_cfg_params, .rig_init = funcubeplus_init, .rig_cleanup = funcube_cleanup, .set_freq = funcube_set_freq, .get_freq = funcube_get_freq, .get_level = funcubepro_get_level, .set_level = funcubepro_set_level, .get_info = funcube_get_info, .get_mode = funcube_get_mode, }; int funcube_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct funcube_priv_data *priv; STATE(rig)->priv = (struct funcube_priv_data *)calloc(sizeof( struct funcube_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->freq = 0; rp->parm.usb.vid = VID; rp->parm.usb.pid = PID; rp->parm.usb.conf = FUNCUBE_CONFIGURATION; rp->parm.usb.iface = FUNCUBE_INTERFACE; rp->parm.usb.alt = FUNCUBE_ALTERNATIVE_SETTING; rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PRODUCT_NAME; return RIG_OK; } int funcubeplus_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct funcube_priv_data *priv; STATE(rig)->priv = (struct funcube_priv_data *)calloc(sizeof( struct funcube_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->freq = 0; rp->parm.usb.vid = VID; rp->parm.usb.pid = PIDPLUS; rp->parm.usb.conf = FUNCUBE_CONFIGURATION; rp->parm.usb.iface = FUNCUBE_INTERFACE; rp->parm.usb.alt = FUNCUBE_ALTERNATIVE_SETTING; rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PRODUCT_NAMEPLUS; return RIG_OK; } int funcube_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* Rem: not reentrant */ const char *funcube_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "Dev %04d", desc.bcdDevice); return buf; } int set_freq_v0(libusb_device_handle *udh, unsigned int f, int timeout) { int ret; int actual_length; unsigned char au8BufOut[64]; // endpoint size unsigned char au8BufIn[64]; // endpoint size // frequency is in Hz, while the dongle expects it in kHz f = f / 1000; au8BufOut[0] = REQUEST_SET_FREQ; // Command to Set Frequency on dongle au8BufOut[1] = (unsigned char)f; au8BufOut[2] = (unsigned char)(f >> 8); au8BufOut[3] = (unsigned char)(f >> 16); rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_SET_FREQ not supported\n", __func__); return -RIG_EIO; } return RIG_OK; } int set_freq_v1(libusb_device_handle *udh, unsigned int f, int timeout) { int ret; int actual_length; unsigned char au8BufOut[64]; // endpoint size unsigned char au8BufIn[64]; // endpoint size au8BufOut[0] = REQUEST_SET_FREQ_HZ; // Command to Set Frequency in Hz on dongle au8BufOut[1] = (unsigned char)f; au8BufOut[2] = (unsigned char)(f >> 8); au8BufOut[3] = (unsigned char)(f >> 16); au8BufOut[4] = (unsigned char)(f >> 24); rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF, au8BufOut[4] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x%02x%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF, au8BufIn[3] & 0xFF, au8BufIn[4] & 0xFF, au8BufIn[5] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_SET_FREQ_HZ not supported\n", __func__); return -RIG_EIO; } return RIG_OK; } int funcube_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct funcube_priv_data *priv = (struct funcube_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; if ((ret = set_freq_v1(udh, freq, rp->timeout)) != RIG_OK) { if ((ret = set_freq_v0(udh, freq, rp->timeout)) == RIG_OK) { priv->freq = freq; } } else { priv->freq = freq; } return ret; } int get_freq_v0(RIG *rig, vfo_t vfo, freq_t *freq) { const struct funcube_priv_data *priv = (struct funcube_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: frequency is not read from the device, the value shown is the last successfully set.\n", __func__); *freq = priv->freq; return RIG_OK; } int get_freq_v1(RIG *rig, vfo_t vfo, freq_t *freq) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; unsigned int f; int actual_length; unsigned char au8BufOut[64] = "\0\0\0\0"; // endpoint size unsigned char au8BufIn[64] = "\0\0\0\0"; // endpoint size au8BufOut[0] = REQUEST_GET_FREQ_HZ; // Command to Set Frequency on dongle rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rp->timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x%02x%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF, au8BufIn[3] & 0xFF, au8BufIn[4] & 0xFF, au8BufIn[5] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_GET_FREQ_HZ not supported\n", __func__); return -RIG_EIO; } f = (au8BufIn[2] & 0xFF) | ((au8BufIn[3] & 0xFF) << 8) | ((au8BufIn[4] & 0xFF) << 16) | ((au8BufIn[5] & 0xFF) << 24), *freq = f; return RIG_OK; } int funcube_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int ret; if ((ret = get_freq_v1(rig, vfo, freq)) != RIG_OK) { ret = get_freq_v0(rig, vfo, freq); } return ret; } int funcube_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; int actual_length; unsigned char au8BufOut[64] = "\0\0\0\0"; // endpoint size unsigned char au8BufIn[64] = "\0\0\0\0"; // endpoint size switch (level) { case RIG_LEVEL_PREAMP: au8BufOut[0] = REQUEST_SET_LNA_GAIN; // Command to Set LNA gain switch (val.i) { case 5: au8BufOut[1] = 6; break; case 10: au8BufOut[1] = 8; break; case 15: au8BufOut[1] = 10; break; case 20: au8BufOut[1] = 12; break; case 25: au8BufOut[1] = 13; break; case 30: au8BufOut[1] = 14; break; default: au8BufOut[1] = 4; } break; case RIG_LEVEL_ATT: au8BufOut[0] = REQUEST_SET_LNA_GAIN; // Command to Set LNA gain switch (val.i) { case 2: au8BufOut[1] = 1; break; case 5: au8BufOut[1] = 0; break; default: au8BufOut[1] = 4; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rp->timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_SET_LEVEL not supported\n", __func__); return -RIG_EIO; } return RIG_OK; } int funcube_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; int actual_length; unsigned char au8BufOut[64] = "\0\0\0\0"; // endpoint size unsigned char au8BufIn[64] = "\0\0\0\0"; // endpoint size switch (level) { case RIG_LEVEL_ATT: case RIG_LEVEL_PREAMP: au8BufOut[0] = REQUEST_GET_LNA_GAIN; // Command to Get LNA / ATT gain break; case RIG_LEVEL_STRENGTH: au8BufOut[0] = REQUEST_GET_RSSI; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, sizeof(au8BufIn), &actual_length, rp->timeout); if (ret < 0 || actual_length != sizeof(au8BufIn)) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF, au8BufIn[2] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: REQUEST_GET_LEVEL_x not supported\n", __func__); return -RIG_EIO; } switch (level) { case RIG_LEVEL_PREAMP: switch (au8BufIn[2]) { case 6: val->i = 5; break; case 8: val->i = 10; break; case 10: val->i = 15; break; case 12: val->i = 20; break; case 13: val->i = 25; break; case 14: val->i = 30; break; default: val->i = 0; } break; case RIG_LEVEL_ATT: switch (au8BufIn[2]) { case 0: val->i = 5; break; case 1: val->i = 2; break; default: val->i = 0; } break; case RIG_LEVEL_STRENGTH: val->i = (int)((float)au8BufIn[2] * 2.8 - 35); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int funcube_hid_cmd(RIG *rig, unsigned char *au8BufOut, unsigned char *au8BufIn, int inputSize) { hamlib_port_t *rp = RIGPORT(rig); libusb_device_handle *udh = rp->handle; int ret; int actual_length; rig_debug(RIG_DEBUG_TRACE, "%s: HID packet set to %02x%02x%02x%02x\n", __func__, au8BufOut[0] & 0xFF, au8BufOut[1] & 0xFF, au8BufOut[2] & 0xFF, au8BufOut[3] & 0xFF); ret = libusb_interrupt_transfer(udh, OUTPUT_ENDPOINT, au8BufOut, sizeof(au8BufOut), &actual_length, rp->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } ret = libusb_interrupt_transfer(udh, INPUT_ENDPOINT, au8BufIn, inputSize, &actual_length, rp->timeout); if (ret < 0 || actual_length != inputSize) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_interrupt_transfer failed (%d): %s\n", __func__, ret, libusb_error_name(ret)); } rig_debug(RIG_DEBUG_TRACE, "%s: Answer buf=%02x%02x\n", __func__, au8BufIn[0] & 0xFF, au8BufIn[1] & 0xFF); if (au8BufIn[1] != FUNCUBE_SUCCESS) { rig_debug(RIG_DEBUG_ERR, "%s: failed to perform FUNCube HID command %d.\n", __func__, au8BufOut[0]); return -RIG_EIO; } return RIG_OK; } int funcubepro_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret; unsigned char au8BufOut[64] = { 0 }; // endpoint size unsigned char au8BufIn[64] = { 0 }; // endpoint size switch (level) { case RIG_LEVEL_PREAMP: rig_debug(RIG_DEBUG_TRACE, "%s: Setting PREAMP state to %d.\n", __func__, val.i); au8BufOut[0] = REQUEST_SET_LNA_GAIN; // Command to set LNA gain if (val.i == 10 || val.i == 30) { au8BufOut[1] = 1; } else { au8BufOut[1] = 0; } ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); if (ret < 0) { return ret; } au8BufOut[0] = REQUEST_SET_MIXER_GAIN; // Set mixer gain if (val.i == 20 || val.i == 30) { au8BufOut[1] = 1; } else { au8BufOut[1] = 0; } return funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); case RIG_LEVEL_RF: au8BufOut[0] = REQUEST_SET_IF_GAIN; // Command to set IF gain au8BufOut[1] = (int)(val.f * 100) ; if (au8BufOut[1] > 59) { au8BufOut[1] = 59; } return funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } } int funcubepro_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; int gain_state; unsigned char au8BufOut[64] = { 0 }; // endpoint size unsigned char au8BufIn[64] = { 0 }; // endpoint size switch (level) { case RIG_LEVEL_PREAMP: au8BufOut[0] = REQUEST_GET_MIXER_GAIN; // Command to get mixer gain enabled ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s: Mixer gain state returned %d.\n", __func__, au8BufIn[2] & 0xFF); gain_state = au8BufIn[2] & 0x1; au8BufOut[0] = REQUEST_GET_LNA_GAIN; // Command to get LNA gain enabled ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s: LNA gain state returned %d.\n", __func__, au8BufIn[2] & 0xFF); //Mixer gain is 20dB 0x2 gain_state *= 2; //Add the LNA gain if present (10dB) 0x1 gain_state += (au8BufIn[2] & 0x1); //Scale it to tens 1->10dB 2->20dB 3->30dB gain_state *= 10; rig_debug(RIG_DEBUG_TRACE, "%s: Calculated gain state is %d.\n", __func__, gain_state); if (gain_state > 30 || gain_state < 0 || gain_state % 10 != 0) { rig_debug(RIG_DEBUG_ERR, "%s: unrecognized composite gain: %d\n", __func__, gain_state); return -RIG_EINVAL; } val->i = gain_state; return RIG_OK; case RIG_LEVEL_RF: au8BufOut[0] = REQUEST_GET_IF_GAIN; ret = funcube_hid_cmd(rig, au8BufOut, au8BufIn, sizeof(au8BufIn)); val->f = ((float)au8BufIn[2]) / 100.; return ret; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } static int funcube_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { if (rig->caps->rig_model == RIG_MODEL_FUNCUBEDONGLE) { *mode = RIG_MODE_USB; } else { *mode = RIG_MODE_IQ; } *width = 192000; return RIG_OK; } #endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ hamlib-4.6.2/rigs/kit/fifisdr.c0000644000175000017500000005143014752216205013234 00000000000000/* * Hamlib KIT backend - FiFi-SDR Receiver(/Tuner) description * Copyright (c) 2010 by Rolf Meeser * * Derived from si570avrusb backend: * Copyright (C) 2004-2010 Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #ifdef HAVE_STDINT_H #include #endif #include #include #include #include "hamlib/rig.h" #include "token.h" /* * Compile this model only if libusb is available */ #if defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif /* Selected request codes of the original AVR USB Si570 firmware */ #define REQUEST_SET_FREQ_BY_VALUE (0x32) #define REQUEST_SET_XTALL_FREQ (0x33) #define REQUEST_READ_MULTIPLY_LO (0x39) #define REQUEST_READ_FREQUENCY (0x3A) /* FiFi-SDR specific requests */ #define REQUEST_FIFISDR_READ (0xAB) #define REQUEST_FIFISDR_WRITE (0xAC) /* USB VID/PID, vendor name (idVendor), product name (idProduct). * Use obdev's generic shared VID/PID pair and follow the rules outlined * in firmware/usbdrv/USBID-License.txt. */ #define USBDEV_SHARED_VID 0x16C0 /* VOTI */ #define USBDEV_SHARED_PID 0x05DC /* Obdev's free shared PID */ #define FIFISDR_VENDOR_NAME "www.ov-lennestadt.de" #define FIFISDR_PRODUCT_NAME "FiFi-SDR" /* All level controls */ #define FIFISDR_LEVEL_ALL (0 \ | RIG_LEVEL_PREAMP \ | RIG_LEVEL_STRENGTH \ | RIG_LEVEL_AF \ | RIG_LEVEL_AGC \ | RIG_LEVEL_SQL \ ) static int fifisdr_init(RIG *rig); static int fifisdr_cleanup(RIG *rig); static int fifisdr_open(RIG *rig); static int fifisdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int fifisdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static const char *fifisdr_get_info(RIG *rig); static int fifisdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int fifisdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int fifisdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int fifisdr_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); /* Private tokens. */ #define TOK_LVL_FMCENTER TOKEN_BACKEND(1) /* FM center frequency deviation */ /* Extra levels definitions */ static const struct confparams fifisdr_ext_levels[] = { { TOK_LVL_FMCENTER, "fmcenter", "FM center", "Center frequency deviation of FM signal", NULL, RIG_CONF_NUMERIC, { .n = { -kHz(5), kHz(5), Hz(1) } } }, { RIG_CONF_END, NULL, } }; /** Private instance data. */ struct fifisdr_priv_instance_data { double multiplier; }; /** FiFi-SDR receiver description. */ struct rig_caps fifisdr_caps = { RIG_MODEL(RIG_MODEL_FIFISDR), .model_name = "FiFi-SDR", .mfg_name = "FiFi", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = FIFISDR_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(FIFISDR_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(RIG_PARM_NONE), .level_gran = {}, .parm_gran = {}, .extparms = NULL, .extlevels = fifisdr_ext_levels, .preamp = { 6, RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_NONE, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { { .startf = kHz(39.1), .endf = MHz(175.0), .modes = RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_FM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A, .ant = RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(39.1), .endf = MHz(175.0), .modes = RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_FM, .low_power = -1, .high_power = -1, .vfo = RIG_VFO_A, .ant = RIG_ANT_1 }, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_SSB, Hz(1)}, {RIG_MODE_SSB, Hz(10)}, {RIG_MODE_SSB, Hz(50)}, {RIG_MODE_AM, Hz(10)}, {RIG_MODE_AM, Hz(50)}, {RIG_MODE_AM, Hz(100)}, {RIG_MODE_FM, kHz(0.1)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_FM, kHz(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, /* normal */ {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_AM, kHz(8.0)}, /* normal */ {RIG_MODE_AM, kHz(6.2)}, {RIG_MODE_AM, kHz(10.0)}, {RIG_MODE_FM, kHz(9.0)}, /* normal */ {RIG_MODE_FM, kHz(6.0)}, {RIG_MODE_FM, kHz(12.5)}, RIG_FLT_END, }, .cfgparams = NULL, .rig_init = fifisdr_init, .rig_cleanup = fifisdr_cleanup, .rig_open = fifisdr_open, .rig_close = NULL, .set_freq = fifisdr_set_freq, .get_freq = fifisdr_get_freq, .set_mode = fifisdr_set_mode, .get_mode = fifisdr_get_mode, .set_level = fifisdr_set_level, .get_level = fifisdr_get_level, .get_ext_level = fifisdr_get_ext_level, .get_info = fifisdr_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /** Convert from host endianness to FiFi-SDR little endian. */ static uint32_t fifisdr_tole32(uint32_t x) { return (((((x) / 1ul) % 256ul) << 0) | ((((x) / 256ul) % 256ul) << 8) | ((((x) / 65536ul) % 256ul) << 16) | ((((x) / 16777216ul) % 256ul) << 24)); } /** Convert FiFi-SDR little endian to host endianness. */ static uint32_t fifisdr_fromle32(uint32_t x) { return (((((x) >> 24) & 0xFF) * 16777216ul) + ((((x) >> 16) & 0xFF) * 65536ul) + ((((x) >> 8) & 0xFF) * 256ul) + ((((x) >> 0) & 0xFF) * 1ul)); } /** USB OUT transfer via vendor device command. */ static int fifisdr_usb_write(RIG *rig, int request, int value, int index, unsigned char *bytes, int size) { int ret; libusb_device_handle *udh = RIGPORT(rig)->handle; ret = libusb_control_transfer(udh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT, request, value, index, bytes, size, RIGPORT(rig)->timeout); if (ret != size) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer (%d/%d) failed: %s\n", __func__, request, value, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } /** USB IN transfer via vendor device command. */ static int fifisdr_usb_read(RIG *rig, int request, int value, int index, unsigned char *bytes, int size) { int ret; libusb_device_handle *udh = RIGPORT(rig)->handle; ret = libusb_control_transfer(udh, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, request, value, index, bytes, size, RIGPORT(rig)->timeout); if (ret != size) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer (%d/%d) failed: %s\n", __func__, request, value, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } int fifisdr_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct fifisdr_priv_instance_data *priv; STATE(rig)->priv = (struct fifisdr_priv_instance_data *)calloc(sizeof( struct fifisdr_priv_instance_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->multiplier = 4; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; rp->parm.usb.vendor_name = FIFISDR_VENDOR_NAME; rp->parm.usb.product = FIFISDR_PRODUCT_NAME; return RIG_OK; } int fifisdr_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int fifisdr_open(RIG *rig) { int ret; uint32_t multiply; struct fifisdr_priv_instance_data *priv; priv = (struct fifisdr_priv_instance_data *)STATE(rig)->priv; /* The VCO is a multiple of the RX frequency. Typically 4 */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 11, /* Read virtual VCO factor */ (unsigned char *)&multiply, sizeof(multiply)); if (ret == RIG_OK) { priv->multiplier = fifisdr_fromle32(multiply); } return RIG_OK; } const char *fifisdr_get_info(RIG *rig) { static char buf[64]; int ret; uint32_t svn_version; ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 0, (unsigned char *)&svn_version, sizeof(svn_version)); if (ret != RIG_OK) { return NULL; } SNPRINTF(buf, sizeof(buf), "Firmware version: %u", svn_version); return buf; } int fifisdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct fifisdr_priv_instance_data *priv = (struct fifisdr_priv_instance_data *) STATE(rig)->priv; int ret; double mhz; uint32_t freq1121; /* Need frequency in 11.21 format */ mhz = (freq * priv->multiplier) / 1e6; freq1121 = fifisdr_tole32(round(mhz * 2097152.0)); ret = fifisdr_usb_write(rig, REQUEST_SET_FREQ_BY_VALUE, 0, 0, (unsigned char *)&freq1121, sizeof(freq1121)); if (ret != RIG_OK) { return -RIG_EIO; } return RIG_OK; } int fifisdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct fifisdr_priv_instance_data *priv = (struct fifisdr_priv_instance_data *) STATE(rig)->priv; int ret; uint32_t freq1121; ret = fifisdr_usb_read(rig, REQUEST_READ_FREQUENCY, 0, 0, (unsigned char *)&freq1121, sizeof(freq1121)); if (ret == RIG_OK) { freq1121 = fifisdr_fromle32(freq1121); *freq = MHz(((double)freq1121 / (1ul << 21)) / priv->multiplier); } return ret; } static int fifisdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int ret; uint8_t fifi_mode; uint32_t fifi_width; /* Translate mode into FiFi-SDR language */ fifi_mode = 0; switch (mode) { case RIG_MODE_AM: fifi_mode = 2; break; case RIG_MODE_LSB: fifi_mode = 0; break; case RIG_MODE_USB: fifi_mode = 1; break; case RIG_MODE_FM: fifi_mode = 3; break; default: return -RIG_EINVAL; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 15, /* Demodulator mode */ (unsigned char *)&fifi_mode, sizeof(fifi_mode)); if (ret != RIG_OK) { return -RIG_EIO; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } /* Set filter width */ fifi_width = fifisdr_tole32(width); ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 16, /* Filter width */ (unsigned char *)&fifi_width, sizeof(fifi_width)); if (ret != RIG_OK) { return -RIG_EIO; } return RIG_OK; } static int fifisdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; uint8_t fifi_mode; uint32_t fifi_width; /* Read current mode */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 15, /* Demodulator mode */ (unsigned char *)&fifi_mode, sizeof(fifi_mode)); if (ret != RIG_OK) { return -RIG_EIO; } /* Translate mode coding */ *mode = RIG_MODE_NONE; switch (fifi_mode) { case 0: *mode = RIG_MODE_LSB; break; case 1: *mode = RIG_MODE_USB; break; case 2: *mode = RIG_MODE_AM; break; case 3: *mode = RIG_MODE_FM; break; } /* Read current filter width */ ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 16, /* Filter width */ (unsigned char *)&fifi_width, sizeof(fifi_width)); if (ret != RIG_OK) { return -RIG_EIO; } *width = s_Hz(fifisdr_fromle32(fifi_width)); return RIG_OK; } static int fifisdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret = RIG_OK; uint8_t fifi_preamp; int16_t fifi_volume; uint8_t fifi_squelch; uint8_t fifi_agc; switch (level) { /* Preamplifier (ADC 0/+6dB switch) */ case RIG_LEVEL_PREAMP: /* Value can be 0 (0 dB) or 1 (+6 dB) */ fifi_preamp = 0; if (val.i == 6) { fifi_preamp = 1; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 19, /* Preamp */ (unsigned char *)&fifi_preamp, sizeof(fifi_preamp)); break; /* RX volume control */ case RIG_LEVEL_AF: /* Transform Hamlib value (float: 0...1) to an integer range (0...100) */ fifi_volume = (int16_t)(val.f * 100.0f); if (fifi_volume < 0) { fifi_volume = 0; } if (fifi_volume > 100) { fifi_volume = 100; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 14, /* Demodulator volume */ (unsigned char *)&fifi_volume, sizeof(fifi_volume)); break; /* Squelch level */ case RIG_LEVEL_SQL: /* Transform Hamlib value (float: 0...1) to an integer range (0...100) */ fifi_squelch = (uint8_t)(val.f * 100.0f); if (fifi_squelch > 100) { fifi_squelch = 100; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 20, /* Squelch control */ (unsigned char *)&fifi_squelch, sizeof(fifi_squelch)); break; /* AGC */ case RIG_LEVEL_AGC: /* Transform Hamlib enum value to FiFi-SDR selector */ fifi_agc = 0; switch (val.i) { case RIG_AGC_OFF: fifi_agc = 0; break; case RIG_AGC_SUPERFAST: fifi_agc = 1; break; case RIG_AGC_FAST: fifi_agc = 2; break; case RIG_AGC_SLOW: fifi_agc = 3; break; case RIG_AGC_USER: fifi_agc = 4; break; case RIG_AGC_MEDIUM: fifi_agc = 5; break; case RIG_AGC_AUTO: fifi_agc = 6; break; } ret = fifisdr_usb_write(rig, REQUEST_FIFISDR_WRITE, 0, 21, /* AGC template */ (unsigned char *)&fifi_agc, sizeof(fifi_agc)); break; /* Unsupported option */ default: ret = -RIG_ENIMPL; } return ret; } static int fifisdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret = RIG_OK; uint32_t fifi_meter = 0; uint8_t fifi_preamp = 0; int16_t fifi_volume = 0; uint8_t fifi_squelch = 0; uint8_t fifi_agc = 0; switch (level) { /* Preamplifier (ADC 0/+6dB switch) */ case RIG_LEVEL_PREAMP: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 19, /* Preamp */ (unsigned char *)&fifi_preamp, sizeof(fifi_preamp)); if (ret == RIG_OK) { /* Value can be 0 (0 dB) or 1 (+6 dB) */ val->i = 0; if (fifi_preamp != 0) { val->i = 6; } } break; /* RX volume control */ case RIG_LEVEL_AF: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 14, /* Demodulator volume */ (unsigned char *)&fifi_volume, sizeof(fifi_volume)); if (ret == RIG_OK) { /* Value is in % (0...100) */ val->f = 0.0f; if ((fifi_volume >= 0) && (fifi_volume <= 100)) { val->f = (float)fifi_volume / 100.0f; } } break; /* Squelch level */ case RIG_LEVEL_SQL: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 20, /* Squelch control */ (unsigned char *)&fifi_squelch, sizeof(fifi_squelch)); if (ret == RIG_OK) { /* Value is in % (0...100) */ val->f = 0.0f; if (fifi_squelch <= 100) { val->f = (float)fifi_squelch / 100.0f; } } break; /* AGC */ case RIG_LEVEL_AGC: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 21, /* AGC template */ (unsigned char *)&fifi_agc, sizeof(fifi_agc)); if (ret == RIG_OK) { val->i = 0; switch (fifi_agc) { case 0: val->i = RIG_AGC_OFF; break; case 1: val->i = RIG_AGC_SUPERFAST; break; case 2: val->i = RIG_AGC_FAST; break; case 3: val->i = RIG_AGC_SLOW; break; case 4: val->i = RIG_AGC_USER; break; case 5: val->i = RIG_AGC_MEDIUM; break; case 6: val->i = RIG_AGC_AUTO; break; } } break; /* Signal strength */ case RIG_LEVEL_STRENGTH: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 17, /* S-Meter */ (unsigned char *)&fifi_meter, sizeof(fifi_meter)); if (ret == RIG_OK) { val->i = fifisdr_fromle32(fifi_meter); } break; /* Unsupported option */ default: ret = -RIG_ENIMPL; } return ret; } static int fifisdr_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int ret = RIG_OK; uint32_t u32; switch (token) { /* FM center frequency deviation */ case TOK_LVL_FMCENTER: ret = fifisdr_usb_read(rig, REQUEST_FIFISDR_READ, 0, 18, /* FM center frequency */ (unsigned char *)&u32, sizeof(u32)); if (ret == RIG_OK) { val->f = Hz((int32_t)fifisdr_fromle32(u32)); } break; /* Unsupported option */ default: ret = -RIG_ENIMPL; } return ret; } #endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ hamlib-4.6.2/rigs/kit/hiqsdr.c0000644000175000017500000003411414752216205013100 00000000000000/* * Hamlib HiQSDR backend * Copyright (c) 20012 by Stephane Fillod * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include /* Standard input/output definitions */ #include /* String function definitions */ #include "hamlib/rig.h" #include "iofunc.h" #include "token.h" /* * http://www.hiqsdr.org */ /* HiQSDR constants */ #define REFCLOCK 122880000 #define DEFAULT_SAMPLE_RATE 48000 /* V1.1 */ #define CTRL_FRAME_LEN 22 struct hiqsdr_priv_data { split_t split; int sample_rate; double ref_clock; unsigned char control_frame[CTRL_FRAME_LEN]; }; static int hiqsdr_init(RIG *rig); static int hiqsdr_cleanup(RIG *rig); static int hiqsdr_open(RIG *rig); static int hiqsdr_close(RIG *rig); static int hiqsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int hiqsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int hiqsdr_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int hiqsdr_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int hiqsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int hiqsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int hiqsdr_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); static int hiqsdr_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int hiqsdr_get_conf(RIG *rig, hamlib_token_t token, char *val); static int hiqsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int hiqsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_SAMPLE_RATE TOKEN_BACKEND(2) const struct confparams hiqsdr_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency of reference clock in Hz", "122880000", RIG_CONF_NUMERIC, { .n = { 0, MHz(256), 1 } } }, { TOK_SAMPLE_RATE, "sample_rate", "Sample rate", "Sample rate", "48000", RIG_CONF_NUMERIC, { /* .n = */ { 48000, 1920000, 1 } } }, { RIG_CONF_END, NULL, } }; /* * HiQSDR rig capabilities. */ #define HIQSDR_FUNC RIG_FUNC_NONE #define HIQSDR_LEVEL (RIG_LEVEL_RFPOWER|RIG_LEVEL_PREAMP|RIG_LEVEL_ATT) #define HIQSDR_PARM RIG_PARM_NONE #define HIQSDR_VFO_OP RIG_OP_NONE #define HIQSDR_SCAN RIG_SCAN_NONE #define HIQSDR_VFO (RIG_VFO_A) #define HIQSDR_ANT (RIG_ANT_1|RIG_ANT_2) #define HIQSDR_MODES (RIG_MODE_CW|RIG_MODE_DSB) struct rig_caps hiqsdr_caps = { RIG_MODEL(RIG_MODEL_HIQSDR), .model_name = "HiQSDR", .mfg_name = "N2ADR", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TUNER, .targetable_vfo = RIG_TARGETABLE_NONE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_UDP_NETWORK, .timeout = 500, .has_get_func = HIQSDR_FUNC, .has_set_func = HIQSDR_FUNC, .has_get_level = HIQSDR_LEVEL, .has_set_level = RIG_LEVEL_SET(HIQSDR_LEVEL), .has_get_parm = HIQSDR_PARM, .has_set_parm = RIG_PARM_SET(HIQSDR_PARM), .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { RIG_CHAN_END, }, .scan_ops = HIQSDR_SCAN, .vfo_ops = HIQSDR_VFO_OP, .transceive = RIG_TRN_OFF, .attenuator = { 2, 4, 6, 10, 20, 30, 44, RIG_DBLST_END }, // -2dB steps in fact .preamp = { 10, RIG_DBLST_END, }, // TODO .rx_range_list1 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = -1, .high_power = -1, HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .tx_range_list1 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = mW(1), .high_power = mW(50), HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = -1, .high_power = -1, HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .tx_range_list2 = { { .startf = kHz(100), .endf = MHz(66), .modes = HIQSDR_MODES, .low_power = mW(1), .high_power = mW(50), HIQSDR_VFO, HIQSDR_ANT }, RIG_FRNG_END, }, .tuning_steps = { {HIQSDR_MODES, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_CW, kHz(2.4)}, {HIQSDR_MODES, RIG_FLT_ANY}, RIG_FLT_END, }, .priv = NULL, .rig_init = hiqsdr_init, .rig_cleanup = hiqsdr_cleanup, .rig_open = hiqsdr_open, .rig_close = hiqsdr_close, .cfgparams = hiqsdr_cfg_params, .set_conf = hiqsdr_set_conf, .get_conf = hiqsdr_get_conf, .set_freq = hiqsdr_set_freq, .get_freq = hiqsdr_get_freq, .set_split_freq = hiqsdr_set_split_freq, .set_split_vfo = hiqsdr_set_split_vfo, .set_mode = hiqsdr_set_mode, .set_ptt = hiqsdr_set_ptt, .set_ant = hiqsdr_set_ant, .set_level = hiqsdr_set_level, .get_level = hiqsdr_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int send_command(RIG *rig) { const struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *) STATE(rig)->priv; int ret; ret = write_block(RIGPORT(rig), (unsigned char *) priv->control_frame, CTRL_FRAME_LEN); #if 0 ret = read_block(RIGPORT(rig), (unsigned char *) priv->control_frame, CTRL_FRAME_LEN); if (ret != CTRL_FRAME_LEN) { ret = ret < 0 ? ret : -RIG_EPROTO; } #endif return ret; } static unsigned compute_sample_rate(const struct hiqsdr_priv_data *priv) { unsigned rx_control; rx_control = (unsigned)(priv->ref_clock / (8. * 8. * priv->sample_rate)) - 1; if (rx_control > 39) { rx_control = 39; } return rx_control; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int hiqsdr_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct hiqsdr_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct hiqsdr_priv_data *)rs->priv; switch (token) { case TOK_OSCFREQ: priv->ref_clock = atof(val); priv->control_frame[12] = compute_sample_rate(priv); break; case TOK_SAMPLE_RATE: priv->sample_rate = atoi(val); priv->control_frame[12] = compute_sample_rate(priv); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int hiqsdr_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct hiqsdr_priv_data *priv; struct rig_state *rs; rs = STATE(rig); priv = (struct hiqsdr_priv_data *)rs->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%f", priv->ref_clock); break; case TOK_SAMPLE_RATE: SNPRINTF(val, val_len, "%d", priv->sample_rate); break; default: return -RIG_EINVAL; } return RIG_OK; } int hiqsdr_get_conf(RIG *rig, hamlib_token_t token, char *val) { return hiqsdr_get_conf2(rig, token, val, 128); } int hiqsdr_init(RIG *rig) { struct hiqsdr_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct hiqsdr_priv_data *)calloc(1, sizeof( struct hiqsdr_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->split = RIG_SPLIT_OFF; priv->ref_clock = REFCLOCK; priv->sample_rate = DEFAULT_SAMPLE_RATE; strncpy(RIGPORT(rig)->pathname, "192.168.2.196:48248", HAMLIB_FILPATHLEN - 1); return RIG_OK; } int hiqsdr_open(RIG *rig) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; #if 0 const char buf_send_to_me[] = { 0x72, 0x72 }; int ret; #endif rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* magic value */ priv->control_frame[0] = 'S'; priv->control_frame[1] = 't'; /* zero tune phase */ memset(priv->control_frame + 2, 0, 8); /* TX output level */ priv->control_frame[10] = 120; /* Tx control: non-CW */ priv->control_frame[11] = 0x02; /* decimation: 48 kSpls */ priv->control_frame[12] = compute_sample_rate(priv); /* firmware version */ priv->control_frame[13] = 0x00; /* X1 connector */ priv->control_frame[14] = 0x00; /* Attenuator */ priv->control_frame[15] = 0x00; /* AntSwitch */ priv->control_frame[16] = 0x00; /* RFU */ memset(priv->control_frame + 17, 0, 5); #if 0 /* Send the samples to me. FIXME: send to port 48247 */ ret = write_block(RIGPORT(rig), buf_send_to_me, sizeof(buf_send_to_me)); if (ret != RIG_OK) { return RIG_OK; } #endif return RIG_OK; } int hiqsdr_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); return RIG_OK; } int hiqsdr_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* */ int hiqsdr_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret; double rxphase; uint32_t rxphase32; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); rxphase = (freq / priv->ref_clock) * (1ULL << 32) + 0.5; rxphase32 = (uint32_t)rxphase; priv->control_frame[2] = rxphase32 & 0xff; priv->control_frame[3] = (rxphase32 >> 8) & 0xff; priv->control_frame[4] = (rxphase32 >> 16) & 0xff; priv->control_frame[5] = (rxphase32 >> 24) & 0xff; if (priv->split == RIG_SPLIT_OFF) { priv->control_frame[6] = priv->control_frame[2]; priv->control_frame[7] = priv->control_frame[3]; priv->control_frame[8] = priv->control_frame[4]; priv->control_frame[9] = priv->control_frame[5]; } ret = send_command(rig); return ret; } static int hiqsdr_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; priv->split = split; return RIG_OK; } int hiqsdr_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret; double rxphase; uint32_t rxphase32; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); rxphase = (tx_freq / priv->ref_clock) * (1ULL << 32) + 0.5; rxphase32 = (uint32_t)rxphase; priv->control_frame[6] = rxphase32 & 0xff; priv->control_frame[7] = (rxphase32 >> 8) & 0xff; priv->control_frame[8] = (rxphase32 >> 16) & 0xff; priv->control_frame[9] = (rxphase32 >> 24) & 0xff; ret = send_command(rig); return ret; } int hiqsdr_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { return -RIG_ENIMPL; } int hiqsdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s\n", __func__, rig_strrmode(mode)); if (mode == RIG_MODE_CW) { priv->control_frame[11] = 0x01; } else { priv->control_frame[11] = 0x02; } ret = send_command(rig); return ret; } int hiqsdr_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %d\n", __func__, ptt); /* not allowed in CW mode */ if (priv->control_frame[11] & 0x01) { return -RIG_ERJCTED; } if (ptt == RIG_PTT_ON) { priv->control_frame[11] |= 0x08; } else { priv->control_frame[11] &= ~0x08; } ret = send_command(rig); return ret; } int hiqsdr_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; rig_debug(RIG_DEBUG_VERBOSE, "%s called: %u\n", __func__, ant); if (ant == RIG_ANT_2) { priv->control_frame[16] |= 0x01; } else { priv->control_frame[16] &= ~0x01; } ret = send_command(rig); return ret; } int hiqsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct hiqsdr_priv_data *priv = (struct hiqsdr_priv_data *)STATE(rig)->priv; int ret = RIG_OK; switch (level) { case RIG_LEVEL_PREAMP: if (val.i) { priv->control_frame[14] |= 0x02; } else { priv->control_frame[14] &= ~0x02; } break; case RIG_LEVEL_ATT: /* FIXME: val->i should be looked up from the att list */ priv->control_frame[14] = val.i & 0x1f; break; case RIG_LEVEL_RFPOWER: /* TX output level */ priv->control_frame[10] = 0xff & (unsigned)(255 * val.f); break; default: return -RIG_EINVAL; } ret = send_command(rig); return ret; } static int hiqsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { return -RIG_ENIMPL; } hamlib-4.6.2/rigs/kit/kit.h0000644000175000017500000000323014752216205012375 00000000000000/* * Hamlib KIT backend - main header * Copyright (c) 2004-2012 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _KIT_H #define _KIT_H 1 #include "hamlib/rig.h" #include "rotator.h" extern struct rig_caps elektor304_caps; extern struct rig_caps elektor507_caps; extern struct rig_caps si570avrusb_caps; extern struct rig_caps si570picusb_caps; extern struct rig_caps si570peaberry1_caps; extern struct rig_caps si570peaberry2_caps; extern struct rig_caps drt1_caps; extern struct rig_caps dwt_caps; extern struct rig_caps usrp0_caps; extern struct rig_caps usrp_caps; extern struct rig_caps dds60_caps; extern struct rig_caps miniVNA_caps; extern struct rig_caps funcube_caps; extern struct rig_caps funcubeplus_caps; extern struct rig_caps fifisdr_caps; extern struct rig_caps hiqsdr_caps; extern struct rig_caps fasdr_caps; extern struct rig_caps rshfiq_caps; extern const struct rot_caps pcrotor_caps; #endif /* _KIT_H */ hamlib-4.6.2/rigs/kit/Android.mk0000644000175000017500000000057514752216205013357 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := elektor304.c drt1.c dwt.c usrp.c elektor507.c \ dds60.c miniVNA.c si570avrusb.c funcube.c fifisdr.c hiqsdr.c \ pcrotor.c kit.c rs_hfiq.c LOCAL_MODULE := kit LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/kit/usrp_impl.h0000644000175000017500000000275614752216205013634 00000000000000/* * Hamlib KIT backend - Universal Software Radio Peripheral * Copyright (c) 2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _USRP_IMPL_H #define _USRP_IMPL_H 1 #include #include __BEGIN_DECLS #define TOK_IFMIXFREQ TOKEN_BACKEND(2) int usrp_init(RIG *rig); int usrp_cleanup(RIG *rig); int usrp_open(RIG *rig); int usrp_close(RIG *rig); int usrp_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int usrp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int usrp_set_conf(RIG *rig, hamlib_token_t token, const char *val); int usrp_get_conf(RIG *rig, hamlib_token_t token, char *val); const char * usrp_get_info(RIG *rig); extern struct rig_caps usrp0_caps; extern struct rig_caps usrp_caps; __END_DECLS #endif /* _USRP_IMPL_H */ hamlib-4.6.2/rigs/kit/pcrotor.c0000644000175000017500000000644414752216205013303 00000000000000/* * Hamlib Rotator backend - PcRotor/WA6UFQ parallel port * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rotator.h" #include "parallel.h" /* ************************************************************************* */ //pcrotor_set_position(ROT *rot, azimuth_t az, elevation_t el) #define PCROTOR_POWER 0x20 #define PCROTOR_CW 0x40 #define PCROTOR_CCW 0x80 #define PCROTOR_MASK (PCROTOR_CCW|PCROTOR_CW|PCROTOR_POWER) static int setDirection(hamlib_port_t *port, unsigned char outputvalue) { int ret; par_lock(port); /* set the data bits. * Should we read before write to not trample the lower significant bits? */ ret = par_write_data(port, outputvalue); par_unlock(port); return ret; } static int pcrotor_stop(ROT *rot) { /* CW=0, CCW=0, Power-up=0 */ return setDirection(ROTPORT(rot), 0); } static int pcrotor_move(ROT *rot, int direction, int speed) { unsigned char outputvalue; rig_debug(RIG_DEBUG_TRACE, "%s called: %d %d\n", __func__, direction, speed); switch (direction) { case ROT_MOVE_CCW: outputvalue = PCROTOR_POWER | PCROTOR_CCW; break; case ROT_MOVE_CW: outputvalue = PCROTOR_POWER | PCROTOR_CCW; break; case 0: /* Stop */ outputvalue = 0; break; default: return -RIG_EINVAL; } return setDirection(ROTPORT(rot), outputvalue); } /* ************************************************************************* */ /* * PcRotor rotator capabilities. * * Control Interface schematics from, courtersy of Bob Hillard WA6UFQ: * http://www.dxzone.com/cgi-bin/dir/jump2.cgi?ID=11173 * * DB25-7=Data-5= Power up/Sleep * DB25-8=Data-6= CW * DB25-9=Data-7= CCW * * There's no feedback. */ /** Fodtrack implement essentially only the set position function. * */ const struct rot_caps pcrotor_caps = { ROT_MODEL(ROT_MODEL_PCROTOR), .model_name = "PcRotor", .mfg_name = "WA6UFQ", .version = "20081013.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rot_type = ROT_TYPE_OTHER, .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .min_az = 0, .max_az = 360, .min_el = 0, .max_el = 0, .priv = NULL, /* priv */ .move = pcrotor_move, .stop = pcrotor_stop, //.set_position = pcrotor_set_position, //.get_position = pcrotor_get_position, }; /* end of file */ hamlib-4.6.2/rigs/kit/dds60.c0000644000175000017500000002251014752216205012523 00000000000000/* * Hamlib KIT backend - DDS-60 description * Copyright (c) 2007 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "parallel.h" #include "token.h" #define DDS60_MODES (RIG_MODE_AM) #define DDS60_FUNC (RIG_FUNC_NONE) #define DDS60_LEVEL_ALL (RIG_LEVEL_NONE) #define DDS60_PARM_ALL (RIG_PARM_NONE) #define DDS60_VFO (RIG_VFO_A) /* defaults */ #define OSCFREQ MHz(30) #define IFMIXFREQ kHz(0) #define PHASE_INCR 11.25 struct dds60_priv_data { freq_t osc_freq; freq_t if_mix_freq; int multiplier; unsigned phase_step; /* as 11.25 deg steps */ }; #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_IFMIXFREQ TOKEN_BACKEND(2) #define TOK_MULTIPLIER TOKEN_BACKEND(3) #define TOK_PHASE_MOD TOKEN_BACKEND(4) static const struct confparams dds60_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency in Hz", "30000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(180), 1 } } }, { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "0", RIG_CONF_NUMERIC, { .n = { 0, MHz(180), 1 } } }, { TOK_MULTIPLIER, "multiplier", "Multiplier", "Optional X6 multiplier", "1", RIG_CONF_CHECKBUTTON }, { TOK_IFMIXFREQ, "phase_mod", "Phase Modulation", "Phase modulation in degrees", "0", RIG_CONF_NUMERIC, { .n = { 0, 360, PHASE_INCR } } }, { RIG_CONF_END, NULL, } }; static int dds60_init(RIG *rig); static int dds60_cleanup(RIG *rig); static int dds60_open(RIG *rig); static int dds60_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int dds60_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int dds60_get_conf(RIG *rig, hamlib_token_t token, char *val); /* * The DDS-60 kit exists with a AD9851 chip (60 MHz), * as well as with the AD9850 chip (30 MHz) (no multiplier). * There is an option to enable/disable the AD9851 X6 multiplier. * http://www.amqrp.org/kits/dds60/ * http://www.analog.com/en/prod/0,2877,AD9851,00.html * * The receiver is controlled via the parallel port (D0,D1,D2). */ struct rig_caps dds60_caps = { RIG_MODEL(RIG_MODEL_DDS60), .model_name = "DDS-60", .mfg_name = "AmQRP", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_PARALLEL, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DDS60_FUNC, .has_set_func = DDS60_FUNC, .has_get_level = DDS60_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DDS60_LEVEL_ALL), .has_get_parm = DDS60_PARM_ALL, .has_set_parm = RIG_PARM_SET(DDS60_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {MHz(1), MHz(60), DDS60_MODES, -1, -1, DDS60_VFO}, /* TBC */ RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(1), MHz(60), DDS60_MODES, -1, -1, DDS60_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DDS60_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {DDS60_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = dds60_cfg_params, .rig_init = dds60_init, .rig_cleanup = dds60_cleanup, .rig_open = dds60_open, .set_conf = dds60_set_conf, .get_conf = dds60_get_conf, .set_freq = dds60_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int dds60_init(RIG *rig) { struct dds60_priv_data *priv; STATE(rig)->priv = (struct dds60_priv_data *)calloc(1, sizeof( struct dds60_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = OSCFREQ; priv->if_mix_freq = IFMIXFREQ; priv->multiplier = 1; priv->phase_step = 0; return RIG_OK; } int dds60_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int dds60_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct dds60_priv_data *priv; float phase; priv = (struct dds60_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &priv->osc_freq); break; case TOK_IFMIXFREQ: sscanf(val, "%"SCNfreq, &priv->if_mix_freq); break; case TOK_MULTIPLIER: sscanf(val, "%d", &priv->multiplier); break; case TOK_PHASE_MOD: sscanf(val, "%f", &phase); priv->phase_step = ((unsigned)((phase + PHASE_INCR / 2) / PHASE_INCR)) % 32; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int dds60_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct dds60_priv_data *priv; priv = (struct dds60_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq); break; case TOK_IFMIXFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->if_mix_freq); break; case TOK_MULTIPLIER: SNPRINTF(val, val_len, "%d", priv->multiplier); break; case TOK_PHASE_MOD: SNPRINTF(val, val_len, "%f", priv->phase_step * PHASE_INCR); break; default: return -RIG_EINVAL; } return RIG_OK; } int dds60_get_conf(RIG *rig, hamlib_token_t token, char *val) { return dds60_get_conf2(rig, token, val, 128); } #define DATA 0x01 /* d0 */ #define CLOCK 0x02 /* d1 */ #define LOAD 0x03 /* d2 */ static void ad_delay(int delay) { /* none needed, I/O bus should be slow enough */ } static void ad_bit(hamlib_port_t *port, unsigned char bit) { bit &= DATA; par_write_data(port, bit); ad_delay(1); par_write_data(port, bit | CLOCK); ad_delay(1); par_write_data(port, bit); ad_delay(1); } static void ad_write(hamlib_port_t *port, unsigned long word, unsigned char control) { int i; /* lock the parallel port */ par_lock(port); /* shift out the least significant 32 bits of the word */ for (i = 0; i < 32; i++) { ad_bit(port, word & DATA); word >>= 1; } /* write out the control byte */ for (i = 0; i < 8; i++) { ad_bit(port, control & DATA); control >>= 1; } /* load the register */ par_write_data(port, LOAD); ad_delay(1); par_write_data(port, 0); /* unlock the parallel port */ par_unlock(port); } int dds60_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long frg; unsigned char control; struct dds60_priv_data *priv; hamlib_port_t *port = RIGPORT(rig); freq_t osc_ref; priv = (struct dds60_priv_data *)STATE(rig)->priv; if (priv->multiplier) { osc_ref = priv->osc_freq * 6; } else { osc_ref = priv->osc_freq; } /* all frequencies are in Hz */ frg = (unsigned long)(((double)freq + priv->if_mix_freq) / osc_ref * 4294967296.0 + 0.5); rig_debug(RIG_DEBUG_VERBOSE, "%s: word %lu, X6 multiplier %d, phase %.2f\n", __func__, frg, priv->multiplier, priv->phase_step * PHASE_INCR); control = priv->multiplier ? 0x01 : 0x00; control |= (priv->phase_step & 0x1f) << 3; ad_write(port, frg, control); return RIG_OK; } int dds60_open(RIG *rig) { hamlib_port_t *port = RIGPORT(rig); /* lock the parallel port */ par_lock(port); /* Serial load enable sequence W_CLK */ par_write_data(port, 0); ad_delay(1); par_write_data(port, CLOCK); ad_delay(1); par_write_data(port, 0); ad_delay(1); /* Serial load enable sequence FQ_UD */ par_write_data(port, LOAD); ad_delay(1); par_write_data(port, 0); /* unlock the parallel port */ par_unlock(port); return RIG_OK; } hamlib-4.6.2/rigs/kit/funcube.h0000644000175000017500000000401114752216205013233 00000000000000/* * Hamlib KIT backend - FUNcube Dongle USB tuner description * Copyright (c) 2009-2011 by Stephane Fillod * * Derived from usbsoftrock-0.5: * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * Author: Stefano Speretta, Innovative Solutions In Space BV * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FUNCUBE_H #define _FUNCUBE_H 1 #define VID 0x04D8 #define PID 0xFB56 #define PIDPLUS 0xFB31 #define VENDOR_NAME "Hanlincrest Ltd. " #define PRODUCT_NAME "FunCube Dongle" #define PRODUCT_NAMEPLUS "FunCube Dongle Pro+" #define FUNCUBE_INTERFACE 0x02 #define FUNCUBE_CONFIGURATION -1 /* no setup */ #define FUNCUBE_ALTERNATIVE_SETTING 0x00 #define INPUT_ENDPOINT 0x82 #define OUTPUT_ENDPOINT 0x02 // Commands #define REQUEST_SET_FREQ 0x64 #define REQUEST_SET_FREQ_HZ 0x65 #define REQUEST_GET_FREQ_HZ 0x66 #define REQUEST_SET_LNA_GAIN 0x6E #define REQUEST_SET_MIXER_GAIN 0x72 // Taken from qthid code #define REQUEST_SET_IF_GAIN 0x75 #define REQUEST_GET_LNA_GAIN 0x96 #define REQUEST_GET_MIXER_GAIN 0x9A // Taken from qthid code #define REQUEST_GET_IF_GAIN 0x9D // Taken from qthid code #define REQUEST_GET_RSSI 0x68 #define FUNCUBE_SUCCESS 0x01 #endif /* _FUNCUBE_H */ hamlib-4.6.2/rigs/kit/si570avrusb.h0000644000175000017500000000401214752216205013677 00000000000000/*** * SoftRock USB I2C host control program * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Based on powerSwitch.c by Christian Starkjohann, * and usbtemp.c by Mathias Dalheimer * of Objective Development Software GmbH (2005) * (see http://www.obdev.at/avrusb) * */ #ifndef _SI570AVRUSB_H #define _SI570AVRUSB_H 1 /* DG8SAQ specific values */ #define SI570_I2C_ADDR 0x55 #define SI570_DCO_HIGH 5670.0 #define SI570_DCO_LOW 4850.0 #define SI570_NOMINAL_XTALL_FREQ 114.285 #define SI570_XTALL_DEVIATION_PPM 2000 #define SI570_DEFAULT_STARTUP_FREQ 56.32 #define REQUEST_READ_VERSION 0x00 #define REQUEST_SET_DDRB 0x01 #define REQUEST_SET_PORTB 0x04 #define REQUEST_READ_EEPROM 0x11 #define REQUEST_FILTERS 0x17 #define REQUEST_SET_FREQ 0x30 #define REQUEST_SET_FREQ_BY_VALUE 0x32 #define REQUEST_SET_XTALL_FREQ 0x33 #define REQUEST_SET_STARTUP_FREQ 0x34 #define REQUEST_READ_MULTIPLY_LO 0x39 #define REQUEST_READ_FREQUENCY 0x3A #define REQUEST_READ_SMOOTH_TUNE_PPM 0x3B #define REQUEST_READ_STARTUP 0x3C #define REQUEST_READ_XTALL 0x3D #define REQUEST_READ_REGISTERS 0x3F //#define REQUEST_SET_STARTUP_FREQ 0x41 #define REQUEST_SET_PTT 0x50 #define REQUEST_READ_KEYS 0x51 struct solution { int HS_DIV; int N1; double f0; double RFREQ; }; #endif /* _SI570AVRUSB_H */ hamlib-4.6.2/rigs/kit/si570avrusb.c0000644000175000017500000011655414752216205013711 00000000000000/* * Hamlib KIT backend - SoftRock / Si570 AVR USB tuner description * Copyright (c) 2009-2010 by Stephane Fillod * * Derived from usbsoftrock-0.5: * Copyright (C) 2009 Andrew Nilsson (andrew.nilsson@gmail.com) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #define BACKEND_VER "20200112" #ifdef HAVE_STDINT_H #include #endif #include #include #include #include "hamlib/rig.h" #include "token.h" /* * Compile this model only if libusb is available */ #if defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H)) #include #ifdef HAVE_LIBUSB_H # include #elif defined HAVE_LIBUSB_1_0_LIBUSB_H # include #endif #include "si570avrusb.h" static int si570avrusb_init(RIG *rig); static int si570picusb_init(RIG *rig); static int si570peaberry1_init(RIG *rig); static int si570peaberry2_init(RIG *rig); static int fasdr_init(RIG *rig); static int si570xxxusb_cleanup(RIG *rig); static int si570xxxusb_open(RIG *rig); static int fasdr_open(RIG *rig); static int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int si570xxxusb_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int si570xxxusb_set_freq_by_value(RIG *rig, vfo_t vfo, freq_t freq); static int si570xxxusb_get_freq_by_value(RIG *rig, vfo_t vfo, freq_t *freq); static int si570xxxusb_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int si570xxxusb_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int si570xxxusb_get_conf(RIG *rig, hamlib_token_t token, char *val); static const char *si570xxxusb_get_info(RIG *rig); #define USBDEV_SHARED_VID 0x16C0 /* VOTI */ #define USBDEV_SHARED_PID 0x05DC /* Obdev's free shared PID */ /* Use obdev's generic shared VID/PID pair and follow the rules outlined * in firmware/usbdrv/USBID-License.txt. */ #define VENDOR_NAME "www.obdev.at" #define PEABERRY_VENDOR_NAME "AE9RB" /* Only for V1, V2 uses the 'standard' obdev name */ #define AVR_PRODUCT_NAME "DG8SAQ-I2C" #define PIC_PRODUCT_NAME "KTH-SDR-KIT" #define PEABERRY_PRODUCT_NAME "Peaberry SDR" #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_MULTIPLIER TOKEN_BACKEND(3) #define TOK_I2C_ADDR TOKEN_BACKEND(4) #define TOK_BPF TOKEN_BACKEND(5) #define F_CAL_STATUS 1 //1 byte #define F_CRYST 2 //4 byte static const struct confparams si570xxxusb_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillator freq", "Oscillator frequency in Hz", "114285000", RIG_CONF_NUMERIC, { .n = { 1, MHz(300), 1 } } }, { TOK_MULTIPLIER, "multiplier", "Freq Multiplier", "Frequency multiplier", "4", RIG_CONF_NUMERIC, { .n = { 0.000001, 100 } } }, { TOK_I2C_ADDR, "i2c_addr", "I2C Address", "Si570 I2C Address", "55", RIG_CONF_NUMERIC, { .n = { 0, 512 } } }, { TOK_BPF, "bpf", "BPF", "Enable Band Pass Filter", "0", RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /* * Common data struct */ struct si570xxxusb_priv_data { unsigned short version; /* >=0x0f00 is PE0FKO's */ double osc_freq; /* MHz */ double multiplier; /* default to 4 for QSD/QSE */ int i2c_addr; int bpf; /* enable BPF? */ }; #define SI570AVRUSB_MODES (RIG_MODE_USB) /* USB is for SDR */ #define SI570AVRUSB_FUNC (RIG_FUNC_NONE) #define SI570AVRUSB_LEVEL_ALL (RIG_LEVEL_NONE) /* TODO: BPF as a parm or ext_level? */ #define SI570AVRUSB_PARM_ALL (RIG_PARM_NONE) #define SI570AVRUSB_VFO (RIG_VFO_A) #define SI570AVRUSB_ANT (RIG_ANT_1) /* * SoftRock Si570 AVR-USB description * * Heavily based on SoftRock USB-I2C Utility usbsoftrock-0.5, * author Andrew Nilsson VK6JBL: * http://groups.yahoo.com/group/softrock40/files/VK6JBL/ * */ struct rig_caps si570avrusb_caps = { RIG_MODEL(RIG_MODEL_SI570AVRUSB), .model_name = "Si570 AVR-USB", .mfg_name = "SoftRock", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570avrusb_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Peaberry V1 * http://www.ae9rb.com */ struct rig_caps si570peaberry1_caps = { RIG_MODEL(RIG_MODEL_SI570PEABERRY1), .model_name = "Si570 Peaberry V1", .mfg_name = "AE9RB", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570peaberry1_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Peaberry V2 * http://www.ae9rb.com */ struct rig_caps si570peaberry2_caps = { RIG_MODEL(RIG_MODEL_SI570PEABERRY2), .model_name = "Si570 Peaberry V2", .mfg_name = "AE9RB", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(53.7), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570peaberry2_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * KTH-SDR-KIT Si570 PIC-USB description * * Same USB interface as AVR-USB, except different product string * and different multiplier. * * http://home.kpn.nl/rw.engberts/sdr_kth.htm */ struct rig_caps si570picusb_caps = { RIG_MODEL(RIG_MODEL_SI570PICUSB), .model_name = "Si570 PIC-USB", .mfg_name = "KTH-SDR kit", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, /* TODO */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(800), MHz(550), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(800), MHz(550), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = si570picusb_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = si570xxxusb_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .get_info = si570xxxusb_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Funkamateur Sdr with Si570 * * Same USB interface as AVR-USB, except different product string * and Oscillator correction may be stored on the device * * http://www.funkamateur.de * ( BX- 200 ) */ struct rig_caps fasdr_caps = { RIG_MODEL(RIG_MODEL_FASDR), .model_name = "FA-SDR", .mfg_name = "Funkamateur", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_FLAG_TUNER | RIG_FLAG_TRANSMITTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_USB, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 0, .has_get_func = SI570AVRUSB_FUNC, .has_set_func = SI570AVRUSB_FUNC, .has_get_level = SI570AVRUSB_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(SI570AVRUSB_LEVEL_ALL), .has_get_parm = SI570AVRUSB_PARM_ALL, .has_set_parm = RIG_PARM_SET(SI570AVRUSB_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { /* probably higher upper range, depending on type (CMOS, LVDS, ..) */ {kHz(1800), MHz(30), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(1800), MHz(30), SI570AVRUSB_MODES, -1, -1, SI570AVRUSB_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {SI570AVRUSB_MODES, Hz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { RIG_FLT_END, }, .cfgparams = si570xxxusb_cfg_params, .rig_init = fasdr_init, .rig_cleanup = si570xxxusb_cleanup, .rig_open = fasdr_open, .set_conf = si570xxxusb_set_conf, .get_conf = si570xxxusb_get_conf, .set_freq = si570xxxusb_set_freq, .get_freq = si570xxxusb_get_freq, .set_ptt = si570xxxusb_set_ptt, .get_info = si570xxxusb_get_info, }; // libusb control transfer request types #define REQUEST_TYPE_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN) #define REQUEST_TYPE_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT) /* * some little endian (these devices are LE) to host endian converters */ static unsigned char *setLongWord(uint32_t value, unsigned char *bytes) { bytes[0] = value & 0xff; bytes[1] = ((value & 0xff00) >> 8) & 0xff; bytes[2] = ((value & 0xff0000) >> 16) & 0xff; bytes[3] = ((value & 0xff000000) >> 24) & 0xff; return bytes; } static uint32_t getLongWord(unsigned char const *bytes) { return bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24); } /* * AVR-USB model */ int si570avrusb_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = AVR_PRODUCT_NAME; return RIG_OK; } /* * Peaberry V1 model (AVR version with different vendor/product name) */ int si570peaberry1_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = PEABERRY_VENDOR_NAME; rp->parm.usb.product = PEABERRY_PRODUCT_NAME; return RIG_OK; } /* * Peaberry V2 model (AVR version with different product name) */ int si570peaberry2_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PEABERRY_PRODUCT_NAME; return RIG_OK; } /* * PIC-USB model */ int si570picusb_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 2; priv->i2c_addr = SI570_I2C_ADDR; /* enable BPF, because this is kit is receiver only */ priv->bpf = 1; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = PIC_PRODUCT_NAME; return RIG_OK; } /* * FA-SDR */ int fasdr_init(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct si570xxxusb_priv_data *priv; STATE(rig)->priv = (struct si570xxxusb_priv_data *)calloc(sizeof(struct si570xxxusb_priv_data), 1); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = SI570_NOMINAL_XTALL_FREQ; /* QSD/QSE */ priv->multiplier = 4; priv->i2c_addr = SI570_I2C_ADDR; /* disable BPF, because it may share PTT I/O line */ priv->bpf = 0; rp->parm.usb.vid = USBDEV_SHARED_VID; rp->parm.usb.pid = USBDEV_SHARED_PID; /* no usb_set_configuration() and usb_claim_interface() */ rp->parm.usb.iface = -1; rp->parm.usb.conf = 1; rp->parm.usb.alt = 0; /* necessary ? */ rp->parm.usb.vendor_name = VENDOR_NAME; rp->parm.usb.product = AVR_PRODUCT_NAME; return RIG_OK; } int fasdr_open(RIG *rig) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret, i; double f; unsigned char buffer[4]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, buffer, 2, RIGPORT(rig)->timeout); if (ret != 2) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } priv->version = buffer[0] + (buffer[1] << 8); // Unsure how to get firmware version ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_EEPROM, F_CAL_STATUS, 0, buffer, 1, RIGPORT(rig)->timeout); if (ret != 1) { return -RIG_EIO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: calibration byte %x", __func__, buffer[0]); // ret = libusb_control_transfer(udh, // REQUEST_TYPE_IN, // REQUEST_READ_XTALL, 0, 0, (unsigned char *) &iFreq, sizeof(iFreq), // RIGPORT(rig)->timeout); if (buffer[0] == 0xFF) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Device not calibrated", __func__); return RIG_OK; } for (i = 0; i < 4; i++) { ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_EEPROM, F_CRYST + i, 0, &buffer[i], 1, RIGPORT(rig)->timeout); if (ret != 1) { return -RIG_EIO; } } priv->osc_freq = buffer[0]; f = buffer[1]; priv->osc_freq += f / 256.; f = buffer[2]; priv->osc_freq += f / (256.*256.); f = buffer[3]; priv->osc_freq += f / (256.*256.*256.); rig_debug(RIG_DEBUG_VERBOSE, "%s: using Xtall at %.3f MHz\n", __func__, priv->osc_freq); return RIG_OK; } int si570xxxusb_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int si570xxxusb_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct si570xxxusb_priv_data *priv; freq_t freq; double multiplier; unsigned int i2c_addr; priv = (struct si570xxxusb_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: if (sscanf(val, "%"SCNfreq, &freq) != 1) { return -RIG_EINVAL; } priv->osc_freq = (double)freq / 1e6; break; case TOK_MULTIPLIER: if (sscanf(val, "%lf", &multiplier) != 1) { return -RIG_EINVAL; } if (multiplier == 0.) { return -RIG_EINVAL; } priv->multiplier = multiplier; break; case TOK_I2C_ADDR: if (sscanf(val, "%x", &i2c_addr) != 1) { return -RIG_EINVAL; } if (i2c_addr >= (1 << 9)) { return -RIG_EINVAL; } priv->i2c_addr = i2c_addr; break; case TOK_BPF: if (sscanf(val, "%d", &priv->bpf) != 1) { return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } return RIG_OK; } int si570xxxusb_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct si570xxxusb_priv_data *priv; priv = (struct si570xxxusb_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, (freq_t)(priv->osc_freq * 1e6)); break; case TOK_MULTIPLIER: SNPRINTF(val, val_len, "%f", priv->multiplier); break; case TOK_I2C_ADDR: SNPRINTF(val, val_len, "%x", priv->i2c_addr); break; case TOK_BPF: SNPRINTF(val, val_len, "%d", priv->bpf); break; default: return -RIG_EINVAL; } return RIG_OK; } int si570xxxusb_get_conf(RIG *rig, hamlib_token_t token, char *val) { return si570xxxusb_get_conf2(rig, token, val, 128); } static int setBPF(RIG *rig, int enable) { libusb_device_handle *udh = RIGPORT(rig)->handle; /* allocate enough space for up to 16 filters */ unsigned short FilterCrossOver[16]; int nBytes; // Does FilterCrossOver needs endianness ordering ? // first find out how may cross over points there are for the 1st bank, use 255 for index nBytes = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_FILTERS, 0, 255, (unsigned char *) FilterCrossOver, sizeof(FilterCrossOver), RIGPORT(rig)->timeout); if (nBytes < 0) { return -RIG_EIO; } if (nBytes > 2) { int i; int retval = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_FILTERS, enable, (nBytes / 2) - 1, (unsigned char *) FilterCrossOver, sizeof(FilterCrossOver), RIGPORT(rig)->timeout); if (retval < 2) { return -RIG_EIO; } nBytes = retval; rig_debug(RIG_DEBUG_TRACE, "%s: Filter Bank 1:\n", __func__); for (i = 0; i < (nBytes / 2) - 1; i++) { rig_debug(RIG_DEBUG_TRACE, " CrossOver[%d] = %f\n", i, (double) FilterCrossOver[i] / (1UL << 5)); } rig_debug(RIG_DEBUG_TRACE, " BPF Enabled: %d\n", FilterCrossOver[(nBytes / 2) - 1]); } return RIG_OK; } int si570xxxusb_open(RIG *rig) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[4]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* * Determine firmware */ ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, buffer, 2, RIGPORT(rig)->timeout); if (ret != 2) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } priv->version = buffer[0] + (buffer[1] << 8); if (priv->version >= 0x0F00 || rig->caps->rig_model == RIG_MODEL_SI570PICUSB) { unsigned int iFreq; rig_debug(RIG_DEBUG_VERBOSE, "%s: detected PE0FKO-like firmware\n", __func__); ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_XTALL, 0, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret != 4) { return -RIG_EIO; } iFreq = getLongWord(buffer); priv->osc_freq = (double)iFreq / (1UL << 24); if (priv->bpf) { ret = setBPF(rig, 1); if (ret != RIG_OK) { return ret; } } } rig_debug(RIG_DEBUG_VERBOSE, "%s: using Xtall at %.3f MHz\n", __func__, priv->osc_freq); return RIG_OK; } /* Rem: not reentrant */ const char *si570xxxusb_get_info(RIG *rig) { static char buf[64]; libusb_device_handle *udh = RIGPORT(rig)->handle; struct libusb_device_descriptor desc; int ret; unsigned char buffer[2]; ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_VERSION, 0x0E00, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret != 2) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return NULL; } /* always succeeds since libusb-1.0.16 */ libusb_get_device_descriptor(libusb_get_device(udh), &desc); SNPRINTF(buf, sizeof(buf), "USB dev %04d, version: %d.%d", desc.bcdDevice, buffer[1], buffer[0]); return buf; } static const int HS_DIV_MAP[] = {4, 5, 6, 7, -1, 9, -1, 11}; static int calcDividers(RIG *rig, double f, struct solution *solution) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; struct solution sols[8]; int i; int imin; double fmin; double y; // Count down through the dividers for (i = 7; i >= 0; i--) { if (HS_DIV_MAP[i] > 0) { sols[i].HS_DIV = i; y = (SI570_DCO_HIGH + SI570_DCO_LOW) / (2 * f); y = y / HS_DIV_MAP[i]; if (y < 1.5) { y = 1.0; } else { y = 2 * round(y / 2.0); } if (y > 128) { y = 128; } sols[i].N1 = trunc(y) - 1; sols[i].f0 = f * y * HS_DIV_MAP[i]; } else { sols[i].f0 = 10000000000000000.0; } } imin = -1; fmin = 10000000000000000.0; for (i = 0; i < 8; i++) { if ((sols[i].f0 >= SI570_DCO_LOW) && (sols[i].f0 <= SI570_DCO_HIGH)) { if (sols[i].f0 < fmin) { fmin = sols[i].f0; imin = i; } } } if (imin >= 0) { solution->HS_DIV = sols[imin].HS_DIV; solution->N1 = sols[imin].N1; solution->f0 = sols[imin].f0; solution->RFREQ = sols[imin].f0 / priv->osc_freq; rig_debug(RIG_DEBUG_TRACE, "%s: solution: HS_DIV = %d, N1 = %d, f0 = %f, RFREQ = %f\n", __func__, solution->HS_DIV, solution->N1, solution->f0, solution->RFREQ); return 1; } else { solution->HS_DIV = 0; solution->N1 = 0; solution->f0 = 0; solution->RFREQ = 0; rig_debug(RIG_DEBUG_TRACE, "%s: No solution\n", __func__); return 0; } } int si570xxxusb_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[6]; int request = REQUEST_SET_FREQ; int value = 0x700 + priv->i2c_addr; int index = 0; double f; struct solution theSolution; int RFREQ_int; int RFREQ_frac; unsigned char fracBuffer[4]; unsigned char intBuffer[4]; if (priv->version >= 0x0f00 || rig->caps->rig_model == RIG_MODEL_SI570PICUSB || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY1 || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY2) { return si570xxxusb_set_freq_by_value(rig, vfo, freq); } f = (freq * priv->multiplier) / 1e6; calcDividers(rig, f, &theSolution); RFREQ_int = trunc(theSolution.RFREQ); RFREQ_frac = round((theSolution.RFREQ - RFREQ_int) * 268435456); setLongWord(RFREQ_int, intBuffer); setLongWord(RFREQ_frac, fracBuffer); buffer[5] = fracBuffer[0]; buffer[4] = fracBuffer[1]; buffer[3] = fracBuffer[2]; buffer[2] = fracBuffer[3]; buffer[2] = buffer[2] | ((intBuffer[0] & 0xf) << 4); buffer[1] = RFREQ_int / 16; buffer[1] = buffer[1] + ((theSolution.N1 & 3) << 6); buffer[0] = theSolution.N1 / 4; buffer[0] = buffer[0] + (theSolution.HS_DIV << 5); ret = libusb_control_transfer(udh, REQUEST_TYPE_OUT, request, value, index, buffer, sizeof(buffer), RIGPORT(rig)->timeout); rig_debug(RIG_DEBUG_TRACE, "%s: Freq=%.6f MHz, Real=%.6f MHz, buf=%02x%02x%02x%02x%02x%02x\n", __func__, freq / 1e6, f, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); if (!ret) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Result buf=%02x%02x\n", __func__, buffer[0], buffer[1]); return RIG_OK; } int si570xxxusb_set_freq_by_value(RIG *rig, vfo_t vfo, freq_t freq) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[4]; int request = REQUEST_SET_FREQ_BY_VALUE; int value = 0x700 + priv->i2c_addr; int index = 0; double f; f = (freq * priv->multiplier) / 1e6; setLongWord(round(f * 2097152.0), buffer); rig_debug(RIG_DEBUG_TRACE, "%s: Freq=%.6f MHz, Real=%.6f MHz, buf=%02x%02x%02x%02x\n", __func__, freq / 1e6, f, buffer[0], buffer[1], buffer[2], buffer[3]); ret = libusb_control_transfer(udh, REQUEST_TYPE_OUT, request, value, index, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (!ret) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } rig_debug(RIG_DEBUG_TRACE, "%s: Result buf=%02x%02x\n", __func__, buffer[0], buffer[1]); return RIG_OK; } static double calculateFrequency(RIG *rig, const unsigned char *buffer) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; int RFREQ_int = ((buffer[2] & 0xf0) >> 4) + ((buffer[1] & 0x3f) * 16); int RFREQ_frac = (256 * 256 * 256 * (buffer[2] & 0xf)) + (256 * 256 * buffer[3]) + (256 * buffer[4]) + (buffer[5]); double RFREQ = RFREQ_int + (RFREQ_frac / 268435456.0); int N1 = ((buffer[1] & 0xc0) >> 6) + ((buffer[0] & 0x1f) * 4); int HS_DIV = (buffer[0] & 0xE0) >> 5; double fout = priv->osc_freq * RFREQ / ((N1 + 1) * HS_DIV_MAP[HS_DIV]); rig_debug(RIG_DEBUG_VERBOSE, "%s: Registers 7..13: %02x%02x%02x%02x%02x%02x\n", __func__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); rig_debug(RIG_DEBUG_VERBOSE, "%s: RFREQ = %f, N1 = %d, HS_DIV = %d, nHS_DIV = %d, fout = %f\n", __func__, RFREQ, N1, HS_DIV, HS_DIV_MAP[HS_DIV], fout); return fout; } int si570xxxusb_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; unsigned char buffer[6]; int ret; if (priv->version >= 0x0f00 || rig->caps->rig_model == RIG_MODEL_SI570PICUSB || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY1 || rig->caps->rig_model == RIG_MODEL_SI570PEABERRY2) { return si570xxxusb_get_freq_by_value(rig, vfo, freq); } ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_REGISTERS, priv->i2c_addr, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret <= 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } *freq = (calculateFrequency(rig, buffer) / priv->multiplier) * 1e6; return RIG_OK; } int si570xxxusb_get_freq_by_value(RIG *rig, vfo_t vfo, freq_t *freq) { const struct si570xxxusb_priv_data *priv = (struct si570xxxusb_priv_data *) STATE(rig)->priv; libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[4]; uint32_t iFreq; ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_READ_FREQUENCY, 0, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret != 4) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } iFreq = getLongWord(buffer); rig_debug(RIG_DEBUG_VERBOSE, "%s: Freq raw: %02x%02x%02x%02x endian converted: %u\n", __func__, buffer[0], buffer[1], buffer[2], buffer[3], iFreq); *freq = (((double)iFreq / (1UL << 21)) / priv->multiplier) * 1e6; return RIG_OK; } int si570xxxusb_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { libusb_device_handle *udh = RIGPORT(rig)->handle; int ret; unsigned char buffer[3]; rig_debug(RIG_DEBUG_TRACE, "%s called: %d\n", __func__, ptt); buffer[0] = 0; buffer[1] = 0; buffer[2] = 0; ret = libusb_control_transfer(udh, REQUEST_TYPE_IN, REQUEST_SET_PTT, (ptt == RIG_PTT_ON) ? 1 : 0, 0, buffer, sizeof(buffer), RIGPORT(rig)->timeout); if (ret < 0) { rig_debug(RIG_DEBUG_ERR, "%s: libusb_control_transfer failed: %s\n", __func__, libusb_error_name(ret)); return -RIG_EIO; } return RIG_OK; } #endif /* defined(HAVE_LIBUSB) && defined(HAVE_LIBUSB_H) */ hamlib-4.6.2/rigs/kit/rs_hfiq.c0000644000175000017500000002573614752216205013253 00000000000000/* * Hamlib rs-hfiq backend - main file * Copyright (c) 2017 by Volker Schroer * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * * For information about the controls see * https://sites.google.com/site/rshfiqtransceiver/home/technical-data/interface-commands * */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #define RSHFIQ_INIT_RETRY 5 #define RSHFIQ_LEVEL_ALL (RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_TEMP_METER) int rshfiq_version_major, rshfiq_version_minor; static int rshfiq_open(RIG *rig) { int retval; int flag; char versionstr[20]; char stopset[2]; hamlib_port_t *rp = RIGPORT(rig); stopset[0] = '\r'; stopset[1] = '\n'; rig_debug(RIG_DEBUG_TRACE, "%s: Port = %s\n", __func__, rp->pathname); rp->timeout = 2000; rp->retry = 1; retval = serial_open(rp); if (retval != RIG_OK) { return retval; } retval = ser_get_dtr(rp, &flag); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: DTR: %d\n", __func__, flag); } else { rig_debug(RIG_DEBUG_TRACE, "%s: Could not get DTR\n", __func__); } if (flag == 0) { flag = 1; // Set DTR retval = ser_set_dtr(rp, flag); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: set DTR\n", __func__); } } //There is a delay between when the port is open and the RS-HFIQ can receive and respond. //Make a few attempts at getting the version string just in case the RS-HFIQ has to catch up first. retval = -RIG_ETIMEOUT; for (int init_retry_count = 0; (init_retry_count < RSHFIQ_INIT_RETRY) && (retval == -RIG_ETIMEOUT); init_retry_count++) { rig_flush(rp); SNPRINTF(versionstr, sizeof(versionstr), "*w\r"); rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, versionstr); retval = write_block(rp, (unsigned char *) versionstr, strlen(versionstr)); if (retval != RIG_OK) { return retval; } retval = read_string(rp, (unsigned char *) versionstr, 20, stopset, 2, 0, 1); } if (retval <= 0) { return retval; } rig_flush(rp); versionstr[retval] = 0; rig_debug(RIG_DEBUG_TRACE, "%s: Rigversion = %s\n", __func__, versionstr); if (!strstr(versionstr, "RS-HFIQ")) { rig_debug(RIG_DEBUG_WARN, "%s: Invalid Rigversion: %s\n", __func__, versionstr); return -RIG_ECONF; } retval = sscanf(versionstr, "RS-HFIQ FW %d.%d", &rshfiq_version_major, &rshfiq_version_minor); if (retval <= 0) { rig_debug(RIG_DEBUG_WARN, "%s: Failed to parse RS-HFIQ firmware version string. Defaulting to 2.0.\n", __func__); rshfiq_version_major = 2; rshfiq_version_minor = 0; } rig_debug(RIG_DEBUG_VERBOSE, "RS-HFIQ returned firmware version major=%d minor=%d\n", rshfiq_version_major, rshfiq_version_minor); if (rshfiq_version_major < 4) { rig_debug(RIG_DEBUG_WARN, "%s: RS-HFIQ firmware major version is less than 4. RFPOWER_METER support will be unavailable.\n", __func__); } return RIG_OK; } static int rshfiq_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char fstr[9]; char cmdstr[15]; int retval; hamlib_port_t *rp = RIGPORT(rig); SNPRINTF(fstr, sizeof(fstr), "%lu", (unsigned long int)(freq)); rig_debug(RIG_DEBUG_TRACE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "*f%lu\r", (unsigned long int)(freq)); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int rshfiq_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char cmdstr[15]; char stopset[2]; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); stopset[0] = '\r'; stopset[1] = '\n'; SNPRINTF(cmdstr, sizeof(cmdstr), "*f?\r"); rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } retval = read_string(rp, (unsigned char *) cmdstr, 9, stopset, 2, 0, 1); if (retval <= 0) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: reply = %s\n", __func__, cmdstr); cmdstr[retval] = 0; *freq = atoi(cmdstr); if (*freq == 0) // fldigi interprets zero frequency as error { *freq = 1; // so return 1 ( freq= 1Hz ) } return RIG_OK; } static int rshfiq_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmdstr[5]; int retval; cmdstr[0] = '*'; cmdstr[1] = 'x'; cmdstr[3] = '\r'; cmdstr[4] = 0; if (ptt == RIG_PTT_ON) { cmdstr[2] = '1'; } else { cmdstr[2] = '0'; } rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); retval = write_block(RIGPORT(rig), (unsigned char *) cmdstr, strlen(cmdstr)); return retval; } static int rshfiq_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { // cppcheck-suppress syntaxError rig_debug(RIG_DEBUG_VERBOSE, "%s called. level type =%"PRIll"\n", __func__, level); char cmdstr[15]; char stopset[2]; int retval; hamlib_port_t *rp = RIGPORT(rig); if (!val) { return -RIG_EINVAL; } switch (level) { //Requires RS-HFIQ firmware version 4 or later case RIG_LEVEL_RFPOWER_METER: if (rshfiq_version_major <= 3) { return -RIG_ENAVAIL; } rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "*L\r"); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_RFPOWER_METER command=%s\n", cmdstr); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } stopset[0] = '\r'; stopset[1] = '\n'; retval = read_string(rp, (unsigned char *) cmdstr, 9, stopset, 2, 0, 1); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_RFPOWER_METER reply=%s\n", cmdstr); if (retval <= 0) { return retval; } cmdstr[retval] = 0; //Range is 0-110. Unit is percent val->i = atoi(cmdstr); val->f = (float)(val->i) / 100; rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_RFPOWER_METER val=%f\n", val->f); return RIG_OK; case RIG_LEVEL_TEMP_METER: rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "*T\r"); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_TEMP_METER command=%s\n", cmdstr); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } stopset[0] = '\r'; stopset[1] = '\n'; retval = read_string(rp, (unsigned char *) cmdstr, 9, stopset, 2, 0, 1); rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_TEMP_METER reply=%s\n", cmdstr); if (retval <= 0) { return retval; } cmdstr[retval] = 0; sscanf(cmdstr, "%d.", &val->i); val->f = val->i; rig_debug(RIG_DEBUG_TRACE, "RIG_LEVEL_TEMP_METER val=%g\n", val->f); return RIG_OK; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Unrecognized RIG_LEVEL_* enum: %"PRIll"\n", __func__, level); return -RIG_EDOM; } } static int rshfiq_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { *mode = RIG_MODE_IQ; return RIG_OK; } struct rig_caps rshfiq_caps = { RIG_MODEL(RIG_MODEL_RSHFIQ), .model_name = "RS-HFIQ", .mfg_name = "HobbyPCB", .version = "20220430.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .dcd_type = RIG_DCD_NONE, .serial_rate_min = 57600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .has_get_level = RSHFIQ_LEVEL_ALL, .rx_range_list1 = { {.startf = kHz(3500), .endf = MHz(30), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, RIG_FRNG_END, }, .rx_range_list2 = { {.startf = kHz(3500), .endf = MHz(30), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { {.startf = kHz(3500), .endf = kHz(3800), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = kHz(7000), .endf = kHz(7200), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = kHz(10100), .endf = kHz(10150), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = MHz(14), .endf = kHz(14350), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = MHz(21), .endf = kHz(21450), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = kHz(24890), .endf = kHz(24990), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, {.startf = MHz(28), .endf = kHz(29700), .modes = RIG_MODE_IQ, .low_power = 0, .high_power = 0, RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_IQ, Hz(1)}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .rig_open = rshfiq_open, .get_freq = rshfiq_get_freq, .set_freq = rshfiq_set_freq, .set_ptt = rshfiq_set_ptt, .get_level = rshfiq_get_level, .get_mode = rshfiq_get_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kit/usrp_impl.cc0000644000175000017500000000775014752216205013771 00000000000000/* * Hamlib KIT backend - Universal Software Radio Peripheral * Copyright (c) 2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* * Compile only this model if usrp is available */ #if defined(HAVE_USRP) #include #include #include #include #include "usrp_impl.h" #include "token.h" struct usrp_priv_data { usrp_standard_rx *urx; usrp_standard_tx *utx; freq_t if_mix_freq; }; int usrp_init(RIG *rig) { // cppcheck-suppress leakReturnValNotUsed STATE(rig)->priv = static_castmalloc(sizeof(struct usrp_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } return RIG_OK; } int usrp_cleanup(RIG *rig) { if (!rig) return -RIG_EINVAL; if (STATE(rig)->priv) free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } int usrp_open(RIG *rig) { struct usrp_priv_data *priv = static_castSTATE(rig)->priv; int which_board = 0; int decim = 125; priv->urx = usrp_standard_rx::make (which_board, decim, 1, -1, usrp_standard_rx::FPGA_MODE_NORMAL).get(); if (priv->urx == 0) return -RIG_EIO; return RIG_OK; } int usrp_close(RIG *rig) { struct usrp_priv_data *priv = static_castSTATE(rig)->priv; if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } delete priv->urx; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int usrp_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct usrp_priv_data *priv = static_castSTATE(rig)->priv; if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } switch(token) { case TOK_IFMIXFREQ: sscanf(val, "%"SCNfreq, &priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int usrp_get_conf(RIG *rig, hamlib_token_t token, char *val) { const struct usrp_priv_data *priv = static_castSTATE(rig)->priv; if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } switch(token) { case TOK_IFMIXFREQ: sprintf(val, "%"PRIfreq, priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } int usrp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct usrp_priv_data *priv = static_castSTATE(rig)->priv; int chan = 0; if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } if (!priv->urx->set_rx_freq (chan, freq)) return -RIG_EPROTO; return RIG_OK; } int usrp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct usrp_priv_data *priv = static_castSTATE(rig)->priv; int chan = 0; if (!priv) { rig_debug(RIG_DEBUG_ERR, "%s: priv == NULL?\n", __func__); return -RIG_EARG; } *freq = priv->urx->rx_freq (chan); return RIG_OK; } const char * usrp_get_info(RIG *rig) { return NULL; } #endif /* HAVE_USRP */ hamlib-4.6.2/rigs/kit/kit.c0000644000175000017500000000430114752216205012370 00000000000000/* * Hamlib KIT backend - main file * Copyright (c) 2004-2012 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "register.h" #include "kit.h" /* * initrigs_kit is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(kit) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&elektor304_caps); rig_register(&drt1_caps); rig_register(&dds60_caps); rig_register(&miniVNA_caps); rig_register(&hiqsdr_caps); rig_register(&rshfiq_caps); #if (defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H))) rig_register(&si570avrusb_caps); rig_register(&si570picusb_caps); rig_register(&si570peaberry1_caps); rig_register(&si570peaberry2_caps); rig_register(&funcube_caps); rig_register(&fifisdr_caps); rig_register(&fasdr_caps); rig_register(&funcubeplus_caps); #endif #if (defined(HAVE_LIBUSB) && (defined(HAVE_LIBUSB_H) || defined(HAVE_LIBUSB_1_0_LIBUSB_H))) || defined(_WIN32) /* rigs with alternate DLL support on Win32 */ rig_register(&dwt_caps); rig_register(&elektor507_caps); #endif #ifdef HAVE_USRP //rig_register(&usrp0_caps); rig_register(&usrp_caps); #endif return RIG_OK; } /* * initrots_kit is called by rot_backend_load */ DECLARE_INITROT_BACKEND(kit) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rot_register(&pcrotor_caps); return RIG_OK; } hamlib-4.6.2/rigs/kit/README.funcubedongle0000644000175000017500000000444214752216205015142 00000000000000+----------------------------------------+ | Hamlib FUNcube dongle Win32 readme | | Written by Wouter Weggelaar PA3WEG | |ISIS - Innovative Solutions In Space BV | +----------------------------------------+ Note: The following only applies for users running Win32 systems. First of all, congratulations on obtaining a FUNcube dongle, the SDR receiver ground segment for the FUNcube satellite! More info on this exciting AMSAT-UK project can be found on http://funcube.org.uk/ more about the dongle on http://www.funcubedongle.com/ The FUNcube dongle driver uses the USB kit backend in hamlib to interface to the dongle via the USB HID interface. For this to work in hamlib, we need LibUSB support (tested with 1.2.3.0 and 1.2.4.0) and LibUSB support compiled into hamlib. This should be the case for all official hamlib releases (hamlib-win32-1.2.13-2 tested). You will need to download and install libusb-win32 from http://sourceforge.net/projects/libusb-win32/ extract the zip archive to a convenient location, change into this directory and run inf-wizard.exe located in the bin directory. Select the proper device in this wizard (Vendor ID 0x04D8, Product ID 0xFB56, interface 2) Click NEXT and accept the defaults, or change the vendor name and product ID as you wish to see it appear in device manager. I've changed this ID to reflect the vendor (hanlincrest ltd) and product name (funcube dongle). You can now suggest a location to store the driver (I suggest creating a directory for this as the wizard creates more than one file). Finally, install the driver as suggested by the wizard. You should be all set up now. Running hamlib from the command line using rigctl -m 2513 -vvvv should provide something like below: ------------------------------------------ >rigctl.exe -m 2513 -v Opened rig model 2513, 'FUNcube Dongle' Rig command: ------------------------------------------ If you made it to here, you are all set up and ready to go. **** PLEASE NOTE: by installing the LibUSB INF driver, other tools accessing the dongle cannot find it anymore as they are looking for the windows HID driver. Just uninstall the hamlib driver if you want to use those tools again! HAMLIB or LibUSB DID NOT BREAK YOUR SYSTEM! **** You could use hardware profiles to easily switch drivers. Happy SDR-ing! Wouter PA3WEG hamlib-4.6.2/rigs/kit/elektor304.c0000644000175000017500000002212414752216205013500 00000000000000/* * Hamlib KIT backend - Elektor DRM receiver description * Copyright (c) 2004-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "token.h" #define ELEKTOR304_MODES (RIG_MODE_AM) #define ELEKTOR304_FUNC (RIG_FUNC_NONE) #define ELEKTOR304_LEVEL_ALL (RIG_LEVEL_NONE) #define ELEKTOR304_PARM_ALL (RIG_PARM_NONE) #define ELEKTOR304_VFO (RIG_VFO_A) /* defaults */ #define OSCFREQ MHz(50) #define IFMIXFREQ kHz(454.3) struct elektor304_priv_data { freq_t osc_freq; freq_t if_mix_freq; }; #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_IFMIXFREQ TOKEN_BACKEND(2) static const struct confparams elektor304_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillatorfreq", "Oscillator frequency in Hz", "50000000", RIG_CONF_NUMERIC, { .n = { 0, GHz(2), 1 } } }, { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "454300", RIG_CONF_NUMERIC, { .n = { 0, MHz(100), 1 } } }, { RIG_CONF_END, NULL, } }; static int elektor304_init(RIG *rig); static int elektor304_cleanup(RIG *rig); static int elektor304_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int elektor304_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int elektor304_get_conf(RIG *rig, hamlib_token_t token, char *val); /* * The Elektor DRM Receiver 3/04 COM interface is based on the Visual Basic * source code by Burkhard Kainka which can be downloaded from www.b-kainka.de * Linux support is based on a code written by Markus März: * http://mitglied.lycos.de/markusmaerz/drm * Linux support is available from DRM Dream project. * * The DDS is a AD9835. * * The receiver is controlled via the TX, RTS and DTR pins of the serial port. */ struct rig_caps elektor304_caps = { RIG_MODEL(RIG_MODEL_ELEKTOR304), .model_name = "Elektor 3/04", .mfg_name = "Elektor", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, /* bit banging */ .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = ELEKTOR304_FUNC, .has_set_func = ELEKTOR304_FUNC, .has_get_level = ELEKTOR304_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ELEKTOR304_LEVEL_ALL), .has_get_parm = ELEKTOR304_PARM_ALL, .has_set_parm = RIG_PARM_SET(ELEKTOR304_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(22), ELEKTOR304_MODES, -1, -1, ELEKTOR304_VFO}, /* TBC */ RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(22), ELEKTOR304_MODES, -1, -1, ELEKTOR304_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ELEKTOR304_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {ELEKTOR304_MODES, kHz(12)}, RIG_FLT_END, }, .cfgparams = elektor304_cfg_params, .rig_init = elektor304_init, .rig_cleanup = elektor304_cleanup, .set_conf = elektor304_set_conf, .get_conf = elektor304_get_conf, .set_freq = elektor304_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int elektor304_init(RIG *rig) { struct elektor304_priv_data *priv; STATE(rig)->priv = (struct elektor304_priv_data *)calloc(1, sizeof(struct elektor304_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = OSCFREQ; priv->if_mix_freq = IFMIXFREQ; return RIG_OK; } int elektor304_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int elektor304_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct elektor304_priv_data *priv; priv = (struct elektor304_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &priv->osc_freq); break; case TOK_IFMIXFREQ: sscanf(val, "%"SCNfreq, &priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int elektor304_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct elektor304_priv_data *priv; priv = (struct elektor304_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq); break; case TOK_IFMIXFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->if_mix_freq); break; default: return -RIG_EINVAL; } return RIG_OK; } int elektor304_get_conf(RIG *rig, hamlib_token_t token, char *val) { return elektor304_get_conf2(rig, token, val, 128); } #define AD_DELAY 4000 /* * Introduce delay after changing the bit state * FIXME: This implementation may not work for very fast computers, * or smart compilers. However, nanosleep can have * granularity > 10ms! */ static int ad_delay(int m) { long j; for (j = 0; j <= m; j++) {} return j; } static int ad_sdata(hamlib_port_t *port, int i) { int ret; ret = ser_set_rts(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_sclk(const hamlib_port_t *port, int i) { int ret; ret = ser_set_brk(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_fsync(hamlib_port_t *port, int i) { int ret; ret = ser_set_dtr(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_write(hamlib_port_t *port, unsigned data) { unsigned mask = 0x8000; int i; ad_sclk(port, 0); /* TXD 0 */ ad_fsync(port, 1); /* DTR 1, CE */ for (i = 0; i < 16; i++) { ad_sdata(port, (data & mask) ? 0 : 1); /* RTS 0 or 1 */ ad_sclk(port, 1); /* TXD 1, clock */ ad_sclk(port, 0); /* TXD 0 */ mask >>= 1; /* Next bit for masking */ } ad_fsync(port, 0); /* DTR 0 */ return RIG_OK; } int elektor304_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long frg; unsigned fhl, fhh, fll, flh; struct elektor304_priv_data *priv; hamlib_port_t *port = RIGPORT(rig); priv = (struct elektor304_priv_data *)STATE(rig)->priv; rig_flush(port); /* Initialization */ ad_fsync(port, 0); ad_sdata(port, 0); ad_sclk(port, 0); /* all frequencies are in Hz */ frg = (unsigned long)(((double)freq + priv->if_mix_freq) / priv->osc_freq * 4294967296.0 + 0.5); fll = frg & 0xff; flh = (frg >> 8) & 0xff; fhl = (frg >> 16) & 0xff; fhh = (frg >> 24) & 0xff; rig_debug(RIG_DEBUG_VERBOSE, "%s: %lu=[%02x.%02x.%02x.%02x]\n", __func__, frg, fll, flh, fhl, fhh); ad_write(port, 0xF800); /* Reset */ ad_write(port, 0x3000 | fll); /* 4 Bytes to FREQ0 */ ad_write(port, 0x2100 | flh); ad_write(port, 0x3200 | fhl); ad_write(port, 0x2300 | fhh); ad_write(port, 0x8000); /* Sync */ ad_write(port, 0xC000); /* Reset end */ return RIG_OK; } hamlib-4.6.2/rigs/kit/usrp.c0000644000175000017500000000752414752216205012604 00000000000000/* * Hamlib KIT backend - Universal Software Radio Peripheral description * Copyright (c) 2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Compile only this model if usrp is available */ #if defined(HAVE_USRP) #include #include #include #include "hamlib/rig.h" #include "usrp_impl.h" #include "token.h" #define USRP_MODES (RIG_MODE_NONE) #define USRP_FUNC (RIG_FUNC_NONE) #define USRP_LEVEL_ALL (RIG_LEVEL_NONE) #define USRP_PARM_ALL (RIG_PARM_NONE) #define USRP_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_C|RIG_VFO_N(3)) static const struct confparams usrp_cfg_params[] = { { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "45000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(400), 1 } } }, { RIG_CONF_END, NULL } }; /* * GNU Radio Universal Software Radio Peripheral * */ struct rig_caps usrp_caps = { RIG_MODEL(RIG_MODEL_USRP), .model_name = "USRP", .mfg_name = "GNU Radio", .version = "0.1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NONE, .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = USRP_FUNC, .has_set_func = USRP_FUNC, .has_get_level = USRP_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(USRP_LEVEL_ALL), .has_get_parm = USRP_PARM_ALL, .has_set_parm = RIG_PARM_SET(USRP_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30), USRP_MODES, -1, -1, USRP_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, USRP_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30), USRP_MODES, -1, -1, USRP_VFO}, {kHz(87.5), MHz(108), RIG_MODE_WFM, -1, -1, USRP_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {USRP_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {USRP_MODES, kHz(40)}, /* FIXME */ RIG_FLT_END, }, .cfgparams = usrp_cfg_params, .rig_init = usrp_init, .rig_cleanup = usrp_cleanup, .rig_open = usrp_open, .rig_close = usrp_close, .set_conf = usrp_set_conf, .get_conf = usrp_get_conf, .set_freq = usrp_set_freq, .get_freq = usrp_get_freq, .get_info = usrp_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #endif /* HAVE_USRP */ hamlib-4.6.2/rigs/kit/miniVNA.c0000644000175000017500000000544614752216205013115 00000000000000/* * Hamlib miniVNA backend - main file * Copyright (c) 2001-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #define DDS_RATIO 10.73741824 static int miniVNA_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char fstr[20]; char cmdstr[40]; int retval; hamlib_port_t *rp = RIGPORT(rig); sprintf_freq(fstr, sizeof(fstr), freq); rig_debug(RIG_DEBUG_TRACE, "%s called: %s %s\n", __func__, rig_strvfo(vfo), fstr); rig_flush(rp); SNPRINTF(cmdstr, sizeof(cmdstr), "0\r%lu\r1\r0\r", (unsigned long int)(freq * DDS_RATIO)); retval = write_block(rp, (unsigned char *) cmdstr, strlen(cmdstr)); if (retval != RIG_OK) { return retval; } return RIG_OK; } struct rig_caps miniVNA_caps = { RIG_MODEL(RIG_MODEL_MINIVNA), .model_name = "miniVNA", .mfg_name = "mRS", .version = "20190817.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .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_NONE, .write_delay = 0, .post_write_delay = 1, .timeout = 1000, .retry = 3, .rx_range_list1 = { {.startf = kHz(100), .endf = MHz(180), .modes = RIG_MODE_CW, .low_power = -1, .high_power = -1, RIG_VFO_A}, RIG_FRNG_END, }, .tx_range_list1 = { {.startf = kHz(100), .endf = MHz(180), .modes = RIG_MODE_CW, .low_power = W(0), .high_power = W(.004), RIG_VFO_A}, RIG_FRNG_END, }, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .set_freq = miniVNA_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kit/drt1.c0000644000175000017500000002472414752216205012466 00000000000000/* * Hamlib KIT backend - Sat-Schneider DRT1/SAD1 DRM receiver description * Copyright (c) 2004-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "token.h" #define DRT1_MODES (RIG_MODE_AM) #define DRT1_FUNC (RIG_FUNC_NONE) #define DRT1_LEVEL_ALL (RIG_LEVEL_NONE) #define DRT1_PARM_ALL (RIG_PARM_NONE) #define DRT1_VFO (RIG_VFO_A) /* defaults */ #define OSCFREQ MHz(45.012) #define IFMIXFREQ MHz(45) #define REFMULT 8 #define CHARGE_PUMP_CURRENT 150 struct drt1_priv_data { freq_t osc_freq; freq_t if_mix_freq; unsigned ref_mult; unsigned pump_crrnt; }; #define TOK_OSCFREQ TOKEN_BACKEND(1) #define TOK_IFMIXFREQ TOKEN_BACKEND(2) #define TOK_REFMULT TOKEN_BACKEND(3) #define TOK_PUMPCRNT TOKEN_BACKEND(4) static const struct confparams drt1_cfg_params[] = { { TOK_OSCFREQ, "osc_freq", "Oscillatorfreq", "Oscillator frequency in Hz", "45012000", RIG_CONF_NUMERIC, { .n = { 0, MHz(400), 1 } } }, { TOK_IFMIXFREQ, "if_mix_freq", "IF", "IF mixing frequency in Hz", "45000000", RIG_CONF_NUMERIC, { .n = { 0, MHz(400), 1 } } }, { TOK_REFMULT, "ref_mult", "REFCLK Multiplier", "REFCLK Multiplier", "8", RIG_CONF_NUMERIC, { .n = { 4, 20, 1 } } }, { TOK_PUMPCRNT, "pump_current", "Charge pump current", "Charge pump current in uA", "150", RIG_CONF_NUMERIC, { .n = { 75, 150, 25 } } }, { RIG_CONF_END, NULL, } }; static int drt1_init(RIG *rig); static int drt1_cleanup(RIG *rig); static int drt1_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int drt1_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int drt1_get_conf(RIG *rig, hamlib_token_t token, char *val); /* * SAT-Service Schneider DRM tuner. * * The receiver is controlled via the TX, RTS and DTR pins of the serial port. */ struct rig_caps drt1_caps = { RIG_MODEL(RIG_MODEL_DRT1), .model_name = "DRT1", .mfg_name = "SAT-Schneider", .version = "20200112.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, /* bit banging */ .serial_rate_min = 9600, /* don't care */ .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 0, .has_get_func = DRT1_FUNC, .has_set_func = DRT1_FUNC, .has_get_level = DRT1_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DRT1_LEVEL_ALL), .has_get_parm = DRT1_PARM_ALL, .has_set_parm = RIG_PARM_SET(DRT1_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(50), MHz(30), DRT1_MODES, -1, -1, DRT1_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(50), MHz(30), DRT1_MODES, -1, -1, DRT1_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {DRT1_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {DRT1_MODES, kHz(10)}, /* opt. 20 kHz */ RIG_FLT_END, }, .cfgparams = drt1_cfg_params, .rig_init = drt1_init, .rig_cleanup = drt1_cleanup, .set_conf = drt1_set_conf, .get_conf = drt1_get_conf, .set_freq = drt1_set_freq, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int drt1_init(RIG *rig) { struct drt1_priv_data *priv; STATE(rig)->priv = (struct drt1_priv_data *)calloc(1, sizeof( struct drt1_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->osc_freq = OSCFREQ; priv->ref_mult = REFMULT; priv->if_mix_freq = IFMIXFREQ; priv->pump_crrnt = CHARGE_PUMP_CURRENT; return RIG_OK; } int drt1_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int drt1_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct drt1_priv_data *priv; priv = (struct drt1_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: sscanf(val, "%"SCNfreq, &priv->osc_freq); break; case TOK_REFMULT: sscanf(val, "%u", &priv->ref_mult); break; case TOK_IFMIXFREQ: sscanf(val, "%"SCNfreq, &priv->if_mix_freq); break; case TOK_PUMPCRNT: sscanf(val, "%u", &priv->pump_crrnt); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int drt1_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct drt1_priv_data *priv; priv = (struct drt1_priv_data *)STATE(rig)->priv; switch (token) { case TOK_OSCFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->osc_freq); break; case TOK_REFMULT: SNPRINTF(val, val_len, "%u", priv->ref_mult); break; case TOK_IFMIXFREQ: SNPRINTF(val, val_len, "%"PRIfreq, priv->if_mix_freq); break; case TOK_PUMPCRNT: SNPRINTF(val, val_len, "%u", priv->pump_crrnt); break; default: return -RIG_EINVAL; } return RIG_OK; } int drt1_get_conf(RIG *rig, hamlib_token_t token, char *val) { return drt1_get_conf2(rig, token, val, 128); } /* DDS is AD9951. The clock input is 45,012 MHz (also 2nd LO frequencie at the same time). The clock multiplier should be set to 8x at start value (possible, that this will change to lower clock multiplier). The charge pump current to 75 µA at start value (possible will change). The VCO gain bit has to be set. The IF offset for LO to the receiving frequency is + 45,000 MHz (fLO = frec + 45,000 MHz) Don't make the data clock too high, there are 1 KOhms decoupling resistors at the input pins of the DDS. Inputs (SDI(O)); SCLK und I/O UPDATE haves 5V TTL level, so that a level converter from RS232 is needed. I will use the attached motorola IC MC1489 as converter for amateur application. This IC inverts the signals ! */ #define AD_DELAY 4000 /* * Introduce delay after changing the bit state * FIXME: This implementation may not work for very fast computers, * or smart compilers. However, nanosleep can have * granularity > 10ms! */ static int ad_delay(int m) { long j; for (j = 0; j <= m; j++) {} return j; } static int ad_sdio(hamlib_port_t *port, int i) { int ret; ret = ser_set_rts(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_sclk(const hamlib_port_t *port, int i) { int ret; ret = ser_set_brk(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_ioupd(hamlib_port_t *port, int i) { int ret; ret = ser_set_dtr(port, i); ad_delay(AD_DELAY); if (ret != RIG_OK) rig_debug(RIG_DEBUG_ERR, "%s: unable to set statusbits\n", __func__); return ret; } static int ad_write_reg(hamlib_port_t *port, unsigned addr, unsigned nb_bytes, unsigned data) { int i; ad_sclk(port, 0); /* TXD 0 */ ad_ioupd(port, 1); /* DTR 1, CE */ /* Instruction byte, MSB Logic 0 = write */ addr &= 0x1f; for (i = 7; i >= 0; i--) { ad_sdio(port, (addr & (1U << i)) ? 0 : 1); /* RTS 0 or 1 */ ad_sclk(port, 1); /* TXD 1, clock */ ad_sclk(port, 0); /* TXD 0 */ } /* Data transfer */ for (i = nb_bytes * 8 - 1; i >= 0; i--) { ad_sdio(port, (data & (1U << i)) ? 0 : 1); /* RTS 0 or 1 */ ad_sclk(port, 1); /* TXD 1, clock */ ad_sclk(port, 0); /* TXD 0 */ } ad_ioupd(port, 0); /* DTR 0 */ return RIG_OK; } /* Register serial addresses */ #define CFR1 0x0 #define CFR2 0x1 #define ASF 0x2 #define ARR 0x3 #define FTW0 0x4 #define POW0 0x5 int drt1_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned long frg; unsigned cfr2; struct drt1_priv_data *priv; hamlib_port_t *port = RIGPORT(rig); priv = (struct drt1_priv_data *)STATE(rig)->priv; rig_flush(port); /* Initialization */ ad_ioupd(port, 0); ad_sdio(port, 0); ad_sclk(port, 0); /* * CFR2: * clock multiplier set to 8x, charge pump current to 75 µA * VCO gain bit has to be set */ cfr2 = ((priv->ref_mult << 3) & 0xf8) | 0x4 | (((priv->pump_crrnt - 75) / 25) & 0x3); ad_write_reg(port, CFR2, 3, cfr2); /* all frequencies are in Hz */ frg = (unsigned long)(((double)freq + priv->if_mix_freq) / (priv->osc_freq * priv->ref_mult) * 4294967296.0); rig_debug(RIG_DEBUG_VERBOSE, "%s: [%#lx]\n", __func__, frg); ad_write_reg(port, FTW0, 4, frg); return RIG_OK; } hamlib-4.6.2/rigs/wj/0000755000175000017500000000000014752216244011353 500000000000000hamlib-4.6.2/rigs/wj/wj.c0000644000175000017500000002250114752216205012054 00000000000000/* * Hamlib Watkins-Johnson backend - main file * Copyright (c) 2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "wj.h" #define CMDSZ 10 const struct confparams wj_cfg_params[] = { { TOK_RIGID, "receiver_id", "receiver ID", "receiver ID", "0", RIG_CONF_NUMERIC, { .n = { 0, 15, 1 } } }, { RIG_CONF_END, NULL, } }; /* * modes */ #define MD_AM 0 #define MD_FM 1 #define MD_CW 2 #define MD_VCW 3 /* BFO variable */ #define MD_ISB 4 #define MD_LSB 5 #define MD_USB 6 #define MD_AMNL 7 /* * wj_transaction * * I'm not sure how monitor protocol works, whether you have * to send the full frame, or just the modal byte. --SF * * TODO: decode the whole reply, and maybe do some caching */ static int wj_transaction(RIG *rig, int monitor) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char buf[CMDSZ] = { 0x8, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; unsigned char rxbuf[CMDSZ]; unsigned char freqbuf[4]; unsigned wj_agc, wj_mode, wj_width, wj_bfo, wj_rfgain; int retval; if (monitor) { buf[1] |= 0x40; /* Monitor+AGC dump */ } else { buf[0] |= 0x40; /* Command */ } buf[0] |= priv->receiver_id & 0x0f; /* tuned frequency */ to_bcd_be(freqbuf, priv->freq / 10, 7); buf[1] |= freqbuf[0] & 0x3f; buf[2] |= freqbuf[1] >> 1; buf[3] |= ((freqbuf[1] & 0x1) << 6) | (freqbuf[2] >> 2); buf[4] |= ((freqbuf[2] & 0x2) << 5) | (freqbuf[3] >> 3); /* gain mode */ switch (priv->agc.i) { case RIG_AGC_SLOW: wj_agc = 0; break; /* slow, 2s */ case RIG_AGC_OFF: wj_agc = 1; break; /* "not used" */ case RIG_AGC_FAST: wj_agc = 2; break; /* normal, 0.1s */ case RIG_AGC_USER: wj_agc = 3; break; /* manual */ default: return -RIG_EINVAL; } buf[4] |= wj_agc & 0x1; buf[5] |= (wj_agc & 0x2) << 5; /* IF BW */ switch (priv->width) { case 200: case 1000: wj_width = 0; break; /* spare */ case 500: wj_width = 1; break; case 2000: wj_width = 2; break; case 4000: wj_width = 3; break; case 8000: wj_width = 4; break; case 3000: case 6000: case 12000: case 16000: wj_width = 5; break; /* spare */ default: return -RIG_EINVAL; } buf[5] |= (wj_width & 0x7) << 3; /* Detection mode */ switch (priv->mode) { case RIG_MODE_CW: wj_mode = (priv->ifshift.i != 0) ? MD_VCW : MD_CW; break; case RIG_MODE_USB: wj_mode = MD_USB; break; case RIG_MODE_LSB: wj_mode = MD_LSB; break; case RIG_MODE_FM: wj_mode = MD_FM; break; case RIG_MODE_AM: wj_mode = MD_AM; break; case RIG_MODE_AMS: wj_mode = MD_ISB; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(priv->mode)); return -RIG_EINVAL; } buf[5] |= wj_mode & 0x7; /* BFO frequency, not sure though */ wj_bfo = (priv->ifshift.i / 10) + 0x400; /* LSBit is 10Hz, +455kHz */ buf[6] |= (wj_bfo >> 5) & 0x3f; buf[7] |= (wj_bfo & 0x1f) << 2; /* RF gain */ wj_rfgain = (unsigned)(priv->rfgain.f * 0x7f); buf[7] |= (wj_rfgain >> 6) & 0x1; buf[8] |= (wj_rfgain & 0x3f) << 1; /* buf[9]: not used if command byte, but must be transmitted */ rig_flush(rp); retval = write_block(rp, buf, CMDSZ); if (retval != RIG_OK) { return retval; } if (monitor) { /* * Transceiver sends back ">" */ retval = read_block(rp, rxbuf, CMDSZ); if (retval < 0 || retval > CMDSZ) { return -RIG_ERJCTED; } /* * TODO: analyze back the reply, and fill in the priv struct */ priv->rawstr.i = rxbuf[9] & 0x7f; } return retval; } int wj_init(RIG *rig) { struct wj_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } STATE(rig)->priv = (struct wj_priv_data *)calloc(1, sizeof(struct wj_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->receiver_id = 0; priv->freq = kHz(500); priv->mode = RIG_MODE_AM; priv->width = kHz(8); priv->agc.i = RIG_AGC_SLOW; priv->rfgain.f = 1; priv->ifshift.i = 0; return RIG_OK; } /* */ int wj_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ int wj_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: priv->receiver_id = atoi(val); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * assumes rig!=NULL, * Assumes rig!=NULL, STATE(rig)->priv!=NULL * and val points to a buffer big enough to hold the conf value. */ int wj_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { const struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; switch (token) { case TOK_RIGID: SNPRINTF(val, val_len, "%u", priv->receiver_id); break; default: return -RIG_EINVAL; } return RIG_OK; } int wj_get_conf(RIG *rig, hamlib_token_t token, char *val) { return wj_get_conf2(rig, token, val, 128); } /* * wj_set_freq * Assumes rig!=NULL */ int wj_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; priv->freq = freq; return wj_transaction(rig, 0); } /* * wj_get_freq * Assumes rig!=NULL */ int wj_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; int retval; retval = wj_transaction(rig, 1); if (retval == RIG_OK) { return retval; } *freq = priv->freq; return RIG_OK; } /* * wj_set_mode * Assumes rig!=NULL */ int wj_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; priv->mode = mode; if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } priv->width = width; } return wj_transaction(rig, 0); } /* * wj_get_mode * Assumes rig!=NULL */ int wj_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; int retval; retval = wj_transaction(rig, 1); if (retval == RIG_OK) { return retval; } *mode = priv->mode; *width = priv->width; return RIG_OK; } /* * wj_set_level * Assumes rig!=NULL */ int wj_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_IF: priv->ifshift.i = val.i; break; case RIG_LEVEL_RF: priv->rfgain.f = val.f; break; case RIG_LEVEL_AGC: priv->agc.i = val.i; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return wj_transaction(rig, 0); } /* * wj_get_level * Assumes rig!=NULL */ int wj_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct wj_priv_data *priv = (struct wj_priv_data *)STATE(rig)->priv; int retval = RIG_OK; retval = wj_transaction(rig, 1); if (retval == RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RAWSTR: val->i = priv->rawstr.i; break; case RIG_LEVEL_IF: val->i = priv->ifshift.i; break; case RIG_LEVEL_RF: val->f = priv->rfgain.f; break; case RIG_LEVEL_AGC: val->i = priv->agc.i; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } /* * initrigs_wj is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(wj) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&wj8888_caps); return RIG_OK; } hamlib-4.6.2/rigs/wj/wj8888.c0000644000175000017500000001021514752216205012413 00000000000000/* * Hamlib Watkins-Johnson backend - WJ-8888 description * Copyright (c) 2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "wj.h" /* modes: what about ISB(Idependant Sideband)? */ #define WJ8888_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_AMS) #define WJ8888_FUNC (RIG_FUNC_NONE) #define WJ8888_LEVEL (RIG_LEVEL_RF|RIG_LEVEL_AGC|RIG_LEVEL_IF|RIG_LEVEL_RAWSTR) #define WJ8888_VFO (RIG_VFO_A) /* FIXME: real measures */ #define WJ8888_STR_CAL { 2, \ { \ { 0x00, -60 }, /* -115.5dBm .. -99.5dBm */ \ { 0x7f, 60 } \ } } /* * WJ-8888 receiver capabilities. * * Needs async I/O board * * * TODO: BFO */ struct rig_caps wj8888_caps = { RIG_MODEL(RIG_MODEL_WJ8888), .model_name = "WJ-8888", .mfg_name = "Watkins-Johnson", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 75, /* jumper E26 */ .serial_rate_max = 9600, /* jumper E19 */ .serial_data_bits = 8, .serial_stop_bits = 1, /* jumper between E5 & E6 */ .serial_parity = RIG_PARITY_NONE, /* no jumper between E3 & E4 */ .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 5, /* typical 5ms, max 15ms */ .timeout = 2000, .retry = 3, .has_get_func = WJ8888_FUNC, .has_set_func = WJ8888_FUNC, .has_get_level = WJ8888_LEVEL, .has_set_level = RIG_LEVEL_SET(WJ8888_LEVEL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 0x7f } }, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = kHz(8), /* IF at 455kHz */ .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = WJ8888_STR_CAL, .cfgparams = wj_cfg_params, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), WJ8888_MODES, -1, -1, WJ8888_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), WJ8888_MODES, -1, -1, WJ8888_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {WJ8888_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {WJ8888_MODES, kHz(2)}, {WJ8888_MODES, Hz(500)}, {WJ8888_MODES, kHz(4)}, {WJ8888_MODES, kHz(8)}, /* option (in spare, to be fixed) */ {WJ8888_MODES, Hz(200)}, {WJ8888_MODES, kHz(1)}, {WJ8888_MODES, kHz(3)}, {WJ8888_MODES, kHz(6)}, {WJ8888_MODES, kHz(12)}, {WJ8888_MODES, kHz(16)}, RIG_FLT_END, }, .rig_init = wj_init, .rig_cleanup = wj_cleanup, .set_conf = wj_set_conf, .get_conf = wj_get_conf, .set_freq = wj_set_freq, .get_freq = wj_get_freq, .set_mode = wj_set_mode, .get_mode = wj_get_mode, .set_level = wj_set_level, .get_level = wj_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/wj/Makefile.am0000644000175000017500000000017514752216205013327 00000000000000WJSRC = wj8888.c wj.c wj.h noinst_LTLIBRARIES = libhamlib-wj.la libhamlib_wj_la_SOURCES = $(WJSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/wj/wj.h0000644000175000017500000000345714752216205012072 00000000000000/* * Hamlib Watkins-Johnson backend - main header * Copyright (c) 2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _WJ_H #define _WJ_H 1 #include #include "token.h" #define BACKEND_VER "20040912" #define TOK_RIGID TOKEN_BACKEND(1) extern const struct confparams wj_cfg_params[]; struct wj_priv_data { unsigned receiver_id; freq_t freq; rmode_t mode; pbwidth_t width; value_t agc; value_t rfgain; value_t ifshift; value_t rawstr; }; int wj_set_conf(RIG *rig, hamlib_token_t token, const char *val); int wj_get_conf(RIG *rig, hamlib_token_t token, char *val); int wj_init(RIG *rig); int wj_cleanup(RIG *rig); int wj_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int wj_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int wj_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int wj_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int wj_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int wj_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern struct rig_caps wj8888_caps; #endif /* _WJ_H */ hamlib-4.6.2/rigs/wj/Makefile.in0000644000175000017500000005222014752216216013340 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/wj ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_wj_la_LIBADD = am__objects_1 = wj8888.lo wj.lo am_libhamlib_wj_la_OBJECTS = $(am__objects_1) libhamlib_wj_la_OBJECTS = $(am_libhamlib_wj_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/wj.Plo ./$(DEPDIR)/wj8888.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_wj_la_SOURCES) DIST_SOURCES = $(libhamlib_wj_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ WJSRC = wj8888.c wj.c wj.h noinst_LTLIBRARIES = libhamlib-wj.la libhamlib_wj_la_SOURCES = $(WJSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/wj/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/wj/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-wj.la: $(libhamlib_wj_la_OBJECTS) $(libhamlib_wj_la_DEPENDENCIES) $(EXTRA_libhamlib_wj_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_wj_la_OBJECTS) $(libhamlib_wj_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wj.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wj8888.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/wj.Plo -rm -f ./$(DEPDIR)/wj8888.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/wj.Plo -rm -f ./$(DEPDIR)/wj8888.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/wj/Android.mk0000644000175000017500000000037314752216205013204 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := wj8888.c wj.c LOCAL_MODULE := wj LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/skanti/0000755000175000017500000000000014752216244012224 500000000000000hamlib-4.6.2/rigs/skanti/Makefile.am0000644000175000017500000000024014752216205014171 00000000000000SKANTISRC = trp8000.c trp8255.c skanti.c skanti.h noinst_LTLIBRARIES = libhamlib-skanti.la libhamlib_skanti_la_SOURCES = $(SKANTISRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/skanti/skanti.c0000644000175000017500000001627614752216205013612 00000000000000/* * Hamlib Skanti backend - main file * Copyright (c) 2004-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include #include #include "skanti.h" /* Line Feed */ #define EOM "\x0d" #define LF "\x0a" #define PROMPT ">" #define BUFSZ 32 /* * modes */ #define MD_LSB "L" #define MD_USB "J" #define MD_CW "A1" #define MD_MCW "A2" #define MD_AM "H" #define MD_RTTY "F" #define MD_R3E "R" /* * skanti_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ static int skanti_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected, check for OK returned */ if (!data || !data_len) { /* * Transceiver sends back ">" */ char retbuf[BUFSZ + 1]; retval = read_string(rp, (unsigned char *) retbuf, BUFSZ, PROMPT, strlen(PROMPT), 0, 1); if (retval < 0) { return retval; } retbuf[retval] = '\0'; if (strstr(retbuf, PROMPT)) { return RIG_OK; } else { return -RIG_ERJCTED; } } retval = read_string(rp, (unsigned char *) data, BUFSZ, LF, strlen(LF), 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; /* strip CR/LF from string */ *data_len -= 2; data[*data_len] = 0; return RIG_OK; } /* * skanti_reset * Assumes rig!=NULL */ int skanti_reset(RIG *rig, reset_t reset) { int retval; /* * master reset * * returned data: *x1A345SF * whatever this means? unit serial #? */ retval = skanti_transaction(rig, "0" EOM, strlen("0" EOM), NULL, NULL); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * skanti_set_freq * Assumes rig!=NULL */ int skanti_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; /* 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "Z%06ld" EOM, (long)(freq / 100)); return skanti_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } /* * skanti_set_mode * Assumes rig!=NULL */ int skanti_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval; char *sk_mode, *sk_filter; pbwidth_t passband_normal; switch (mode) { /* TODO: MCW, R3E */ case RIG_MODE_CW: sk_mode = MD_CW EOM; break; case RIG_MODE_USB: sk_mode = MD_USB EOM; break; case RIG_MODE_LSB: sk_mode = MD_LSB EOM; break; case RIG_MODE_RTTY: sk_mode = MD_RTTY EOM; break; case RIG_MODE_AM: sk_mode = MD_AM EOM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } retval = skanti_transaction(rig, sk_mode, strlen(sk_mode), NULL, NULL); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } /* * TODO: please sk8000 owners, check this, I'm not sure * which passband is default! */ passband_normal = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL || width == passband_normal) { sk_filter = "I" EOM; } else if (width < passband_normal) { sk_filter = width < 1000 ? "V" EOM : "N" EOM; } else { sk_filter = "W" EOM; } retval = skanti_transaction(rig, sk_filter, strlen(sk_filter), NULL, NULL); return retval; } /* * skanti_set_split_freq * Assumes rig!=NULL */ int skanti_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { char freqbuf[BUFSZ]; /* 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), "T%06ld" EOM, (long)(tx_freq / 100)); return skanti_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } /* * skanti_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sense though) */ int skanti_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmdbuf[BUFSZ], *agc; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_PREAMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), "R%c" EOM, val.i ? 'F' : 'O'); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_ATT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "A%c" EOM, val.i ? 'T' : 'O'); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "M%cO" EOM, val.f < 0.33 ? 'L' : (val.f < 0.66 ? 'M' : 'F')); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_SLOW: agc = "AS"EOM; break; case RIG_AGC_FAST: agc = "AA"EOM; break; case RIG_AGC_OFF: agc = "AF"EOM; break; default: return -RIG_EINVAL; } return skanti_transaction(rig, agc, strlen(agc), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * skanti_set_ptt * Assumes rig!=NULL, ptt!=NULL */ int skanti_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "X%c" EOM, ptt == RIG_PTT_ON ? 'N' : 'F'); return skanti_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } int skanti_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { if (op != RIG_OP_TUNE) { return -RIG_EINVAL; } return skanti_transaction(rig, "XT"EOM, strlen("XT"EOM), NULL, NULL); } /* * initrigs_skanti is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(skanti) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&trp8000_caps); rig_register(&trp8255_caps); return RIG_OK; } hamlib-4.6.2/rigs/skanti/Makefile.in0000644000175000017500000005271314752216216014220 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/skanti ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_skanti_la_LIBADD = am__objects_1 = trp8000.lo trp8255.lo skanti.lo am_libhamlib_skanti_la_OBJECTS = $(am__objects_1) libhamlib_skanti_la_OBJECTS = $(am_libhamlib_skanti_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/skanti.Plo ./$(DEPDIR)/trp8000.Plo \ ./$(DEPDIR)/trp8255.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_skanti_la_SOURCES) DIST_SOURCES = $(libhamlib_skanti_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SKANTISRC = trp8000.c trp8255.c skanti.c skanti.h noinst_LTLIBRARIES = libhamlib-skanti.la libhamlib_skanti_la_SOURCES = $(SKANTISRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/skanti/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/skanti/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-skanti.la: $(libhamlib_skanti_la_OBJECTS) $(libhamlib_skanti_la_DEPENDENCIES) $(EXTRA_libhamlib_skanti_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_skanti_la_OBJECTS) $(libhamlib_skanti_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skanti.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trp8000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trp8255.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/skanti.Plo -rm -f ./$(DEPDIR)/trp8000.Plo -rm -f ./$(DEPDIR)/trp8255.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/skanti.Plo -rm -f ./$(DEPDIR)/trp8000.Plo -rm -f ./$(DEPDIR)/trp8255.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/skanti/Android.mk0000644000175000017500000000041614752216205014053 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := trp8000.c trp8255.c skanti.c LOCAL_MODULE := skanti LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/skanti/skanti.h0000644000175000017500000000270314752216205013605 00000000000000/* * Hamlib Skanti backend - main header * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _SKANTI_H #define _SKANTI_H 1 #include #define BACKEND_VER "20191208" int skanti_reset(RIG *rig, reset_t reset); int skanti_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int skanti_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int skanti_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int skanti_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int skanti_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int skanti_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); extern struct rig_caps trp8000_caps; extern struct rig_caps trp8255_caps; #endif /* _SKANTI_H */ hamlib-4.6.2/rigs/skanti/trp8255.c0000644000175000017500000003012514752216205013437 00000000000000/* * Hamlib Skanti backend - TRP8255 description * Copyright (c) 2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "idx_builtin.h" #include "iofunc.h" #define TRP8255_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8255_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8255_AM_TX_MODES RIG_MODE_AM #define TRP8255_FUNC (RIG_FUNC_MUTE) #define TRP8255_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AGC|\ RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_SQL) #define TRP8255_PARM_ALL (RIG_PARM_TIME|RIG_PARM_BACKLIGHT) #define TRP8255_VFO_OPS (RIG_OP_TUNE|RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY) #define TRP8255_VFO (RIG_VFO_A) #define TRP8255_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .tx_freq = 1, \ } /* * Private data */ struct cu_priv_data { split_t split; /* current emulated split state */ int ch; /* current memorized memory channel */ }; static int cu_transaction(RIG *rig, const char *cmd, int cmd_len); static int cu_open(RIG *rig); static int cu_close(RIG *rig); static int cu_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int cu_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int cu_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int cu_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int cu_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int cu_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int cu_set_parm(RIG *rig, setting_t parm, value_t val); static int cu_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int cu_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int cu_set_mem(RIG *rig, vfo_t vfo, int ch); static int cu_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* * TRP 8255 rig capabilities. * The protocol is different than TRP8000, * because the TRP8255 has the "CU" (Control Unit). * */ struct rig_caps trp8255_caps = { RIG_MODEL(RIG_MODEL_TRP8255), .model_name = "TRP 8255 S R", .mfg_name = "Skanti", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 2400, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = TRP8255_FUNC, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_SET(TRP8255_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(TRP8255_PARM_ALL), .vfo_ops = TRP8255_VFO_OPS, .preamp = { 10, RIG_DBLST_END }, /* TBC */ .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 76, RIG_MTYPE_MEM, TRP8255_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TRP8255_ALL_MODES, -1, -1, TRP8255_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(2), MHz(30), TRP8255_AM_TX_MODES, W(4), W(40), TRP8255_VFO}, {MHz(2), MHz(30), TRP8255_OTHER_TX_MODES, W(10), W(100), TRP8255_VFO}, RIG_FRNG_END, }, .tuning_steps = { {TRP8255_ALL_MODES, 10}, {TRP8255_ALL_MODES, 100}, {TRP8255_ALL_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* rough guesses */ {TRP8255_ALL_MODES, kHz(2.7)}, /* intermit */ {TRP8255_ALL_MODES, kHz(2.1)}, /* narrow */ {TRP8255_ALL_MODES, kHz(6)}, /* wide */ {TRP8255_ALL_MODES, Hz(500)}, /* very narrow */ RIG_FLT_END, }, .rig_open = cu_open, .rig_close = cu_close, .set_freq = cu_set_freq, .set_mode = cu_set_mode, .set_split_freq = cu_set_split_freq, .set_split_vfo = cu_set_split_vfo, .set_ptt = cu_set_ptt, .set_mem = cu_set_mem, .vfo_op = cu_vfo_op, .set_level = cu_set_level, .set_func = cu_set_func, .set_parm = cu_set_parm, .set_ts = cu_set_ts, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ #define ACK 0x06 #define NACK 0x15 #define CR "\x0d" /* TODO: retry */ static int cu_transaction(RIG *rig, const char *cmd, int cmd_len) { int i; char retchar; hamlib_port_t *rp = RIGPORT(rig); for (i = 0; i < cmd_len; i++) { int ret = write_block(rp, (unsigned char *) &cmd[i], 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &retchar, 1); switch (retchar) { case ACK: continue; case NACK: return -RIG_ERJCTED; default: return -RIG_EPROTO; } } return RIG_OK; } static int cu_open(RIG *rig) { const char cmd[] = { 0x01, 0x02 }; /* SOH, STX */ struct cu_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); STATE(rig)->priv = calloc(1, sizeof(struct cu_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = (struct cu_priv_data *)STATE(rig)->priv; memset(priv, 0, sizeof(struct cu_priv_data)); priv->split = RIG_SPLIT_OFF; priv->ch = 0; return cu_transaction(rig, cmd, 2); } static int cu_close(RIG *rig) { const char cmd[] = { 0x16 }; /* DLE */ struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; free(priv); return cu_transaction(rig, cmd, 1); } int cu_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { const struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; char cmdbuf[16]; int ret; if (freq >= MHz(100)) { return -RIG_EINVAL; } /* RX freq */ SNPRINTF(cmdbuf, sizeof(cmdbuf), ":%06u"CR, (unsigned)(freq / Hz(100))); ret = cu_transaction(rig, cmdbuf, strlen(cmdbuf)); if (ret != RIG_OK) { return ret; } if (priv->split != RIG_SPLIT_ON) { return cu_vfo_op(rig, vfo, RIG_OP_CPY); } return RIG_OK; } static int cu_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; priv->split = split; return RIG_OK; } int cu_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmdbuf[16]; if (freq >= MHz(100)) { return -RIG_EINVAL; } /* TX freq */ SNPRINTF(cmdbuf, sizeof(cmdbuf), ";%06u"CR, (unsigned)(freq / Hz(100))); return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char *cmd; int ret; switch (mode) { case RIG_MODE_USB: cmd = "X"; break; case RIG_MODE_LSB: cmd = "Y"; break; case RIG_MODE_AM: cmd = "Z"; break; case RIG_MODE_RTTY: cmd = "["; break; /* case RIG_MODE_R3E: cmd = "\\"; break; */ case RIG_MODE_CW: cmd = "]"; break; /* case RIG_MODE_MCW: cmd = '^'; break; */ default: return -RIG_EINVAL; } ret = cu_transaction(rig, cmd, 1); if (ret != RIG_OK) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width < rig_passband_normal(rig, mode)) { cmd = "D"; } else if (width > rig_passband_normal(rig, mode)) { cmd = "B"; } else { cmd = "C"; } return cu_transaction(rig, cmd, 1); } int cu_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmdbuf[16]; cmdbuf[1] = 0; switch (level) { case RIG_LEVEL_PREAMP: cmdbuf[0] = val.i ? 'm' : 'n'; break; case RIG_LEVEL_ATT: cmdbuf[0] = val.i ? 'o' : 'p'; break; case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_AUTO: cmdbuf[0] = 'J'; break; case RIG_AGC_FAST: cmdbuf[0] = 'K'; break; case RIG_AGC_SLOW: cmdbuf[0] = 'L'; break; case RIG_AGC_OFF: cmdbuf[0] = 'M'; break; default: return -RIG_EINVAL; } break; case RIG_LEVEL_SQL: cmdbuf[0] = val.i ? 'o' : 'p'; break; case RIG_LEVEL_RFPOWER: if (val.f < 0.4) { cmdbuf[0] = 'S'; /* low */ } else if (val.f < 0.6) { cmdbuf[0] = 'U'; /* medium */ } else { cmdbuf[0] = 'W'; /* high */ } break; case RIG_LEVEL_AF: SNPRINTF(cmdbuf, sizeof(cmdbuf), "y%02u"CR, (unsigned)(99 - val.f * 99)); break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[16]; int cmd_len; cmd_len = 1; switch (func) { case RIG_FUNC_MUTE: cmdbuf[0] = status ? 'l' : 'k'; break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, cmd_len); } int cu_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { char cmdbuf[16]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "w%c"CR, ts >= s_kHz(1) ? '2' : ts >= s_Hz(100) ? '1' : '0'); return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_parm(RIG *rig, setting_t parm, value_t val) { char cmdbuf[16]; switch (parm) { case RIG_PARM_TIME: /* zap seconds */ val.i /= 60; SNPRINTF(cmdbuf, sizeof(cmdbuf), "f%02d%02d"CR, val.i / 60, val.i % 60); break; case RIG_PARM_BACKLIGHT: SNPRINTF(cmdbuf, sizeof(cmdbuf), "z%1u"CR, (unsigned)(val.f * 5)); break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } int cu_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char *cmd; cmd = ptt == RIG_PTT_ON ? "u" : "v"; return cu_transaction(rig, cmd, 1); } static int cu_set_mem(RIG *rig, vfo_t vfo, int ch) { struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; /* memorize channel for RIG_OP_TO_VFO & RIG_OP_FROM_VFO */ priv->ch = ch; return RIG_OK; } int cu_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct cu_priv_data *priv = (struct cu_priv_data *)STATE(rig)->priv; char cmdbuf[16]; switch (op) { case RIG_OP_TUNE: cmdbuf[0] = 'R'; cmdbuf[1] = 0; break; case RIG_OP_CPY: cmdbuf[0] = ':'; cmdbuf[1] = ';'; cmdbuf[2] = 0x0d; cmdbuf[3] = 0; break; case RIG_OP_TO_VFO: SNPRINTF(cmdbuf, sizeof(cmdbuf), "<%02u"CR, (unsigned)priv->ch); break; case RIG_OP_FROM_VFO: SNPRINTF(cmdbuf, sizeof(cmdbuf), "d%02u"CR, (unsigned)priv->ch); break; default: return -RIG_EINVAL; } return cu_transaction(rig, cmdbuf, strlen(cmdbuf)); } hamlib-4.6.2/rigs/skanti/trp8000.c0000644000175000017500000000764014752216205013431 00000000000000/* * Hamlib Skanti backend - TRP8000 description * Copyright (c) 2004-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "idx_builtin.h" #include "skanti.h" /* modes: what about MCW, R3E ? */ #define TRP8000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRP8000_AM_TX_MODES RIG_MODE_AM #define TRP8000_FUNC (RIG_FUNC_NONE) #define TRP8000_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_AGC|RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define TRP8000_PARM_ALL (RIG_PARM_NONE) #define TRP8000_VFO (RIG_VFO_A) /* TBC */ /* * trp8000 rig capabilities. * * * TODO: TUNING, BFO, SENSITIVITY(RF gain?) */ struct rig_caps trp8000_caps = { RIG_MODEL(RIG_MODEL_TRP8000), .model_name = "TRP8000", .mfg_name = "Skanti", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 300, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 2000, .retry = 3, .has_get_func = TRP8000_FUNC, .has_set_func = TRP8000_FUNC, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_SET(TRP8000_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(TRP8000_PARM_ALL), .vfo_ops = RIG_OP_TUNE, .preamp = { 10, RIG_DBLST_END }, /* TBC */ .attenuator = { 20, RIG_DBLST_END }, /* TBC */ .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TRP8000_ALL_MODES, -1, -1, TRP8000_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(2), MHz(30), TRP8000_AM_TX_MODES, W(4), W(40), TRP8000_VFO}, {MHz(2), MHz(30), TRP8000_OTHER_TX_MODES, W(10), W(100), TRP8000_VFO}, RIG_FRNG_END, }, .tuning_steps = { {TRP8000_ALL_MODES, 10}, {TRP8000_ALL_MODES, 100}, {TRP8000_ALL_MODES, kHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* rough guesses */ {TRP8000_ALL_MODES, kHz(2.7)}, /* intermit */ {TRP8000_ALL_MODES, kHz(2.1)}, /* narrow */ {TRP8000_ALL_MODES, kHz(6)}, /* wide */ {TRP8000_ALL_MODES, Hz(500)}, /* very narrow */ RIG_FLT_END, }, .set_freq = skanti_set_freq, .set_mode = skanti_set_mode, .set_split_freq = skanti_set_split_freq, .set_ptt = skanti_set_ptt, .vfo_op = skanti_vfo_op, .set_level = skanti_set_level, .reset = skanti_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/codan/0000755000175000017500000000000014752216242012015 500000000000000hamlib-4.6.2/rigs/codan/codan.h0000644000175000017500000000400414752216205013167 00000000000000/* * Hamlib Barrett backend - main header * Copyright (c) 2017 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _CODAN_H #define _CODAN_H 1 #include "hamlib/rig.h" #define BACKEND_VER "20240318" #define EOM "\x0a" #define TRUE 1 #define FALSE 0 // For the current implemented command set 64 is long enough // This will need a lot more room for some channel commands like IDFA which return all channels // But that would 9999*41 or 406KB so didn't do that right now #define CODAN_DATA_LEN 64 extern struct rig_caps envoy_caps; extern struct rig_caps ngs_caps; struct codan_priv_data { char cmd_str[CODAN_DATA_LEN]; /* command string buffer */ char ret_data[CODAN_DATA_LEN]; /* returned data--max value, most are less */ }; extern int codan_transaction(RIG *rig, char *cmd, int expected, char **result); extern int codan_init(RIG *rig); extern int codan_cleanup(RIG *rig); extern int codan_set_freq(RIG *rig, vfo_t vfo, freq_t freq); extern int codan_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); extern int codan_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern int codan_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); extern int codan_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); #endif /* _CODAN_H */ hamlib-4.6.2/rigs/codan/Makefile.am0000644000175000017500000000022314752216205013765 00000000000000CODANSRC = codan.c codan.h noinst_LTLIBRARIES = libhamlib-codan.la libhamlib_codan_la_SOURCES = $(CODANSRC) EXTRA_DIST = README.codan Android.mk hamlib-4.6.2/rigs/codan/Makefile.in0000644000175000017500000005204714752216216014013 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/codan ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_codan_la_LIBADD = am__objects_1 = codan.lo am_libhamlib_codan_la_OBJECTS = $(am__objects_1) libhamlib_codan_la_OBJECTS = $(am_libhamlib_codan_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/codan.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_codan_la_SOURCES) DIST_SOURCES = $(libhamlib_codan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CODANSRC = codan.c codan.h noinst_LTLIBRARIES = libhamlib-codan.la libhamlib_codan_la_SOURCES = $(CODANSRC) EXTRA_DIST = README.codan Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/codan/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/codan/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-codan.la: $(libhamlib_codan_la_OBJECTS) $(libhamlib_codan_la_DEPENDENCIES) $(EXTRA_libhamlib_codan_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_codan_la_OBJECTS) $(libhamlib_codan_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codan.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/codan.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/codan.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/codan/Android.mk0000644000175000017500000000040014752216205013637 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := codan.c codan.h LOCAL_MODULE := codan LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/codan/codan.c0000644000175000017500000003441714752216205013175 00000000000000/* * Hamlib CODAN backend - main file * Copyright (c) 2021 by Michael Black W9MDB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "serial.h" #include "misc.h" #include "register.h" #include "codan.h" #define MAXCMDLEN 64 #define CODAN_VFOS (RIG_VFO_A|RIG_VFO_B) #define CODAN_MODES (RIG_MODE_USB) int codan_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int codan_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int codan_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int codan_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int codan_transaction(RIG *rig, char *cmd, int expected, char **result) { char cmd_buf[MAXCMDLEN]; int retval; hamlib_port_t *rp = RIGPORT(rig); struct codan_priv_data *priv = STATE(rig)->priv; //int retry = 3; rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd=%s\n", __func__, cmd); SNPRINTF(cmd_buf, sizeof(cmd_buf), "%s%s", cmd, EOM); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd_buf, strlen(cmd_buf)); hl_usleep(rig->caps->post_write_delay); if (retval < 0) { return retval; } if (expected == 0) { // response format is response...0x0d0x0a retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x0a", 1, 0, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: result=%s, resultlen=%d\n", __func__, priv->ret_data, (int)strlen(priv->ret_data)); if (retval < 0) { return retval; } } else { retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x0a", 1, 0, 1); if (retval < 0) { return retval; } if (strncmp(priv->ret_data, "LEVELS:", 7) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); retval = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), "\x0a", 1, 0, 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); } } #if 0 int hr, min, sec; while (--retry >= 0 && strncmp(priv->ret_data, "OK", 2) != 0 && sscanf(priv->ret_data, "%d:%d:%d", &hr, &min, &sec) != 3) { char tmpbuf[256]; retval = read_string(rp, (unsigned char *) tmpbuf, sizeof(priv->ret_data), "\x0a", 1, 0, 1); dump_hex((unsigned char *)priv->ret_data, strlen(priv->ret_data)); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); } #endif rig_debug(RIG_DEBUG_VERBOSE, "%s: retval=%d\n", __func__, retval); rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, priv->ret_data); if (result != NULL) { *result = &(priv->ret_data[0]); rig_debug(RIG_DEBUG_VERBOSE, "%s: returning result=%s\n", __func__, *result); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: no result requested\n", __func__); } return RIG_OK; } int codan_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s version %s\n", __func__, rig->caps->version); // cppcheck claims leak here but it's freed in cleanup STATE(rig)->priv = (struct codan_priv_data *)calloc(1, sizeof(struct codan_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } RETURNFUNC2(RIG_OK); } int codan_open(RIG *rig) { char *results = NULL; codan_transaction(rig, "\recho off", 1, &results); codan_transaction(rig, "ver", 1, &results); //codan_transaction(rig, "prompt time", 1, &results); codan_transaction(rig, "login", 1, &results); if (!strstr(results, "admin")) { codan_transaction(rig, "login admin ''", 0, NULL); } codan_transaction(rig, "login", 1, &results); codan_set_freq(rig, RIG_VFO_A, 14074000.0); RETURNFUNC2(RIG_OK); } int codan_close(RIG *rig) { char *results = NULL; codan_transaction(rig, "logout admin\rfreq", 1, &results); RETURNFUNC2(RIG_OK); } int codan_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * codan_get_mode * Assumes rig!=NULL */ int codan_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char *result = NULL; char modeA[8], modeB[8]; int widthA, center; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = codan_transaction(rig, "mode", 0, &result); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad response=%s\n", __func__, result); return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s: result=%s", __func__, result); int n = sscanf(result, "MODE: %7[A-Z], %7[A-Z], %d, %d", modeA, modeB, ¢er, &widthA); if (n != 4) { rig_debug(RIG_DEBUG_ERR, "%s: sscanf expected 4, got %d, %s\n", __func__, n, result); return -RIG_EPROTO; } if (strncmp(modeA, "USB", 3) == 0) { *mode = RIG_MODE_USB; } else if (strncmp(modeA, "LSB", 3) == 0) { *mode = RIG_MODE_LSB; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown mode=%s'\n", __func__, modeA); return -RIG_EPROTO; } *width = widthA; // we'll default this to 3000 for now rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(*mode), (int)*width); return RIG_OK; } /* * codan_set_mode * Assumes rig!=NULL */ int codan_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char cmd_buf[32], *ttmode; char *response = NULL; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_USB: ttmode = "USBW"; break; case RIG_MODE_LSB: ttmode = "LSBW"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF((char *) cmd_buf, sizeof(cmd_buf), "mode %s", ttmode); retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } return RIG_OK; } /* * codan_set_freq * assumes rig!=NULL, STATE(rig)->priv!=NULL */ int codan_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd_buf[MAXCMDLEN]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); // Purportedly can't do split so we just set VFOB=VFOA SNPRINTF(cmd_buf, sizeof(cmd_buf), "connect tcvr rf %.0f %.0f\rfreq", freq, freq); char *response = NULL; retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { return retval; } return retval; } /* * codan_get_freq * Assumes rig!=NULL, STATE(rig)->priv!=NULL, freq!=NULL */ int codan_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); *freq = 0; retval = codan_transaction(rig, "freq", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } retval = sscanf(response, "FREQ: %lg", freq); *freq *= 1000; // returned freq is in kHz if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unable to parse response\n", __func__); return -RIG_EPROTO; } return RIG_OK; } /* * codan_get_ptt * Assumes rig!=NULL */ int codan_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; char *response = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = codan_transaction(rig, "connect tcvr rf ptt", 0, &response); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error response?='%s'\n", __func__, response); return retval; } const char *p = strstr(response, "Ptt"); if (p) { if (strcmp(p, "Ptt=Off") == 0) { *ptt = 0; } else { *ptt = 1; } } else { rig_debug(RIG_DEBUG_ERR, "%s: unable to find Ptt in %s\n", __func__, response); return -RIG_EPROTO; } return RIG_OK; } /* * codan_set_ptt * Assumes rig!=NULL */ int codan_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char cmd_buf[MAXCMDLEN]; char *response; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); SNPRINTF(cmd_buf, sizeof(cmd_buf), "connect tcvr rf ptt %s\rptt", ptt == 0 ? "off" : "on"); response = NULL; retval = codan_transaction(rig, cmd_buf, 0, &response); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: invalid response=%s\n", __func__, response); return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s: cmd result=%s\n", __func__, response); return RIG_OK; } struct rig_caps envoy_caps = { RIG_MODEL(RIG_MODEL_CODAN_ENVOY), .model_name = "Envoy", .mfg_name = "CODAN", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = CODAN_MODES, .low_power = -1, .high_power = -1, CODAN_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {CODAN_MODES, 1}, {CODAN_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(0.5)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.0)}, RIG_FLT_END, }, .priv = NULL, .rig_init = codan_init, .rig_open = codan_open, .rig_close = codan_close, .rig_cleanup = codan_cleanup, .set_freq = codan_set_freq, .get_freq = codan_get_freq, .set_mode = codan_set_mode, .get_mode = codan_get_mode, .set_ptt = codan_set_ptt, .get_ptt = codan_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ngs_caps = { RIG_MODEL(RIG_MODEL_CODAN_NGT), .model_name = "NGT", .mfg_name = "CODAN", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .targetable_vfo = RIG_TARGETABLE_FREQ, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .transceive = RIG_TRN_RIG, .rx_range_list1 = {{ .startf = kHz(1600), .endf = MHz(30), .modes = CODAN_MODES, .low_power = -1, .high_power = -1, CODAN_VFOS, RIG_ANT_1 }, RIG_FRNG_END, }, .rx_range_list2 = {RIG_FRNG_END,}, .tx_range_list1 = {RIG_FRNG_END,}, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { {CODAN_MODES, 1}, {CODAN_MODES, RIG_TS_ANY}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(0.5)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.0)}, RIG_FLT_END, }, .priv = NULL, .rig_init = codan_init, .rig_cleanup = codan_cleanup, .set_freq = codan_set_freq, .get_freq = codan_get_freq, .set_mode = codan_set_mode, .get_mode = codan_get_mode, .set_ptt = codan_set_ptt, .get_ptt = codan_get_ptt, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; DECLARE_INITRIG_BACKEND(codan) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&envoy_caps); rig_register(&ngs_caps); rig_debug(RIG_DEBUG_VERBOSE, "%s: _init back from rig_register\n", __func__); return RIG_OK; } hamlib-4.6.2/rigs/codan/README.codan0000644000175000017500000000100514752216205013673 00000000000000CODAN NGT and Envoy Radio Control Process. User Programming Responsibilities 1. Set Admin password to '' (empty, or NO password) 2. Enable Free TX mode by the sales option available from CODAN USA 3. Must know the serial port connected to "CICS" in the radio programming. This is most often the GP (general purpose) port which is a 15-pin D-Sub connector on a flying lead on the back of the radio. (NGT and Envoy models). Programming must be set to select "CICS" as the device which is addressed via the GP port. hamlib-4.6.2/rigs/commradio/0000755000175000017500000000000014752216245012706 500000000000000hamlib-4.6.2/rigs/commradio/commradio.c0000644000175000017500000001225114752216205014741 00000000000000/* * Hamlib CommRadio backend * idk, copyright and GPL here */ #include #include #include #include #include #include #include "misc.h" #include "commradio.h" #include "frame.h" /* * As far as I can tell, the commands and their structure are the same for the * CR-1a as they are for the CTX-10, but I don't have a CR1a to test with. * I'm putting these functions here in case they are reusable. */ int commradio_transaction(RIG *rig, const unsigned char *cmd, int cmd_len, unsigned char *data, int *data_len) { int ret = -RIG_EINTERNAL; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); ENTERFUNC; rs = STATE(rig); rs->transaction_active = 1; /* * Flush is needed until async mode is done. The CTX-10 sends frames every * time the VFO changes. */ rig_flush(rp); int frame_len; unsigned char frame[3 + 2 * (cmd_len + 2)]; size_t rx_len = CR_FRAMELENGTH; unsigned char rx[rx_len]; frame_len = frame_message(frame, cmd, cmd_len); ret = write_block(rp, frame, frame_len); if (ret < RIG_OK) { goto transaction_quit; } const char stopset[] = { CR_EOF }; ret = read_string(rp, rx, rx_len - 1, stopset, 1, 0, 1); if (ret < RIG_OK) { goto transaction_quit; } ret = commradio_unpack_frame(data, rx, ret); if (ret < RIG_OK) { goto transaction_quit; } *data_len = ret; //TODO: check for error response 0x11 transaction_quit: rs->transaction_active = 0; RETURNFUNC(ret); } int commradio_init(RIG *rig) { ENTERFUNC; // I can't think of anything that goes in here yet. RETURNFUNC(RIG_OK); } int commradio_cleanup(RIG *rig) { ENTERFUNC; // dealloc stuff if it gets added to _init RETURNFUNC(RIG_OK); } int commradio_rig_open(RIG *rig) { ENTERFUNC; // Possibly check if our serial port is configured right and we are not // doing bad things to the GPIO lines RETURNFUNC(RIG_OK); } int commradio_rig_close(RIG *rig) { ENTERFUNC; // i don't really know RETURNFUNC(RIG_OK); } /* * The CTX-10 sends VFO frequency updates when the knob is turned by the * operator, so this is really a good case for async events. Unfortunately * I can't find any good examples of how to do that, so instead just flush * and send a request... */ int commradio_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const unsigned char cmd[] = {0x32}; // Get frequency request unsigned char data[CR_FRAMELENGTH]; int data_len; int ret = -RIG_EINTERNAL; ENTERFUNC; ret = commradio_transaction(rig, cmd, 1, data, &data_len); if (data_len == 5 && (data[0] == 0x33 || data[0] == 0x34)) { *freq = (data[1] << 24 | data[2] << 16 | data[3] << 8 | data[4]); ret = RIG_OK; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected response to 0x32\n", __func__); } RETURNFUNC(ret); } int commradio_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[CR_FRAMELENGTH]; int data_len; int ret = -RIG_EINTERNAL; ENTERFUNC; if (freq < 150000 || freq > 30000000) { RETURNFUNC(-RIG_EINVAL); } uint32_t int_freq = freq; rig_debug(RIG_DEBUG_VERBOSE, "%s: Got freq=%f, int_freq=%u\n", __func__, freq, int_freq); unsigned char cmd[] = { 0x30, // Set frequency request 0xFF & (int_freq >> 24), 0xFF & (int_freq >> 16), 0xFF & (int_freq >> 8), 0xFF & (int_freq) }; ret = commradio_transaction(rig, cmd, 5, data, &data_len); if (data_len == 5 && (data[0] == 0x31 || data[0] == 0x34)) { uint32_t new_freq = (data[1] << 24 | data[2] << 16 | data[3] << 8 | data[4]); if (int_freq == new_freq) { RETURNFUNC(RIG_OK); } else { RETURNFUNC(-RIG_ERJCTED); } } // CTX-10 returns 11 02 30 00 00 00 01 if we try to go out of its // general-coverage frequency range 150kHz - 30MHz. I'm not sure why Hamlib // even tries to do this, since its defined in the caps... else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected response to 0x30\n", __func__); ret = -RIG_ERJCTED; } RETURNFUNC(ret); } /* * Stubs. I'm not aware of a way to get or set the mode on the CTX-10. */ int commradio_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return (RIG_OK); } int commradio_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { *mode = RIG_MODE_NONE; return (RIG_OK); } /* * Stubs. The CTX-10 has only one VFO and split mode doesn't change how it * responds via the serial port. */ int commradio_set_vfo(RIG *rig, vfo_t vfo) { return (RIG_OK); } int commradio_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = RIG_VFO_A; return (RIG_OK); } DECLARE_INITRIG_BACKEND(commradio) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&ctx10_caps); return (RIG_OK); } /* * For some reason, I can't get this to even link without this function. */ DECLARE_PROBERIG_BACKEND(commradio) { return (RIG_MODEL_NONE); } hamlib-4.6.2/rigs/commradio/Makefile.am0000644000175000017500000000026614752216205014662 00000000000000COMMRADIOSRC = commradio.c commradio.h frame.c frame.h ctx10.c noinst_LTLIBRARIES = libhamlib-commradio.la libhamlib_commradio_la_SOURCES = $(COMMRADIOSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/commradio/Makefile.in0000644000175000017500000005301114752216216014671 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/commradio ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_commradio_la_LIBADD = am__objects_1 = commradio.lo frame.lo ctx10.lo am_libhamlib_commradio_la_OBJECTS = $(am__objects_1) libhamlib_commradio_la_OBJECTS = $(am_libhamlib_commradio_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/commradio.Plo ./$(DEPDIR)/ctx10.Plo \ ./$(DEPDIR)/frame.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_commradio_la_SOURCES) DIST_SOURCES = $(libhamlib_commradio_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ COMMRADIOSRC = commradio.c commradio.h frame.c frame.h ctx10.c noinst_LTLIBRARIES = libhamlib-commradio.la libhamlib_commradio_la_SOURCES = $(COMMRADIOSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/commradio/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/commradio/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-commradio.la: $(libhamlib_commradio_la_OBJECTS) $(libhamlib_commradio_la_DEPENDENCIES) $(EXTRA_libhamlib_commradio_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_commradio_la_OBJECTS) $(libhamlib_commradio_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commradio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctx10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/commradio.Plo -rm -f ./$(DEPDIR)/ctx10.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/commradio.Plo -rm -f ./$(DEPDIR)/ctx10.Plo -rm -f ./$(DEPDIR)/frame.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/commradio/ctx10.c0000644000175000017500000000604514752216205013732 00000000000000 #include #include "hamlib/rig.h" #include "bandplan.h" #include "commradio.h" /* * The CTX-10 has only one VFO, but can be set into some sort of "split" mode * where the screen shows two different frequencies. * So far I have not figured out how to access these via serial. */ #define CTX10_VFO (RIG_VFO_A) #define CTX10_RX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM) #define CTX10_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB) struct rig_caps ctx10_caps = { RIG_MODEL(RIG_MODEL_CTX10), .model_name = "CTX-10", .mfg_name = "Commradio", .version = "20240809.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 3000000, .serial_rate_max = 3000000, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, // .level_gran = {}, // .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, // .preamp = { RIG_DBLST_END, }, // .attenuator = { RIG_DBLST_END, }, // .max_rit = Hz(0), // .max_xit = Hz(0), // .max_ifshift = Hz(0), .targetable_vfo = 0, .vfo_ops = (RIG_OP_FROM_VFO | RIG_OP_TO_VFO), .scan_ops = RIG_SCAN_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30), CTX10_RX_MODES, -1, -1, CTX10_VFO, 0}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_80m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_60m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_40m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_30m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_20m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_17m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_15m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_12m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), FRQ_RNG_10m_REGION2(CTX10_TX_MODES, W(1), W(10), CTX10_VFO, 0), }, .tuning_steps = { {CTX10_RX_MODES, 10}, RIG_TS_END, }, // .async_data_supported = 1, //TODO: Revisit this // .decode_event = commradio_decode_event, .rig_init = commradio_init, // .rig_cleanup = commradio_cleanup, // .rig_open = commradio_rig_open, // .rig_close = commradio_rig_close, .get_freq = commradio_get_freq, .set_freq = commradio_set_freq, .get_mode = commradio_get_mode, .set_mode = commradio_set_mode, .get_vfo = commradio_get_vfo, .set_vfo = commradio_set_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/commradio/frame.h0000644000175000017500000000073514752216205014072 00000000000000/* * Hamlib CommRadio backend * idk, copyright and GPL here */ #ifndef _FRAME_H #define _FRAME_H #define CR_SOF 0xFE #define CR_EOF 0xFD #define CR_ESC 0xFC //TODO: Find out what the frame length actually is for IQ/spectrum data #define CR_FRAMELENGTH 256 int frame_message(unsigned char frame[], const unsigned char *data, int data_len); int commradio_unpack_frame(unsigned char msg[], const unsigned char *frame, int frame_len); #endif /* _FRAME_H */ hamlib-4.6.2/rigs/commradio/commradio.h0000644000175000017500000000131214752216205014742 00000000000000 #ifndef _COMMRADIO_H #define _COMMRADIO_H int commradio_transaction(RIG *rig, const unsigned char *cmd, int cmd_len, unsigned char *data, int *data_len); int commradio_init(RIG *rig); int commradio_cleanup(RIG *rig); int commradio_rig_open(RIG *rig); int commradio_rig_close(RIG *rig); int commradio_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int commradio_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int commradio_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int commradio_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int commradio_set_vfo(RIG *rig, vfo_t vfo); int commradio_get_vfo(RIG *rig, vfo_t *vfo); extern struct rig_caps ctx10_caps; #endif /* _COMMRADIO_H */ hamlib-4.6.2/rigs/commradio/Android.mk0000644000175000017500000000042214752216205014531 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := commradio.c ctx10.c frame.c LOCAL_MODULE := commradio LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/commradio/frame.c0000644000175000017500000001214314752216205014061 00000000000000/* * Hamlib CommRadio backend * idk, copyright and GPL here */ #include #include #include #include #include #include "frame.h" /* * Brute-force determined to be polynomial = 0x1021. * Seems to be the same CRC16 as Kermit. Initialized with 0. */ uint16_t crc16tab[] = { 0, 4489, 8978, 12955, 17956, 22445, 25910, 29887, 35912, 40385, 44890, 48851, 51820, 56293, 59774, 63735, 4225, 264, 13203, 8730, 22181, 18220, 30135, 25662, 40137, 36160, 49115, 44626, 56045, 52068, 63999, 59510, 8450, 12427, 528, 5017, 26406, 30383, 17460, 21949, 44362, 48323, 36440, 40913, 60270, 64231, 51324, 55797, 12675, 8202, 4753, 792, 30631, 26158, 21685, 17724, 48587, 44098, 40665, 36688, 64495, 60006, 55549, 51572, 16900, 21389, 24854, 28831, 1056, 5545, 10034, 14011, 52812, 57285, 60766, 64727, 34920, 39393, 43898, 47859, 21125, 17164, 29079, 24606, 5281, 1320, 14259, 9786, 57037, 53060, 64991, 60502, 39145, 35168, 48123, 43634, 25350, 29327, 16404, 20893, 9506, 13483, 1584, 6073, 61262, 65223, 52316, 56789, 43370, 47331, 35448, 39921, 29575, 25102, 20629, 16668, 13731, 9258, 5809, 1848, 65487, 60998, 56541, 52564, 47595, 43106, 39673, 35696, 33800, 38273, 42778, 46739, 49708, 54181, 57662, 61623, 2112, 6601, 11090, 15067, 20068, 24557, 28022, 31999, 38025, 34048, 47003, 42514, 53933, 49956, 61887, 57398, 6337, 2376, 15315, 10842, 24293, 20332, 32247, 27774, 42250, 46211, 34328, 38801, 58158, 62119, 49212, 53685, 10562, 14539, 2640, 7129, 28518, 32495, 19572, 24061, 46475, 41986, 38553, 34576, 62383, 57894, 53437, 49460, 14787, 10314, 6865, 2904, 32743, 28270, 23797, 19836, 50700, 55173, 58654, 62615, 32808, 37281, 41786, 45747, 19012, 23501, 26966, 30943, 3168, 7657, 12146, 16123, 54925, 50948, 62879, 58390, 37033, 33056, 46011, 41522, 23237, 19276, 31191, 26718, 7393, 3432, 16371, 11898, 59150, 63111, 50204, 54677, 41258, 45219, 33336, 37809, 27462, 31439, 18516, 23005, 11618, 15595, 3696, 8185, 63375, 58886, 54429, 50452, 45483, 40994, 37561, 33584, 31687, 27214, 22741, 18780, 15843, 11370, 7921, 3960 }; static uint16_t crc16byte(const unsigned char byte, uint16_t crc) { return crc16tab[(crc & 0xFF) ^ byte] ^ (crc >> 8); } static uint16_t crc16(const unsigned char *data, int data_len, uint16_t crc) { for (int i = 0; i < data_len; i++) { crc = crc16byte(data[i], crc); } return crc; } static int esc_append(unsigned char frame[], int idx, const unsigned char a) { switch (a) { case CR_SOF: case CR_EOF: case CR_ESC: frame[idx] = CR_ESC; frame[idx + 1] = a ^ 20; return idx + 2; break; default: frame[idx] = a; return idx + 1; } } /* * frame[] might be 2x the size of data and crc +3 bytes if it is just a long * string of 0xFC, 0xFD, or 0xFE for some insane reason. * */ int frame_message(unsigned char frame[], const unsigned char *data, const int data_len) { uint16_t crc = 0; frame[0] = CR_SOF; frame[1] = 0x21; /* Messages to the radio are always 0x21 */ crc = crc16byte(frame[1], crc); frame[2] = data[0]; crc = crc16byte(frame[2], crc); int frame_len = 3; for (int i = 1; i < data_len; i++) { crc = crc16byte(data[i], crc); frame_len = esc_append(frame, frame_len, data[i]); } frame_len = esc_append(frame, frame_len, crc >> 8); frame_len = esc_append(frame, frame_len, crc & 0xFF); frame[frame_len] = CR_EOF; frame_len++; return frame_len; } int commradio_unpack_frame(unsigned char msg[], const unsigned char *frame, const int frame_len) { if (frame_len < 5) { rig_debug(RIG_DEBUG_ERR, "%s Got a frame that was too small (<5) to be valid\n", __func__); return -RIG_ETRUNC; } if ((frame[0] != CR_SOF) || (frame[frame_len - 1] != CR_EOF)) { rig_debug(RIG_DEBUG_ERR, "%s Tried to unpack a frame without start or end\n", __func__); return -RIG_EPROTO; } if (frame[1] != 0x11) { rig_debug(RIG_DEBUG_ERR, "%s Message address is not for host (0x11)\n", __func__); return -RIG_EPROTO; } int msg_len = 0; for (int i = 2; i < frame_len; i++) { switch (frame[i]) { case CR_SOF: return -RIG_EPROTO; break; case CR_EOF: i = frame_len; break; case CR_ESC: i++; msg[msg_len] = frame[i] ^ 20; msg_len++; break; default: msg[msg_len] = frame[i]; msg_len++; } } uint16_t msg_crc = (msg[msg_len - 2] << 8) | msg[msg_len - 1]; msg_len = msg_len - 2; uint16_t crc = crc16(msg, msg_len, crc16byte(frame[1], 0)); if (msg_crc != crc) { rig_debug(RIG_DEBUG_ERR, "%s CRC check failed. msg_crc=%x, crc=%x\n", __func__, msg_crc, crc); } return msg_len; } hamlib-4.6.2/rigs/rs/0000755000175000017500000000000014752216244011357 500000000000000hamlib-4.6.2/rigs/rs/xk852.c0000644000175000017500000002656314752216205012335 00000000000000#include #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" #include "xk852.h" #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM LF #define EOM CR #define XK852_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_CW|RIG_MODE_AM) #define XK852_FUNC (RIG_FUNC_NONE) #define XK852_LEVEL_ALL (RIG_LEVEL_SQL | RIG_LEVEL_RFPOWER) #define XK852_PARM_ALL (RIG_PARM_NONE) #define XK852_VFO (RIG_VFO_A) #define XK852_VFO_OPS (RIG_OP_NONE) #define XK852_ANTS (RIG_ANT_1) #define XK852_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = XK852_FUNC, \ .levels = RIG_LEVEL_SET(XK852_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } int xk852_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: len=%d,cmd=%s\n", __func__, cmd_len, cmd); rig_flush(rp); rig_debug(RIG_DEBUG_VERBOSE, "xk852_transaction: len=%d,cmd=%s\n", cmd_len, cmd); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, RESPSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } // Send command discard return int xk852_send_command(RIG *rig, const char *cmd, int cmd_len) { char buf[RESPSZ]; int len; int retval = 0; retval = xk852_transaction(rig, cmd, cmd_len, buf, &len); return retval; } int xk852_parse_state(const char *msg, xk852_state *state) { int ret; ret = sscanf(msg, BOM "*F%7u" SCNfreq, &state -> freq); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse frequency from '%s'\n", __func__, msg); return -RIG_EPROTO; }; ret = sscanf(msg, "%*13cI%1u", &state -> mode); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse mode from '%s'\n", __func__, msg); return -RIG_EPROTO; }; ret = sscanf(msg, "%*23cN%1u", &state -> noise_blank); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse noise blanker state from '%s'\n", __func__, msg); return -RIG_EPROTO; }; ret = sscanf(msg, "%*31cS%1u", &state -> op_mode); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse op mode state from '%s'\n", __func__, msg); return -RIG_EPROTO; }; return RIG_OK; }; int xk852_query_state(RIG *rig, xk852_state *state) { char buf[RESPSZ]; int buf_len, ret; #define STATE_QUERY BOM "*O1" EOM ret = xk852_transaction(rig, STATE_QUERY, strlen(STATE_QUERY), buf, &buf_len); if (ret < 0) { return ret; } ret = xk852_parse_state(buf, state); return ret; }; /* * xk852_set_freq * Assumes rig!=NULL */ int xk852_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; char *fmt = BOM "*F%.7" PRIll EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s,freq=%.0f\n", __func__, rig_strvfo(vfo), freq); SNPRINTF(freqbuf, sizeof(freqbuf), fmt, (int64_t)((freq + 5) / 10)); retval = xk852_send_command(rig, freqbuf, strlen(freqbuf)); return retval; } /* * xk852_get_freq * Assumes rig!=NULL */ int xk852_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { xk852_state state; int ret; ret = xk852_query_state(rig, &state); *freq = (freq_t)(state.freq * 10); return ret; } /* * xk852_set_mode * Assumes rig!=NULL */ int xk852_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32]; xk852_mode smode; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(mode), (int)width); switch (mode) { case RIG_MODE_AM: smode = XK852_MODE_AME; break; case RIG_MODE_USB: smode = XK852_MODE_USB; break; case RIG_MODE_LSB: smode = XK852_MODE_LSB; break; case RIG_MODE_CW: smode = XK852_MODE_CW; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "*I%1u" EOM, smode); retval = xk852_send_command(rig, buf, strlen(buf)); return retval; } /* * xk852_get_mode * Assumes rig!=NULL */ int xk852_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { xk852_state state; int ret; ret = xk852_query_state(rig, &state); if (ret != RIG_OK) { return ret; } switch (state.mode) { case XK852_MODE_AME: *mode = RIG_MODE_AM; break; case XK852_MODE_USB: *mode = RIG_MODE_USB; break; case XK852_MODE_LSB: *mode = RIG_MODE_LSB; break; case XK852_MODE_CW: *mode = RIG_MODE_CW; break; default: return -RIG_EINVAL; } return RIG_OK; } int xk852_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[64]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_RFPOWER: if (val.f >= 0.5) SNPRINTF(buf, sizeof(buf), BOM "*S4" EOM) else if (val.f >= 0.1) SNPRINTF(buf, sizeof(buf), BOM "*S3" EOM) else if (val.f >= 0.001) SNPRINTF(buf, sizeof(buf), BOM "*S2" EOM) else { SNPRINTF(buf, sizeof(buf), BOM "*S1" EOM); } break; case RIG_LEVEL_SQL: if (val.f <= 0.5) SNPRINTF(buf, sizeof(buf), BOM "*N0" EOM) else { SNPRINTF(buf, sizeof(buf), BOM "*N1" EOM); } break; case RIG_LEVEL_AGC: case RIG_LEVEL_AF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = xk852_send_command(rig, buf, strlen(buf)); return retval; } int xk852_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; xk852_state state; ret = xk852_query_state(rig, &state); if (ret != RIG_OK) { return ret; } switch (level) { case RIG_LEVEL_SQL: switch (state.noise_blank) { case XK852_NOISE_BLANK_OFF: val->f = 1; return RIG_OK; break; case XK852_NOISE_BLANK_ON: val->f = 0; return RIG_OK; break; } case RIG_LEVEL_RFPOWER: switch (state.op_mode) { case XK852_OP_MODE_OFF: val->f = 0; return RIG_OK; break; case XK852_OP_MODE_RX: val->f = 0; return RIG_OK; break; case XK852_OP_MODE_TX_LOW: val->f = 0.099; return RIG_OK; break; case XK852_OP_MODE_TX_MID: val->f = 0.499; return RIG_OK; break; case XK852_OP_MODE_TX_FULL: val->f = 1; return RIG_OK; break; } default: return -RIG_ENIMPL; break; } return -RIG_EINVAL; } int xk852_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval = 0; char cmd[32]; int ptt_code = 2; switch (ptt) { case RIG_PTT_OFF: ptt_code = 2; break; case RIG_PTT_ON: ptt_code = 1; break; case RIG_PTT_ON_MIC: ptt_code = 1; break; case RIG_PTT_ON_DATA: ptt_code = 1; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), BOM "*X%1d" EOM, ptt_code); retval = xk852_transaction(rig, cmd, strlen(cmd), NULL, NULL); return retval; } int xk852_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { // int retval = 0; // int len; // char buf[RESPSZ]; // char *cmd = BOM "X?" EOM; // rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); // retval = xk852_transaction(rig, cmd, strlen(cmd), buf, &len); // if (retval < 0) // { // return retval; // } // retval = (sscanf(buf, "%*cX%1u", ptt) == 1) ? RIG_OK : -RIG_EPROTO; *ptt = RIG_PTT_OFF; return RIG_OK; } /* * XK852 rig capabilities. */ struct rig_caps xk852_caps = { RIG_MODEL(RIG_MODEL_XK852), .model_name = "XK852", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_ALPHA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, // Need to set RTS on for some reason // And HANDSHAKE_NONE even though HARDWARE is what is called for .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 200, //nach senden warten // also see post_ptt_delay (in manpage) .timeout = 200, .retry = 3, .has_get_func = XK852_FUNC, .has_set_func = XK852_FUNC, .has_get_level = XK852_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(XK852_LEVEL_ALL), .has_get_parm = XK852_PARM_ALL, .has_set_parm = RIG_PARM_SET(XK852_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {RIG_DBLST_END}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = XK852_VFO_OPS, .chan_list = { {0, 99, RIG_MTYPE_MEM, XK852_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(1500), MHz(30), XK852_MODES, -1, -1, XK852_VFO, XK852_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(1500), MHz(30), XK852_MODES, 0, 150000, XK852_VFO, XK852_ANTS }, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_ALL, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(150)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {XK852_MODES, kHz(2.4)}, {XK852_MODES, kHz(1.5)}, {XK852_MODES, Hz(150)}, {XK852_MODES, Hz(300)}, {XK852_MODES, Hz(600)}, {XK852_MODES, kHz(6)}, {XK852_MODES, kHz(9)}, {XK852_MODES, kHz(15)}, {XK852_MODES, kHz(30)}, {XK852_MODES, kHz(50)}, {XK852_MODES, kHz(120)}, RIG_FLT_END, }, .priv = NULL, .set_ptt = xk852_set_ptt, .get_ptt = xk852_get_ptt, .set_freq = xk852_set_freq, .get_freq = xk852_get_freq, .set_mode = xk852_set_mode, .get_mode = xk852_get_mode, .set_level = xk852_set_level, .get_level = xk852_get_level, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/rs/gp2000.c0000644000175000017500000002472714752216205012364 00000000000000/* * Hamlib R&S GP2000 backend - main file * Reused from rs.c * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stéphane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Looks like the GP2000 could be reused in other rigs so * we implement that and then the XK2100 uses this interface */ #include #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" #include "gp2000.h" #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM LF #define EOM CR /* * R&S GB2 protocol ? */ /* * gp2000 * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int gp2000_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: len=%d,cmd=%s\n", __func__, cmd_len, cmd); rig_flush(rp); rig_debug(RIG_DEBUG_VERBOSE, "gp2000_transaction: len=%d,cmd=%s\n", cmd_len, cmd); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, RESPSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * gp2000_set_freq * Assumes rig!=NULL */ int gp2000_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; // cppcheck-suppress * char *fmt = BOM "F%" PRIll ",%" PRIll EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s,freq=%.0f\n", __func__, rig_strvfo(vfo), freq); SNPRINTF(freqbuf, sizeof(freqbuf), fmt, (int64_t) freq, (int64_t) freq); retval = gp2000_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * gp2000_get_freq * Assumes rig!=NULL */ int gp2000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[RESPSZ]; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define FREQ_QUERY BOM "F?" EOM retval = gp2000_transaction(rig, FREQ_QUERY, strlen(FREQ_QUERY), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%*cF%" SCNfreq, freq) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } /* * gp2000_set_mode * Assumes rig!=NULL */ int gp2000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32], *smode; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(mode), (int)width); switch (mode) { case RIG_MODE_AM: smode = "1"; break; case RIG_MODE_USB: smode = "2"; break; case RIG_MODE_LSB: smode = "3"; break; case RIG_MODE_CW: smode = "5"; break; case RIG_MODE_FM: smode = "9"; break; case RIG_MODE_PKTUSB: smode = "13"; // use the 2700 bandwidth for packet break; case RIG_MODE_PKTLSB: smode = "14"; // use the 2700 bandwidth for packet break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "I%s" EOM, smode); retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); if (retval < 0) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width > 0) { SNPRINTF(buf, sizeof(buf), BOM "W%d" EOM, (int) width); retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); } return retval; } /* * gp2000_get_mode * Assumes rig!=NULL */ int gp2000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[RESPSZ]; int buf_len, retval; int nmode; char *pmode = "UNKNOWN"; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define DEM_QUERY BOM "I?" EOM retval = gp2000_transaction(rig, DEM_QUERY, strlen(DEM_QUERY), buf, &buf_len); if (retval < 0) { return retval; } n = sscanf(buf, "%*cI%d", &nmode); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse mode from '%s'\n", __func__, buf); return -RIG_EPROTO; } switch (nmode) { case 1: pmode = "AM"; break; case 2: pmode = "USB"; break; case 3: pmode = "LSB"; break; case 5: pmode = "CW"; break; case 9: pmode = "FM"; break; case 13: pmode = "PKTUSB"; break; case 14: pmode = "PKTLSB"; break; } *mode = rig_parse_mode(pmode); #define BAND_QUERY BOM "W?" EOM retval = gp2000_transaction(rig, BAND_QUERY, strlen(BAND_QUERY), buf, &buf_len); if (retval < 0) { return retval; } *width = atoi(&buf[2]); return retval; } #ifdef XXREMOVEDXX // Not referenced anywhere int gp2000_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[32], *sfunc; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = "SQ00"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "%s %s" EOM, sfunc, status ? "1" : "0"); retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } #endif #ifdef XXREMOVEDXX // Not referenced anywhere int gp2000_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[RESPSZ], *sfunc; int buf_len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = BOM "SQ00?" EOM; break; default: return -RIG_EINVAL; } retval = gp2000_transaction(rig, sfunc, strlen(sfunc), buf, &buf_len); if (retval < 0) { return retval; } // we expected LF+"X" where X is the status *status = buf[2] == 1 ? 1 : 0; return retval; } #endif int gp2000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[64]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: SNPRINTF(buf, sizeof(buf), BOM "SR%02d" EOM, (int)val.f); break; case RIG_LEVEL_SQL: SNPRINTF(buf, sizeof(buf), BOM "SQ%1d" EOM, (int)val.f); break; case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = gp2000_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int gp2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[RESPSZ], *slevel; int buf_len, retval, ival; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_AF: slevel = BOM "SL?" EOM; break; case RIG_LEVEL_SQL: slevel = BOM "SQ?" EOM; break; case RIG_LEVEL_STRENGTH: case RIG_LEVEL_ATT: case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = gp2000_transaction(rig, slevel, strlen(slevel), buf, &buf_len); if (retval < 0) { return retval; } switch (level) { case RIG_LEVEL_AF: if (num_sscanf(buf, "%*cSL%d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival; break; case RIG_LEVEL_SQL: if (num_sscanf(buf, "%*cSQ%1d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival; break; default: return -RIG_EINVAL; } return retval; } const char * gp2000_get_info(RIG *rig) { static char infobuf[128]; int info_len, retval; int addr = -1; char type[32] = "unk type"; char rigid[32] = "unk rigid"; char sernum[32] = "unk sernum"; char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s\n", __func__); #define ID_QUERY BOM "IDENT?" EOM retval = gp2000_transaction(rig, ID_QUERY, strlen(ID_QUERY), infobuf, &info_len); if (retval < 0) { return NULL; } p = strtok(infobuf, ","); while (p) { switch (p[0]) { case 0x0a: sscanf(p, "%*cIDENT%31s", type); break; case 'i': sscanf(p, "id%31s", rigid); break; case 's': sscanf(p, "sn%31s", sernum); break; default: printf("Unknown response: %s\n", p); } p = strtok(NULL, ","); } SNPRINTF(infobuf, sizeof(infobuf), "ADDR=%02d\nTYPE=%s\nSER#=%s\nID =%s\n", addr, type, sernum, rigid); return infobuf; } int gp2000_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval = 0; char cmd[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); SNPRINTF(cmd, sizeof(cmd), "X%1d", ptt); retval = gp2000_transaction(rig, cmd, strlen(cmd), NULL, NULL); return retval; } int gp2000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval = 0; int len; char buf[RESPSZ]; char *cmd = BOM "X?" EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); retval = gp2000_transaction(rig, cmd, strlen(cmd), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%*cX%1u", ptt) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } hamlib-4.6.2/rigs/rs/Makefile.am0000644000175000017500000000027614752216205013335 00000000000000RSSRC = esmc.c eb200.c rs.c rs.h gp2000.c gp2000.h xk2100.c ek89x.c ek89x.h xk852.h xk852.c noinst_LTLIBRARIES = libhamlib-rs.la libhamlib_rs_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/rs/rs.h0000644000175000017500000000314014752216205012067 00000000000000/* * Hamlib R&S backend - main header * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _RS_H #define _RS_H 1 #include #define BACKEND_VER "20090803" int rs_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int rs_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int rs_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int rs_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int rs_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int rs_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int rs_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int rs_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int rs_reset(RIG *rig, reset_t reset); const char * rs_get_info(RIG *rig); extern struct rig_caps esmc_caps; extern struct rig_caps eb200_caps; #endif /* _RS_H */ hamlib-4.6.2/rigs/rs/Makefile.in0000644000175000017500000005415014752216216013350 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/rs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_rs_la_LIBADD = am__objects_1 = esmc.lo eb200.lo rs.lo gp2000.lo xk2100.lo ek89x.lo \ xk852.lo am_libhamlib_rs_la_OBJECTS = $(am__objects_1) libhamlib_rs_la_OBJECTS = $(am_libhamlib_rs_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/eb200.Plo ./$(DEPDIR)/ek89x.Plo \ ./$(DEPDIR)/esmc.Plo ./$(DEPDIR)/gp2000.Plo ./$(DEPDIR)/rs.Plo \ ./$(DEPDIR)/xk2100.Plo ./$(DEPDIR)/xk852.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_rs_la_SOURCES) DIST_SOURCES = $(libhamlib_rs_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ RSSRC = esmc.c eb200.c rs.c rs.h gp2000.c gp2000.h xk2100.c ek89x.c ek89x.h xk852.h xk852.c noinst_LTLIBRARIES = libhamlib-rs.la libhamlib_rs_la_SOURCES = $(RSSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/rs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/rs/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-rs.la: $(libhamlib_rs_la_OBJECTS) $(libhamlib_rs_la_DEPENDENCIES) $(EXTRA_libhamlib_rs_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_rs_la_OBJECTS) $(libhamlib_rs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eb200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ek89x.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/esmc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gp2000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rs.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xk2100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xk852.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/eb200.Plo -rm -f ./$(DEPDIR)/ek89x.Plo -rm -f ./$(DEPDIR)/esmc.Plo -rm -f ./$(DEPDIR)/gp2000.Plo -rm -f ./$(DEPDIR)/rs.Plo -rm -f ./$(DEPDIR)/xk2100.Plo -rm -f ./$(DEPDIR)/xk852.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/eb200.Plo -rm -f ./$(DEPDIR)/ek89x.Plo -rm -f ./$(DEPDIR)/esmc.Plo -rm -f ./$(DEPDIR)/gp2000.Plo -rm -f ./$(DEPDIR)/rs.Plo -rm -f ./$(DEPDIR)/xk2100.Plo -rm -f ./$(DEPDIR)/xk852.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/rs/Android.mk0000644000175000017500000000042314752216205013204 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := esmc.c eb200.c rs.c xk2100.c gp2000.c LOCAL_MODULE := rs LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/rs/ek89x.h0000644000175000017500000000346014752216205012420 00000000000000/* * Hamlib R&S backend for EK895/896 - main header * Reused from gp2000.c * Copyright (c) 2022 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _EK89X_H #define _EK89X_H 1 #include int ek89x_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int ek89x_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int ek89x_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int ek89x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int ek89x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int ek89x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int ek89x_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int ek89x_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int ek89x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int ek89x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int ek89x_reset(RIG *rig, reset_t reset); const char * gek89x_get_info(RIG *rig); extern struct rig_caps ek89x_caps; #endif /* EK89X_H */ hamlib-4.6.2/rigs/rs/rs.c0000644000175000017500000001772314752216205012076 00000000000000/* * Hamlib R&S backend - main file * Copyright (c) 2009-2010 by Stéphane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "register.h" #include "num_stdio.h" #include "rs.h" #include "gp2000.h" #include "ek89x.h" #include "xk852.h" #define BUFSZ 64 #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM CR #define EOM CR /* * R&S GB2 protocol ? */ /* * rs_transaction * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int rs_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, BUFSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * rs_set_freq * Assumes rig!=NULL */ int rs_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; SNPRINTF(freqbuf, sizeof(freqbuf), BOM "FREQ %"PRIll EOM, (int64_t)freq); retval = rs_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * rs_get_freq * Assumes rig!=NULL */ int rs_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[RESPSZ]; int len, retval; #define FREQ_QUERY BOM "FREQ?" EOM retval = rs_transaction(rig, FREQ_QUERY, strlen(FREQ_QUERY), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%"SCNfreq, freq) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } /* * rs_set_mode * Assumes rig!=NULL */ int rs_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32], *smode; int retval; switch (mode) { case RIG_MODE_AM: smode = "AM"; break; case RIG_MODE_WFM: case RIG_MODE_FM: smode = "FM"; break; case RIG_MODE_CW: smode = "CW"; break; case RIG_MODE_USB: smode = "USB"; break; case RIG_MODE_LSB: smode = "LSB"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "DEM %s" EOM, smode); retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); if (retval < 0) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width > 0) { SNPRINTF(buf, sizeof(buf), BOM "BAND %d" EOM, (int) width); retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); } return retval; } /* * rs_get_mode * Assumes rig!=NULL */ int rs_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[RESPSZ]; int buf_len, retval; #define DEM_QUERY BOM "DEM?" EOM retval = rs_transaction(rig, DEM_QUERY, strlen(DEM_QUERY), buf, &buf_len); if (retval < 0) { return retval; } *mode = rig_parse_mode(buf); #define BAND_QUERY BOM "BAND?" EOM retval = rs_transaction(rig, BAND_QUERY, strlen(BAND_QUERY), buf, &buf_len); if (retval < 0) { return retval; } *width = atoi(buf); return retval; } int rs_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[32], *sfunc; int retval; switch (func) { case RIG_FUNC_AFC: sfunc = "FREQ:AFC"; break; case RIG_FUNC_SQL: sfunc = "OUTP:SQU"; break; case RIG_FUNC_LOCK: sfunc = "DISP:ENAB"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "%s %s" EOM, sfunc, status ? "ON" : "OFF"); retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int rs_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[RESPSZ], *sfunc; int buf_len, retval; switch (func) { case RIG_FUNC_AFC: sfunc = BOM "FREQ:AFC?" EOM; break; case RIG_FUNC_SQL: sfunc = BOM "OUTP:SQU?" EOM; break; case RIG_FUNC_LOCK: sfunc = BOM "DISP:ENAB?" EOM; break; default: return -RIG_EINVAL; } retval = rs_transaction(rig, sfunc, strlen(sfunc), buf, &buf_len); if (retval < 0) { return retval; } *status = (!memcmp(buf, "ON", 2) || !memcmp(buf, "1", 1)) ? 1 : 0; return retval; } int rs_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[32]; int retval; switch (level) { case RIG_LEVEL_ATT: SNPRINTF(buf, sizeof(buf), BOM "INP:ATT:STAT %s" EOM, val.i ? "ON" : "OFF"); break; case RIG_LEVEL_SQL: /* dBuV */ SNPRINTF(buf, sizeof(buf), BOM "OUTP:SQU:THR %d" EOM, (int)(20 + val.f * 20)); break; case RIG_LEVEL_AF: num_snprintf(buf, sizeof(buf), BOM "SYST:AUD:VOL %.1f" EOM, val.f); break; case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = rs_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int rs_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[RESPSZ], *slevel; int buf_len, retval; switch (level) { case RIG_LEVEL_STRENGTH: slevel = BOM "SENS:DATA? \"VOLT:AC\"" EOM; break; case RIG_LEVEL_ATT: slevel = BOM "INP:ATT:STAT?" EOM; break; case RIG_LEVEL_AF: slevel = BOM "SYST:AUD:VOL?" EOM; break; case RIG_LEVEL_SQL: case RIG_LEVEL_AGC: case RIG_LEVEL_RF: return -RIG_ENIMPL; default: return -RIG_EINVAL; } retval = rs_transaction(rig, slevel, strlen(slevel), buf, &buf_len); if (retval < 0) { return retval; } switch (level) { case RIG_LEVEL_STRENGTH: /* assumes FORMAat:DATA ASCii * result in dBuV, keep only integer part */ sscanf(buf, "%d", &val->i); val->i -= 34; break; case RIG_LEVEL_ATT: val->i = (!memcmp(buf, "ON", 2) || !memcmp(buf, "1", 1)) ? STATE(rig)->attenuator[0] : 0; break; case RIG_LEVEL_AF: if (num_sscanf(buf, "%f", &val->f) != 1) { return -RIG_EPROTO; } break; default: return -RIG_EINVAL; } return retval; } const char *rs_get_info(RIG *rig) { static char infobuf[128]; int info_len, retval; #define ID_QUERY BOM "*IDN?" EOM retval = rs_transaction(rig, ID_QUERY, strlen(ID_QUERY), infobuf, &info_len); if (retval < 0) { return NULL; } return infobuf; } int rs_reset(RIG *rig, reset_t reset) { int retval; #define RST_CMD BOM "*RST" EOM retval = rs_transaction(rig, RST_CMD, strlen(RST_CMD), NULL, NULL); return retval; } /* * initrigs_rs is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(rs) { rig_debug(RIG_DEBUG_VERBOSE, "%s: _init called\n", __func__); rig_register(&esmc_caps); rig_register(&eb200_caps); rig_register(&xk2100_caps); rig_register(&xk852_caps); rig_register(&ek89x_caps); return RIG_OK; } hamlib-4.6.2/rigs/rs/ek89x.c0000644000175000017500000003326214752216205012416 00000000000000/* * Hamlib R&S EK895/896 backend - main file * Reused from p2000.c * Copyright (c) 2022 by Michael Black W9MDB * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stéphane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Looks like the GP2000 could be reused in other rigs so * we implement that and then the EK89X uses this interface */ #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "num_stdio.h" #include "ek89x.h" #define RESPSZ 64 #define LF "\x0a" #define CR "\x0d" #define BOM LF #define EOM CR /* * ek89x * We assume that rig!=NULL, STATE(rig)!= NULL, data!=NULL, data_len!=NULL */ int ek89x_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: len=%d,cmd=%s\n", __func__, cmd_len, cmd); rig_flush(rp); rig_debug(RIG_DEBUG_VERBOSE, "ek89x_transaction: len=%d,cmd=%s\n", cmd_len, cmd); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* no data expected */ if (!data || !data_len) { return RIG_OK; } retval = read_string(rp, (unsigned char *) data, RESPSZ, CR, 1, 0, 1); if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * ek89x_set_freq * Assumes rig!=NULL */ int ek89x_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[32]; int retval; // cppcheck-suppress * char *fmt = BOM "F%" PRIll EOM; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s,freq=%.0f\n", __func__, rig_strvfo(vfo), freq); SNPRINTF(freqbuf, sizeof(freqbuf), fmt, (int64_t) freq, (int64_t) freq); retval = ek89x_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * ek89x_get_freq * Assumes rig!=NULL */ int ek89x_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[RESPSZ]; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define FREQ_QUERY BOM "F?" EOM retval = ek89x_transaction(rig, FREQ_QUERY, strlen(FREQ_QUERY), buf, &len); if (retval < 0) { return retval; } retval = (sscanf(buf, "%*cF%" SCNfreq, freq) == 1) ? RIG_OK : -RIG_EPROTO; return retval; } /* * ek89x_set_mode * Assumes rig!=NULL */ int ek89x_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[32], *smode; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(mode), (int)width); switch (mode) { case RIG_MODE_USB: smode = "15"; break; case RIG_MODE_LSB: smode = "16"; break; case RIG_MODE_ISBUSB: smode = "17"; break; case RIG_MODE_ISBLSB: smode = "18"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "I%s" EOM, smode); retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); if (retval < 0) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width > 0) { if (width <= 150) { width = 1; } else if (width <= 300) { width = 3; } else if (width <= 600) { width = 6; } else if (width <= 1000) { width = 10; } else if (width <= 1500) { width = 15; } else if (width <= 2100) { width = 21; } else if (width <= 2400) { width = 24; } else if (width <= 2700) { width = 27; } else if (width <= 3100) { width = 31; } else if (width <= 4000) { width = 40; } else if (width <= 4800) { width = 48; } else if (width <= 6000) { width = 60; } else if (width <= 8000) { width = 80; } SNPRINTF(buf, sizeof(buf), BOM "W%d" EOM, (int) width); retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); } return retval; } /* * ek89x_get_mode * Assumes rig!=NULL */ int ek89x_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[RESPSZ]; int buf_len, retval; int nmode; char *pmode = "UNKNOWN"; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); #define DEM_QUERY BOM "I?" EOM retval = ek89x_transaction(rig, DEM_QUERY, strlen(DEM_QUERY), buf, &buf_len); if (retval < 0) { return retval; } n = sscanf(buf, "%*cI%d", &nmode); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse mode from '%s'\n", __func__, buf); return -RIG_EPROTO; } switch (nmode) { case 15: pmode = "USB"; break; case 16: pmode = "LSB"; break; } *mode = rig_parse_mode(pmode); #define BAND_QUERY BOM "FIB?" EOM retval = ek89x_transaction(rig, BAND_QUERY, strlen(BAND_QUERY), buf, &buf_len); if (retval < 0) { return retval; } int twidth; sscanf(buf, "%*cFIB%d", &twidth); if (twidth == 1) { *width = 150; } else { *width = twidth * 100; } return retval; } #ifdef XXREMOVEDXX // Not referenced anywhere int ek89x_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[32], *sfunc; int len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = "SQ00"; break; default: return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), BOM "%s %s" EOM, sfunc, status ? "1" : "0"); retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } #endif #ifdef XXREMOVEDXX // Not referenced anywhere int ek89x_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[RESPSZ], *sfunc; int buf_len, retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (func) { case RIG_FUNC_SQL: sfunc = BOM "SQ00?" EOM; break; default: return -RIG_EINVAL; } retval = ek89x_transaction(rig, sfunc, strlen(sfunc), buf, &buf_len); if (retval < 0) { return retval; } // we expected LF+"X" where X is the status *status = buf[2] == 1 ? 1 : 0; return retval; } #endif int ek89x_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[64]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_PREAMP: SNPRINTF(buf, sizeof(buf), BOM "PA%d" EOM, (int)val.f); break; default: return -RIG_EINVAL; } retval = ek89x_transaction(rig, buf, strlen(buf), NULL, NULL); return retval; } int ek89x_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[RESPSZ], *slevel; int buf_len, retval, ival; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __func__, rig_strvfo(vfo)); switch (level) { case RIG_LEVEL_PREAMP: slevel = BOM "PA?" EOM; break; case RIG_LEVEL_STRENGTH: slevel = BOM "L?" EOM; break; default: return -RIG_EINVAL; } retval = ek89x_transaction(rig, slevel, strlen(slevel), buf, &buf_len); if (retval < 0) { return retval; } switch (level) { case RIG_LEVEL_PREAMP: if (num_sscanf(buf, "%*cPA%d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival; break; case RIG_LEVEL_STRENGTH: if (num_sscanf(buf, "%*cL%d", &ival) != 1) { return -RIG_EPROTO; } val->f = ival - 34; // approximately break; default: return -RIG_EINVAL; } return retval; } const char * ek89x_get_info(RIG *rig) { static char infobuf[128]; int info_len, retval; int addr = -1; char type[32] = "unk type"; char rigid[32] = "unk rigid"; char sernum[32] = "unk sernum"; char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s\n", __func__); #define ID_QUERY BOM "IDENT?" EOM retval = ek89x_transaction(rig, ID_QUERY, strlen(ID_QUERY), infobuf, &info_len); if (retval < 0) { return NULL; } p = strtok(infobuf, ","); while (p) { switch (p[0]) { case 0x0a: sscanf(p, "%*cIDENT%31s", type); break; case 'i': sscanf(p, "id%31s", rigid); break; case 's': sscanf(p, "sn%31s", sernum); break; default: printf("Unknown response: %s\n", p); } p = strtok(NULL, ","); } SNPRINTF(infobuf, sizeof(infobuf), "ADDR=%02d\nTYPE=%s\nSER#=%s\nID =%s\n", addr, type, sernum, rigid); return infobuf; } #define EK89X_MODES (RIG_MODE_USB|RIG_MODE_LSB) #define EK89X_FUNC (RIG_FUNC_SQL) #define EK89X_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH) #define EK89X_PARM_ALL (RIG_PARM_NONE) #define EK89X_VFO (RIG_VFO_A) #define EK89X_VFO_OPS (RIG_OP_NONE) #define EK89X_ANTS (RIG_ANT_1) #define EK89X_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = EK89X_FUNC, \ .levels = RIG_LEVEL_SET(EK89X_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * EK89X rig capabilities. * * Had to use NONE for flow control and set RTS high * We are not using address mode since we're on RS232 for now * If using RS485 should add address capability * * TODO * - set/get_channels */ struct rig_caps ek89x_caps = { RIG_MODEL(RIG_MODEL_EK89X), .model_name = "EK895/6", .mfg_name = "Rohde&Schwarz", .version = "20220813.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, // Need to set RTS on for some reason // And HANDSHAKE_NONE even though HARDWARE is what is called for .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 38400, .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_ODD, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = EK89X_FUNC, .has_set_func = EK89X_FUNC, .has_get_level = EK89X_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(EK89X_LEVEL_ALL), .has_get_parm = EK89X_PARM_ALL, .has_set_parm = RIG_PARM_SET(EK89X_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {32, RIG_DBLST_END}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ //.vfo_ops = XK2100_VFO_OPS, .chan_list = { {0, 999, RIG_MTYPE_MEM, EK89X_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(0), MHz(30), EK89X_MODES, -1, -1, EK89X_VFO, EK89X_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { { kHz(0), MHz(30), EK89X_MODES, -1, -1, EK89X_VFO, EK89X_ANTS }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* .tuning_steps = { {EK89X_MODES,1}, {EK89X_MODES,10}, {EK89X_MODES,100}, {EK89X_MODES,1000}, RIG_TS_END, }, */ /* mode/filter list, remember: order matters! */ .filters = { {EK89X_MODES, kHz(8.0)}, {EK89X_MODES, kHz(6.0)}, {EK89X_MODES, Hz(4.8)}, {EK89X_MODES, Hz(4.0)}, {EK89X_MODES, Hz(3.1)}, {EK89X_MODES, kHz(2.7)}, {EK89X_MODES, kHz(2.4)}, {EK89X_MODES, kHz(1.5)}, {EK89X_MODES, kHz(1.0)}, {EK89X_MODES, Hz(600)}, {EK89X_MODES, Hz(300)}, {EK89X_MODES, Hz(150)}, RIG_FLT_END, }, .priv = NULL, // .set_ptt = ek89x_set_ptt, receiver only // .get_ptt = ek89x_get_ptt, receiver only .set_freq = ek89x_set_freq, .get_freq = ek89x_get_freq, .set_mode = ek89x_set_mode, .get_mode = ek89x_get_mode, .set_level = ek89x_set_level, .get_level = ek89x_get_level, //.set_func = ek89x_set_func, //.get_func = ek89x_get_func, .get_info = ek89x_get_info, #if 0 /* TODO */ .rig_open = ek89x_rig_open, .set_channel = ek89x_set_channel, .get_channel = ek89x_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/rs/esmc.c0000644000175000017500000001135014752216205012367 00000000000000/* * Hamlib R&S backend - ESMC description * Copyright (c) 2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "rs.h" /* TODO: LOG and PULSE ? */ #define ESMC_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define ESMC_FUNC (RIG_FUNC_SQL|RIG_FUNC_AFC) #define ESMC_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_STRENGTH) #define ESMC_PARM_ALL (RIG_PARM_NONE) #define ESMC_VFO (RIG_VFO_A) #define ESMC_VFO_OPS (RIG_OP_NONE) #define ESMC_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = ESMC_FUNC, \ .levels = RIG_LEVEL_SET(ESMC_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * ESMC rig capabilities. * * Needs option ESMC-R2 for computer operation RS232C/RS422/RS485 * * http://www2.rohde-schwarz.com/file/ESMC_25.pdf */ struct rig_caps esmc_caps = { RIG_MODEL(RIG_MODEL_ESMC), .model_name = "ESMC", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, /* 7E2 */ .serial_rate_max = 115200, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = ESMC_FUNC, .has_set_func = ESMC_FUNC, .has_get_level = ESMC_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(ESMC_LEVEL_ALL), .has_get_parm = ESMC_PARM_ALL, .has_set_parm = RIG_PARM_SET(ESMC_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 30, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = ESMC_VFO_OPS, .chan_list = { { 0, 999, RIG_MTYPE_MEM, ESMC_MEM_CAP }, RIG_CHAN_END, }, /* * With following options: * ESMC-T2 20 MHz to 1.3 GHz * ESMC-T0 0.5 MHz to 30 MHz * ESMC-FE 20 MHz to 3 GHz */ .rx_range_list1 = { {kHz(20), MHz(650), ESMC_MODES, -1, -1, ESMC_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(20), MHz(650), ESMC_MODES, -1, -1, ESMC_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {ESMC_MODES, 1}, {ESMC_MODES, 10}, {ESMC_MODES, 100}, {ESMC_MODES, 1000}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(200)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {ESMC_MODES, kHz(2.5)}, {ESMC_MODES, kHz(0.5)}, {ESMC_MODES, kHz(8)}, {ESMC_MODES, kHz(15)}, {ESMC_MODES, kHz(30)}, {ESMC_MODES, kHz(50)}, {ESMC_MODES, kHz(100)}, {ESMC_MODES, kHz(200)}, {ESMC_MODES, kHz(500)}, {ESMC_MODES, MHz(1)}, {ESMC_MODES, MHz(2)}, {ESMC_MODES, MHz(4)}, {ESMC_MODES, MHz(8)}, RIG_FLT_END, }, .priv = NULL, .set_freq = rs_set_freq, .get_freq = rs_get_freq, .set_mode = rs_set_mode, .get_mode = rs_get_mode, .set_level = rs_set_level, .get_level = rs_get_level, .set_func = rs_set_func, .get_func = rs_get_func, .get_info = rs_get_info, #if 0 /* TODO */ .rig_open = rs_rig_open, .set_channel = rs_set_channel, .get_channel = rs_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/rs/xk2100.c0000644000175000017500000001235214752216205012370 00000000000000/* * Hamlib R&S backend - XK2100 description * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "gp2000.h" #define XK2100_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM) #define XK2100_FUNC (RIG_FUNC_SQL) /* #define XK2100_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC| \ * RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_STRENGTH) */ #define XK2100_LEVEL_ALL (RIG_LEVEL_SQL|\ RIG_LEVEL_AF) #define XK2100_PARM_ALL (RIG_PARM_NONE) #define XK2100_VFO (RIG_VFO_A) #define XK2100_VFO_OPS (RIG_OP_NONE) #define XK2100_ANTS (RIG_ANT_1) #define XK2100_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = XK2100_FUNC, \ .levels = RIG_LEVEL_SET(XK2100_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * XK2100 rig capabilities. * * Had to use NONE for flow control and set RTS high * We are not using address mode since we're on RS232 for now * If using RS485 should add address capability * * TODO * - set/get_channels */ struct rig_caps xk2100_caps = { RIG_MODEL(RIG_MODEL_XK2100), .model_name = "XK2100", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, // Need to set RTS on for some reason // And HANDSHAKE_NONE even though HARDWARE is what is called for .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 38400, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = XK2100_FUNC, .has_set_func = XK2100_FUNC, .has_get_level = XK2100_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(XK2100_LEVEL_ALL), .has_get_parm = XK2100_PARM_ALL, .has_set_parm = RIG_PARM_SET(XK2100_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = {RIG_DBLST_END}, .attenuator = {32, RIG_DBLST_END}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = XK2100_VFO_OPS, .chan_list = { {0, 99, RIG_MTYPE_MEM, XK2100_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(1500), MHz(30), XK2100_MODES, -1, -1, XK2100_VFO, XK2100_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { { kHz(1500), MHz(30), XK2100_MODES, -1, -1, XK2100_VFO, XK2100_ANTS }, RIG_FRNG_END, }, .tx_range_list2 = {RIG_FRNG_END,}, .tuning_steps = { // Rem: no support for changing tuning step {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* .tuning_steps = { {XK2100_MODES,1}, {XK2100_MODES,10}, {XK2100_MODES,100}, {XK2100_MODES,1000}, RIG_TS_END, }, */ /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(150)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {XK2100_MODES, kHz(2.4)}, {XK2100_MODES, kHz(1.5)}, {XK2100_MODES, Hz(150)}, {XK2100_MODES, Hz(300)}, {XK2100_MODES, Hz(600)}, {XK2100_MODES, kHz(6)}, {XK2100_MODES, kHz(9)}, {XK2100_MODES, kHz(15)}, {XK2100_MODES, kHz(30)}, {XK2100_MODES, kHz(50)}, {XK2100_MODES, kHz(120)}, RIG_FLT_END, }, .priv = NULL, .set_ptt = gp2000_set_ptt, .get_ptt = gp2000_get_ptt, .set_freq = gp2000_set_freq, .get_freq = gp2000_get_freq, .set_mode = gp2000_set_mode, .get_mode = gp2000_get_mode, .set_level = gp2000_set_level, .get_level = gp2000_get_level, //.set_func = gp2000_set_func, //.get_func = gp2000_get_func, .get_info = gp2000_get_info, #if 0 /* TODO */ .rig_open = gp2000_rig_open, .set_channel = gp2000_set_channel, .get_channel = gp2000_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/rs/xk852.h0000644000175000017500000000607314752216205012334 00000000000000/* * Hamlib R&S backend for XK852 - main header * Reused from rs.c * Based on xk2000.h * Copyright (c) 2024 by Marc Fontaine DM1MF * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _XK852_H #define _XK852_H 1 #undef BACKEND_VER #define BACKEND_VER "20240921" #include typedef enum { XK852_CMD_ADDRESS = 'A', XK852_CMD_BFO = 'B', XK852_CMD_FREQUENCY = 'F', XK852_CMD_LINE = 'G', XK852_CMD_FSK_STOP = 'H', XK852_CMD_MODE = 'I', XK852_CMD_EXTERN = 'J', XK852_CMD_CHANNEL = 'K', XK852_CMD_NOISE_BLANK = 'N', XK852_CMD_STATUS = 'O', XK852_CMD_OP_MODE = 'S', XK852_CMD_SELFTEST = 'T', XK852_CMD_VOICE = 'V', XK852_CMD_PTT = 'X', XK852_CMD_TUNE = 'Y', XK852_CMD_FSK_POLARITY = 'Z' } xk852_cmd; typedef enum { XK852_LINE_OFF = 1, XK852_LINE_ON = 1 } xk852_line; typedef enum { XK852_FSK_STOP_OFF = 0, XK852_FSK_STOP_ON = 1 } xk852_fsk_stop; typedef enum { XK852_MODE_AME = 1, XK852_MODE_USB = 2, XK852_MODE_LSB = 3, XK852_MODE_CW = 5, XK852_MODE_ISB = 6, XK852_MODE_FSK_LP = 7, XK852_MODE_FSK_NP = 8, XK852_MODE_FSK_HP = 9 } xk852_mode; typedef enum { XK852_OP_MODE_OFF = 0, XK852_OP_MODE_RX = 1, XK852_OP_MODE_TX_LOW = 2, XK852_OP_MODE_TX_MID = 3, XK852_OP_MODE_TX_FULL = 4, } xk852_op_mode; // TODO: check Noiseblank command does not work ! typedef enum { XK852_NOISE_BLANK_OFF = 0, XK852_NOISE_BLANK_ON = 1, } xk852_noise_blank; typedef struct { int freq; xk852_mode mode; xk852_noise_blank noise_blank; xk852_op_mode op_mode; } xk852_state; int xk852_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int xk852_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int xk852_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int xk852_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int xk852_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int xk852_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int xk852_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int xk852_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int xk852_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int xk852_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int xk852_reset(RIG *rig, reset_t reset); //const char * xk852_get_info(RIG *rig); extern struct rig_caps xk852_caps; #endif /* XK852_H */ hamlib-4.6.2/rigs/rs/gp2000.h0000644000175000017500000000347514752216205012366 00000000000000/* * Hamlib R&S backend for XK2000 - main header * Reused from rs.c * Copyright (c) 2018 by Michael Black W9MDB * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _XK2000_H #define _XK2000_H 1 #undef BACKEND_VER #define BACKEND_VER "20210901" #include int gp2000_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int gp2000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int gp2000_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int gp2000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int gp2000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int gp2000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int gp2000_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int gp2000_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int gp2000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int gp2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int gp2000_reset(RIG *rig, reset_t reset); const char * gp2000_get_info(RIG *rig); extern struct rig_caps xk2100_caps; #endif /* XK2000_H */ hamlib-4.6.2/rigs/rs/eb200.c0000644000175000017500000001131114752216205012245 00000000000000/* * Hamlib R&S backend - EB200 description * Copyright (c) 2009-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "rs.h" /* TODO: PULSE and IQ ? */ #define EB200_MODES (RIG_MODE_SSB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define EB200_FUNC (RIG_FUNC_SQL|RIG_FUNC_AFC|RIG_FUNC_LOCK) #define EB200_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC|\ RIG_LEVEL_RF|RIG_LEVEL_AF|RIG_LEVEL_STRENGTH) #define EB200_PARM_ALL (RIG_PARM_NONE) #define EB200_VFO (RIG_VFO_A) #define EB200_VFO_OPS (RIG_OP_NONE) #define EB200_ANTS (RIG_ANT_1) #define EB200_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .funcs = EB200_FUNC, \ .levels = RIG_LEVEL_SET(EB200_LEVEL_ALL), \ .channel_desc=1, \ .flags = RIG_CHFLAG_SKIP, \ } /* * EB200 rig capabilities. * * Needs option ESMBR2 for computer operation RS-232C * * TODO * - set/get_channels * - get_dcd * - set_ant */ struct rig_caps eb200_caps = { RIG_MODEL(RIG_MODEL_EB200), .model_name = "EB200", .mfg_name = "Rohde&Schwarz", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, /* 7E2 */ .serial_rate_max = 115200, /* 7E1, RTS/CTS */ .serial_data_bits = 7, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_EVEN, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = EB200_FUNC, .has_set_func = EB200_FUNC, .has_get_level = EB200_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(EB200_LEVEL_ALL), .has_get_parm = EB200_PARM_ALL, .has_set_parm = RIG_PARM_SET(EB200_PARM_ALL), .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END }, .attenuator = { 32, RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 7, /* FIXME */ .vfo_ops = EB200_VFO_OPS, .chan_list = { { 0, 999, RIG_MTYPE_MEM, EB200_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(10), GHz(3), EB200_MODES, -1, -1, EB200_VFO, EB200_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(10), GHz(3), EB200_MODES, -1, -1, EB200_VFO, EB200_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { {EB200_MODES, 1}, {EB200_MODES, 10}, {EB200_MODES, 100}, {EB200_MODES, 1000}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_WFM, kHz(150)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(15)}, {EB200_MODES, kHz(2.4)}, {EB200_MODES, kHz(1.5)}, {EB200_MODES, Hz(150)}, {EB200_MODES, Hz(300)}, {EB200_MODES, Hz(600)}, {EB200_MODES, kHz(6)}, {EB200_MODES, kHz(9)}, {EB200_MODES, kHz(15)}, {EB200_MODES, kHz(30)}, {EB200_MODES, kHz(50)}, {EB200_MODES, kHz(120)}, RIG_FLT_END, }, .priv = NULL, .set_freq = rs_set_freq, .get_freq = rs_get_freq, .set_mode = rs_set_mode, .get_mode = rs_get_mode, .set_level = rs_set_level, .get_level = rs_get_level, .set_func = rs_set_func, .get_func = rs_get_func, .get_info = rs_get_info, .reset = rs_reset, #if 0 /* TODO */ .rig_open = rs_rig_open, .set_channel = rs_set_channel, .get_channel = rs_get_channel, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/yaesu/0000755000175000017500000000000014752216244012061 500000000000000hamlib-4.6.2/rigs/yaesu/ft990v12.c0000644000175000017500000030637614752216205013365 00000000000000/* * hamlib - (C) Stephane Fillod 2002-2010 (fillods at users.sourceforge.net) * (C) Terry Embry 2009 * * ft990.c - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* THIS FILE WAS MODIFIED IN DECEMBER 2016 TO REMOVE ANY REFERENCE TO THE FT-1000/D. SEPARATE ft1000d.c and .h FILES * WERE CREATED TO HANDLE FT-1000/D COMMANDS AND PROVIDE THE FULL RANGE OF FUNCTIONS AVAILABLE ON THE FT-1000/D * TO MAXIMISE COMPATIBILITY WITH RIGCTL. * G0OAN */ /* MODIFIED VERSION for FT-990 with ROM v1.2 : June 2022 * The standard version was written for FT-990 with ROM v1.3 and as the CAT spec was different to ROM v1.2 CAT * would not work with the older ROM. This version enables ROM v1.2 to work although it is necessary to accept * that frequent polling functionality is not feasible with this older ROM. With ROM v1.2 polling fetches 1492 * bytes which at 4800 Baud takes about 3.8 seconds during which the FT-990 has a CAT blackout. The longest poll * interval available in WSJT-X is 99 seconds. * Collaboration between M0EZP David Brewerton and K1MMI Edmund Hajjar */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft990v12.h" // FT990 native commands enum ft990v12_native_cmd_e { FT990_NATIVE_SPLIT_OFF = 0, FT990_NATIVE_SPLIT_ON, FT990_NATIVE_RECALL_MEM, FT990_NATIVE_VFO_TO_MEM, FT990_NATIVE_LOCK_OFF, FT990_NATIVE_LOCK_ON, FT990_NATIVE_VFO_A, FT990_NATIVE_VFO_B, FT990_NATIVE_MEM_TO_VFO, FT990_NATIVE_VFO_STEP_UP, FT990_NATIVE_VFO_STEP_UP_FAST, FT990_NATIVE_VFO_STEP_DOWN, FT990_NATIVE_VFO_STEP_DOWN_FAST, FT990_NATIVE_RX_CLARIFIER_OFF, FT990_NATIVE_RX_CLARIFIER_ON, FT990_NATIVE_TX_CLARIFIER_OFF, FT990_NATIVE_TX_CLARIFIER_ON, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET, FT990_NATIVE_CLARIFIER_OPS, FT990_NATIVE_FREQ_SET, FT990_NATIVE_MODE_SET_LSB, FT990_NATIVE_MODE_SET_USB, FT990_NATIVE_MODE_SET_CW_W, FT990_NATIVE_MODE_SET_CW_N, FT990_NATIVE_MODE_SET_AM_W, FT990_NATIVE_MODE_SET_AM_N, FT990_NATIVE_MODE_SET_FM, FT990_NATIVE_MODE_SET_RTTY_LSB, FT990_NATIVE_MODE_SET_RTTY_USB, FT990_NATIVE_MODE_SET_PKT_LSB, FT990_NATIVE_MODE_SET_PKT_FM, FT990_NATIVE_PACING, FT990_NATIVE_PTT_OFF, FT990_NATIVE_PTT_ON, FT990_NATIVE_UPDATE_ALL_DATA, FT990_NATIVE_UPDATE_MEM_CHNL, FT990_NATIVE_UPDATE_OP_DATA, FT990_NATIVE_UPDATE_VFO_DATA, FT990_NATIVE_UPDATE_MEM_CHNL_DATA, FT990_NATIVE_TUNER_OFF, FT990_NATIVE_TUNER_ON, FT990_NATIVE_TUNER_START, FT990_NATIVE_RPTR_SHIFT_NONE, FT990_NATIVE_RPTR_SHIFT_MINUS, FT990_NATIVE_RPTR_SHIFT_PLUS, FT990_NATIVE_VFO_TO_VFO, FT990_NATIVE_BANDWIDTH, FT990_NATIVE_OP_FREQ_STEP_UP, FT990_NATIVE_OP_FREQ_STEP_DOWN, FT990_NATIVE_READ_METER, FT990_NATIVE_DIM_LEVEL, FT990_NATIVE_RPTR_OFFSET, FT990_NATIVE_READ_FLAGS, FT990_NATIVE_SIZE }; /* HAMLIB API implementation */ static int ft990v12_init(RIG *rig); static int ft990v12_cleanup(RIG *rig); static int ft990v12_open(RIG *rig); static int ft990v12_close(RIG *rig); static int ft990v12_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft990v12_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft990v12_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft990v12_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft990v12_set_vfo(RIG *rig, vfo_t vfo); static int ft990v12_get_vfo(RIG *rig, vfo_t *vfo); static int ft990v12_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft990v12_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft990v12_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft990v12_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); static int ft990v12_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft990v12_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft990v12_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft990v12_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft990v12_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft990v12_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft990v12_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft990v12_set_parm(RIG *rig, setting_t parm, value_t val); static int ft990v12_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft990v12_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft990v12_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft990v12_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft990v12_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft990v12_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft990v12_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ft990v12_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); /* Private helper function prototypes */ static int ft990v12_get_update_data(RIG *rig, unsigned char ci, unsigned short ch); static int ft990v12_send_static_cmd(RIG *rig, unsigned char ci); static int ft990v12_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft990v12_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft990v12_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); static const yaesu_cmd_set_t ncmd[] = { /* ci */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 00 00 Split (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* 01 01 Split (On) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* 02 02 Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* 03 03 Memory Operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* 04 04 Lock (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* 05 05 Lock (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* 06 06 Select VFO (A) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* 07 07 Select VFO (B) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* 08 08 Copy Memory Data to VFO A */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* 09 09 OP Freq Up 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x07 } }, /* 10 0a OP Freq Up 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* 11 0b OP Freq Down 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x08 } }, /* 12 0c OP Freq Down 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* 13 0d RX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* 14 0e RX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* 15 0f TX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* 16 10 TX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0xff, 0x09 } }, /* 17 11 Clear Clarifier Offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* 18 12 Clarifier */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* 19 13 Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* 20 14 OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* 21 15 OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* 22 16 OP Mode Set CW 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* 23 17 OP Mode Set CW 500Hz */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* 24 18 OP Mode Set AM 6KHz */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* 25 19 OP Mode Set AM 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* 26 1a OP Mode Set FM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* 27 1b OP Mode Set RTTY LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* 28 1c OP Mode Set RTTY USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* 29 1d OP Mode Set PKT LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* 30 1e OP Mode Set PKT FM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* 31 1f Pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* 32 20 PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* 33 21 PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* 34 22 Update All Data (1492 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* 35 23 Update Memory Ch Number M0EZP: 2ndByte was 0x01 */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* 36 24 Update Op Data M0EZP: 2ndByte was 0x02 */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* 37 25 Update VFO Data M0EZP: 2ndByte was 0x03 */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* 38 26 Update Memory Ch Data M0EZP: 2ndByte was 0x04 */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* 39 27 Tuner (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* 40 28 Tuner (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* 41 29 Tuner (Start) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* 42 2a Repeater Mode (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* 43 2b Repeater Mode (Minus) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* 44 2c Repeater Mode (Plus) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* 45 2d Copy displayed VFO (A=B || B=A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8C } }, /* 46 2e Select Bandwidth */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8E } }, /* 47 2f Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8E } }, /* 48 30 Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* 49 31 Read Meter */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf8 } }, /* 50 32 DIM Level */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* 51 33 Set Offset for Repeater Shift */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* 52 34 Read Status Flags */ }; /* * Private data */ // M0EZP: status 0=uni first call, 1=uni after first call int ft990uni_get_freq_state = 0; struct ft990v12_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of CAT cmd */ ft990v12_update_data_t update_data; /* returned data */ }; /* * ft990 rigs capabilities. */ #define FT990_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } // Old FT990 ROM has to read all 1492 to get frequency // So for this model we just use the cache to read freq struct rig_caps ft990uni_caps = { RIG_MODEL(RIG_MODEL_FT990UNI), .model_name = "FT-990 Old Rom", .mfg_name = "Yaesu", .version = "20220628.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT990_WRITE_DELAY, .post_write_delay = FT990_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | \ RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_BACKLIGHT, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 13.0f}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 90, RIG_MTYPE_MEM, FT990_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(1, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(2, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT990_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT990_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT990_AM_RX_MODES, Hz(100)}, /* Normal */ {FT990_AM_RX_MODES, kHz(1)}, /* Fast */ {FT990_FM_RX_MODES, Hz(100)}, /* Normal */ {FT990_FM_RX_MODES, kHz(1)}, /* Fast */ {FT990_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT990_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft990v12_init, .rig_cleanup = ft990v12_cleanup, .rig_open = ft990v12_open, /* port opened */ .rig_close = ft990v12_close, /* port closed */ .set_freq = ft990v12_set_freq, .get_freq = ft990v12_get_freq, .set_mode = ft990v12_set_mode, .get_mode = ft990v12_get_mode, .set_vfo = ft990v12_set_vfo, .get_vfo = ft990v12_get_vfo, .set_ptt = ft990v12_set_ptt, .get_ptt = ft990v12_get_ptt, .set_rptr_shift = ft990v12_set_rptr_shift, .get_rptr_shift = ft990v12_get_rptr_shift, .set_rptr_offs = ft990v12_set_rptr_offs, .set_split_vfo = ft990v12_set_split_vfo, .get_split_vfo = ft990v12_get_split_vfo, .set_rit = ft990v12_set_rit, .get_rit = ft990v12_get_rit, .set_xit = ft990v12_set_xit, .get_xit = ft990v12_get_xit, .set_func = ft990v12_set_func, .get_func = ft990v12_get_func, .set_parm = ft990v12_set_parm, .get_level = ft990v12_get_level, .set_mem = ft990v12_set_mem, .get_mem = ft990v12_get_mem, .vfo_op = ft990v12_vfo_op, .set_channel = ft990v12_set_channel, .get_channel = ft990v12_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init */ int ft990v12_init(RIG *rig) { struct ft990v12_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft990v12_priv_data *) calloc(1, sizeof(struct ft990v12_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; // Set default pacing value priv->pacing = FT990_PACING_DEFAULT_VALUE; // Set operating vfo mode to current VFO priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /* * rig_cleanup */ int ft990v12_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open */ int ft990v12_open(RIG *rig) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } // Get current rig settings and status // err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); // M0EZP read flags instead of update err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close */ int ft990v12_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft990v12_priv_data *priv; int err; vfo_t vfo_save; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); // Frequency range sanity check if (freq < 100000 || freq > 30000000) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; vfo_save = priv->current_vfo; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != vfo_save) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990v12_send_dial_freq(rig, FT990_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } if (vfo != vfo_save) { err = ft990v12_set_vfo(rig, vfo_save); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft990v12_priv_data *priv; unsigned char *p; freq_t f; int err; int ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: ft990uni_get_freq_state = 0x%02x\n", __func__, ft990uni_get_freq_state); if (ft990uni_get_freq_state < 2) { // M0EZP: UNI first call needs UPDATE_ALL ft990uni_get_freq_state = ft990uni_get_freq_state + 1; if (!rig) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = priv->update_data.vfoa.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = priv->update_data.vfob.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = priv->update_data.current_front.basefreq; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } ci = FT990_NATIVE_UPDATE_ALL_DATA; /* M0EZP: inserted to override CI */ err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: p0=0x%02x p1=0x%02x p2=0x%02x\n", __func__, p[0], p[1], p[2]); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); // Frequency sanity check if (f < 100000 || f > 30000000) { return -RIG_EINVAL; } *freq = f; return RIG_OK; } else { // M0EZP: Uni use cache // *freq = vfo == RIG_VFO_A ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB; return (RIG_OK); } } /* * rig_set_ptt* * * Control PTT for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft990v12_priv_data *priv; int err; unsigned char ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (ptt) { case RIG_PTT_ON: ci = FT990_NATIVE_PTT_ON; break; case RIG_PTT_OFF: ci = FT990_NATIVE_PTT_OFF; break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt* * * Get PTT line status * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * ptt * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the PTT status * is independent from the VFO selection. */ int ft990v12_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } *ptt = ((priv->update_data.flag1 & FT990_SF_XMIT) != 0); rig_debug(RIG_DEBUG_TRACE, "%s: set ptt = 0x%02x\n", __func__, *ptt); return RIG_OK; } /* * rig_set_rptr_shift* * * Set repeater shift for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | - = negative repeater shift, * | | + = positive repeater shift, * | | any other character = simplex (is this a bug?) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be set when in FM mode. */ int ft990v12_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct ft990v12_priv_data *priv; unsigned char ci; char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rptr_shift = 0x%02x\n", __func__, rptr_shift); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Construct update query switch (vfo) { case RIG_VFO_A: p = (char *) &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (char *) &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: p = (char *) &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, *p); // Shift mode settings are only valid in FM mode if ((*p & FT990_MODE_FM) == 0) { return -RIG_EINVAL; } // Construct repeater shift command switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: ci = FT990_NATIVE_RPTR_SHIFT_NONE; break; case RIG_RPT_SHIFT_MINUS: ci = FT990_NATIVE_RPTR_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: ci = FT990_NATIVE_RPTR_SHIFT_PLUS; break; default: return -RIG_EINVAL; } // Set repeater shift err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rptr_shift* * * Get repeater shift setting for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * shift * | output | 0 = simplex * | | 1 = negative repeater shift * | | 2 = positive repeater shift * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be obtained when in FM mode. */ int ft990v12_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct ft990v12_priv_data *priv; ft990v12_op_data_t *p; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, p->mode); // Shift mode settings are only valid in FM mode if (p->mode & FT990_MODE_FM) { *rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } else { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set rptr shift = 0x%02x\n", __func__, *rptr_shift); return RIG_OK; } /* * rig_set_rptr_offs* * * Set repeater frequency offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * off | input | 0 - 199999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * repeater frequency offset is independent from the VFO selection. */ int ft990v12_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char bcd[(int) FT990_BCD_RPTR_OFFSET / 2]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed offs = %d\n", __func__, (int)offs); // Check for valid offset if (offs < 0 || offs > 199999) { return -RIG_EINVAL; } to_bcd(bcd, offs / 10, FT990_BCD_RPTR_OFFSET); rig_debug(RIG_DEBUG_TRACE, "%s: set bcd[0] = 0x%02x, bcd[1] = 0x%02x, bcd[2] = 0x%02x\n", __func__, bcd[0], bcd[1], bcd[2]); err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_RPTR_OFFSET, 0, bcd[2], bcd[1], bcd[0]); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ int ft990v12_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft990v12_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo = priv->current.vfo = 0x%02x\n", __func__, vfo); } if (tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = priv->current.vfo = 0x%02x\n", __func__, tx_vfo); } // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if (vfo == tx_vfo || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } // Set TX VFO first if RIG_VFO_MEM selected for RX VFO if (vfo == RIG_VFO_MEM) { err = ft990v12_set_vfo(rig, tx_vfo); if (err != RIG_OK) { return err; } } // Set RX VFO err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } switch (split) { case RIG_SPLIT_ON: ci = FT990_NATIVE_SPLIT_ON; break; case RIG_SPLIT_OFF: ci = FT990_NATIVE_SPLIT_OFF; break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored in order to * preserve the current split vfo system settings. */ int ft990v12_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Read status flags err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } // Get split mode status *split = priv->update_data.flag1 & FT990_SF_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, *split); // Get transmit vfo switch (priv->current_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: if (priv->update_data.flag1 & FT990_SF_VFOB) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx_vfo = 0x%02x\n", __func__, *tx_vfo); return RIG_OK; } /* * rig_set_rit* * * Set receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * rit = 0 && xit enabled -> disable rit * rit = 0 && xit disabled -> disable rit and set frequency = 0 */ int ft990v12_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)rit); // Check for valid clarifier offset frequency if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // If rit = 0 disable RX clarifier if (rit == 0) { err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_TX_EN) == 0) { err = ft990v12_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } // Disable RX Clarifier err = ft990v12_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable RX Clarifier err = ft990v12_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set RX clarifier offset err = ft990v12_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_rit* * * Get receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft990v12_priv_data *priv; unsigned char ci; ft990v12_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990v12_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } // Get update for selected VFO/MEM err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_RX_EN) { *rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *rit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: rit freq = %li Hz\n", __func__, *rit); return RIG_OK; } /* * rig_set_xit* * * Set transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * xit = 0 && rit enabled -> disable xit * xit = 0 && rit disabled -> disable xit and set frequency = 0 */ int ft990v12_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)xit); if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Disable TX clarifier and return if xit = 0 if (xit == 0) { err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_RX_EN) == 0) { err = ft990v12_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } err = ft990v12_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable TX Clarifier err = ft990v12_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set TX clarifier offset err = ft990v12_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_xit* * * Get transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct ft990v12_priv_data *priv; unsigned char ci; ft990v12_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990v12_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990v12_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_TX_EN) { *xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *xit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, *xit); return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER * status | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig functions are vfo independent. */ int ft990v12_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_LOCK: if (status) { ci = FT990_NATIVE_LOCK_ON; } else { ci = FT990_NATIVE_LOCK_OFF; } break; case RIG_FUNC_TUNER: if (status) { ci = FT990_NATIVE_TUNER_ON; } else { ci = FT990_NATIVE_TUNER_OFF; } break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get status of a rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER, MON * status * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig function are vfo independent. */ int ft990v12_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } switch (func) { case RIG_FUNC_LOCK: *status = ((priv->update_data.flag2 & FT990_SF_LOCKED) != 0); break; case RIG_FUNC_TUNER: *status = ((priv->update_data.flag3 & FT990_SF_TUNER_ON) != 0); break; case RIG_FUNC_MON: *status = ((priv->update_data.flag3 & FT990_SF_XMIT_MON) != 0); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_parm* * * Set rig parameters that are not VFO specific * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * parm | input | BACKLIGHT * val | input | 0.0..1.0 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: */ int ft990v12_set_parm(RIG *rig, setting_t parm, value_t val) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed parm = %s\n", __func__, rig_strparm(parm)); rig_debug(RIG_DEBUG_TRACE, "%s: passed val = %f\n", __func__, val.f); switch (parm) { case RIG_PARM_BACKLIGHT: err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_DIM_LEVEL, (unsigned char)(0x0d * val.f), 0, 0, 0); break; default: return -RIG_EINVAL; } if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_mode* * * Set operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width | input | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft990v12_priv_data *priv; unsigned char bw; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (mode) { case RIG_MODE_AM: if (width == rig_passband_narrow(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_N; } else if (width == rig_passband_normal(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT990_NATIVE_MODE_SET_CW_W; break; case RIG_MODE_USB: ci = FT990_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: ci = FT990_NATIVE_MODE_SET_LSB; break; case RIG_MODE_RTTY: ci = FT990_NATIVE_MODE_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT990_NATIVE_MODE_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT990_NATIVE_MODE_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT990_NATIVE_MODE_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT990_NATIVE_MODE_SET_PKT_FM; break; default: return -RIG_EINVAL; } err = ft990v12_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT990_NATIVE_MODE_SET_AM_N || ci == FT990_NATIVE_MODE_SET_AM_W || ci == FT990_NATIVE_MODE_SET_FM || ci == FT990_NATIVE_MODE_SET_PKT_FM) { return RIG_OK; } if (width <= 250) { bw = FT990_BW_F250; } else if (width <= 500) { bw = FT990_BW_F500; } else if (width <= 2000) { bw = FT990_BW_F2000; } else { bw = FT990_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_mode* * * Get operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width * | output | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft990v12_priv_data *priv; unsigned char *p; unsigned char *fl; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_B: p = &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfob.filter; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; fl = &priv->update_data.current_front.filter; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990v12_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: fl = 0x%02x\n", __func__, *fl); rig_debug(RIG_DEBUG_TRACE, "%s: current mode = 0x%02x\n", __func__, *p); switch (*p) { case FT990_MODE_LSB: *mode = RIG_MODE_LSB; break; case FT990_MODE_USB: *mode = RIG_MODE_USB; break; case FT990_MODE_CW: *mode = RIG_MODE_CW; break; case FT990_MODE_AM: *mode = RIG_MODE_AM; break; case FT990_MODE_FM: *mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_RTTYR; } else { *mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_PKTFM; } else { *mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get mode = %s\n", __func__, rig_strrmode(*mode)); // The FT990 firmware appears to have a bug since the // AM bandwidth for 2400Hz and 6000Hz are interchanged. switch (*fl & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 8000; } else if (*mode == RIG_MODE_AM) // <- FT990 firmware bug? { *width = 6000; } else { *width = 2400; } break; case FT990_BW_F2000: *width = 2000; break; case FT990_BW_F500: *width = 500; break; case FT990_BW_F250: *width = 250; break; case FT990_BW_F6000: *width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get width = %li Hz\n", __func__, *width); return RIG_OK; } /* * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_set_vfo(RIG *rig, vfo_t vfo) { struct ft990v12_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_A; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_B; break; case RIG_VFO_MEM: ci = FT990_NATIVE_RECALL_MEM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set ci = %i\n", __func__, ci); if (vfo == RIG_VFO_MEM) { err = ft990v12_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->update_data.channelnumber + 1); } else { err = ft990v12_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } priv->current_vfo = vfo; return RIG_OK; } /* * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * The result is stored in the priv->current_vfo data structure * for later retrieval. */ int ft990v12_get_vfo(RIG *rig, vfo_t *vfo) { struct ft990v12_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990v12_priv_data *)STATE(rig)->priv; /* Get flags for VFO status err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } */ if (priv->update_data.flag2 & FT990_SF_MEM || priv->update_data.flag2 & FT990_SF_MTUNE) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.flag1 & FT990_SF_VFOB) { priv->current_vfo = RIG_VFO_B; } else { priv->current_vfo = RIG_VFO_A; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_2 = 0x%02x\n", __func__, priv->update_data.flag2); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, priv->current_vfo); *vfo = priv->current_vfo; return RIG_OK; } /* * rig_get_level * * This function will read the meter level.The data * is processed depending upon selection of the level * parameter. The following are the currently supported * levels and returned value range: * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * level | input | STRENGTH, ALC, COMP, RFPOWER, SWR * value * | output | see table below * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * ---------------------------------------------------------- * level | Description | Returned Value | Units | * ---------------------------------------------------------- * STRENGTH | Signal Strength | -54 .. +60 | db | * COMP | Compression | 0.0 .. 1.0 | %/100 | * RFPOWER | RF Power Output | 0.0 .. 1.0 | %/100 | * SWR | Standing Wave Ratio | 0.0 .. 1.0 | %/100 | * ---------------------------------------------------------- * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value) { struct ft990v12_priv_data *priv; unsigned char mdata[YAESU_CMD_LENGTH]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed level %s\n", __func__, rig_strlevel(level)); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990v12_send_static_cmd(rig, FT990_NATIVE_READ_METER); if (err != RIG_OK) { return err; } err = read_block(RIGPORT(rig), mdata, FT990_READ_METER_LENGTH); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: meter data %d\n", __func__, mdata[0]); switch (level) { case RIG_LEVEL_STRENGTH: value->i = mdata[0] / 2.246 - 54; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %d\n", __func__, value->i); break; case RIG_LEVEL_ALC: case RIG_LEVEL_COMP: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_SWR: value->f = (float) mdata[0] / 255; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %f\n", __func__, value->f); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op* * * Perform vfo operations * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | VFOA, VFOB, MEM * op | input | CPY = copy from VFO to VFO * | | FROM_VFO = copy from VFO to MEM * | | TO_VFO = copy from MEM to VFO * | | UP = step dial frequency up * | | DOWN = step dial frequency down * | | TUNE = start antenna tuner * | | TOGGLE = toggle between VFOA and VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990v12_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ft990v12_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed op %s\n", __func__, rig_strvfop(op)); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990v12_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (op) { case RIG_OP_CPY: ci = FT990_NATIVE_VFO_TO_VFO; break; case RIG_OP_FROM_VFO: ci = FT990_NATIVE_VFO_TO_MEM; break; case RIG_OP_TO_VFO: ci = FT990_NATIVE_MEM_TO_VFO; break; case RIG_OP_UP: ci = FT990_NATIVE_OP_FREQ_STEP_UP; break; case RIG_OP_DOWN: ci = FT990_NATIVE_OP_FREQ_STEP_DOWN; break; case RIG_OP_TUNE: ci = FT990_NATIVE_TUNER_START; break; case RIG_OP_TOGGLE: switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_B; vfo = RIG_VFO_B; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_A; vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (op == RIG_OP_TO_VFO || op == RIG_OP_FROM_VFO) err = ft990v12_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); else { err = ft990v12_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } if (op == RIG_OP_TOGGLE) { priv->current_vfo = vfo; } return RIG_OK; } /* * rig_set_mem* * * Set main vfo to selected memory channel number * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch | input | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the channel selection is vfo independent. */ int ft990v12_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ch = %i\n", __func__, ch); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; // Check for valid channel number if (ch < 1 || ch > 90) { return -RIG_EINVAL; } // Recall selected memory channel err = ft990v12_send_dynamic_cmd(rig, FT990_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = RIG_VFO_MEM; priv->update_data.channelnumber = ch - 1; return RIG_OK; } /* * rig_get_mem* * * Get memory channel number used by main vfo * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch * | output | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since * the channel selection is vfo independent. */ int ft990v12_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: channel number %i\n", __func__, priv->update_data.channelnumber + 1); *ch = priv->update_data.channelnumber + 1; // Check for valid channel number if (*ch < 1 || *ch > 90) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_channel* * * Set memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | channel attribute data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure */ int ft990v12_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return -RIG_ENIMPL; } /* * rig_get_channel* * * Get memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | (chan->vfo) currVFO, VFOA, VFOB, MEM * | | (chan->channel_num) 0 - 90 * chan * | output | channel attributes data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing a memory channel number of 0 returns information on * the current channel or channel last in use. * * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ int ft990v12_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ft990v12_priv_data *priv; ft990v12_op_data_t *p; char ci; int err; channel_t _chan; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->vfo = %s\n", __func__, rig_strvfo(chan->vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->channel_num = %i\n", __func__, chan->channel_num); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (chan->channel_num < 0 || chan->channel_num > 90) { return -RIG_EINVAL; } /* * Get a clean slate so we don't have to assign value to * variables that are not relevant to this equipment */ _chan.channel_num = chan->channel_num; _chan.vfo = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = _chan.channel_num; chan->vfo = _chan.vfo; if (chan->channel_num == 0) { switch (chan->vfo) { // Current or last selected memory channel case RIG_VFO_MEM: err = ft990v12_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } chan->channel_num = priv->update_data.channelnumber + 1; p = (ft990v12_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; break; case RIG_VFO_A: p = (ft990v12_op_data_t *) &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (ft990v12_op_data_t *) &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_CURR: p = (ft990v12_op_data_t *) &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } } else { p = (ft990v12_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; chan->vfo = RIG_VFO_MEM; } /* * Get data for selected VFO/MEM */ err = ft990v12_get_update_data(rig, ci, chan->channel_num); if (err != RIG_OK) { return err; } // Blanked memory, nothing to report if (p->bpf & FT990_EMPTY_MEM) { return RIG_OK; } /* * Get RX frequency */ chan->freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_RTTYR; } else { chan->mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_PKTFM; } else { chan->mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = 0x%02x\n", __func__, p->mode); rig_debug(RIG_DEBUG_TRACE, "%s: filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->width = 8000; } else if (chan->mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->width = 6000; } else { chan->width = 2400; } break; case FT990_BW_F2000: chan->width = 2000; break; case FT990_BW_F500: chan->width = 500; break; case FT990_BW_F250: chan->width = 250; break; case FT990_BW_F6000: chan->width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } err = ft990v12_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, priv->update_data.flag1); /* * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ if (chan->vfo & RIG_VFO_CURR) { chan->split = (priv->update_data.flag1 & FT990_SF_SPLIT); if (priv->update_data.flag1 & FT990_SF_XMIT_MON) { chan->funcs |= RIG_FUNC_MON; } if (priv->update_data.flag1 & FT990_SF_TUNER_ON) { chan->funcs |= RIG_FUNC_TUNER; } if (priv->update_data.flag1 & FT990_SF_FAST) { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 1000; } else { chan->tuning_step = 100; } } else { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 100; } else { chan->tuning_step = 10; } } } /* * Get RIT frequencies */ if (p->status & FT990_CLAR_RX_EN) { chan->rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } if (chan->split & RIG_SPLIT_ON) { // Get data for the transmit VFO p = (ft990v12_op_data_t *) &priv->update_data.current_front; /* M0EZP: was current_rear */ /* FT1000D * if (RIG_MODEL_FT1000D == rig->caps->rig_model) * p = (ft990v12_op_data_t *) &priv->update_data.vfob; * chan->tx_freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + * p->basefreq[2]) * 10; * * THIS SECTION WAS REMOVED IN DECEMBER 2016. SEE SEPARATE ft1000d.c and .h FILES */ /* Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->tx_mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->tx_mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->tx_mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->tx_mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->tx_mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_RTTYR; } else { chan->tx_mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_PKTFM; } else { chan->tx_mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx mode = %s\n", __func__, rig_strrmode(chan->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: tx filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->tx_mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->tx_width = 8000; } else if (chan->tx_mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->tx_width = 6000; } else { chan->tx_width = 2400; } break; case FT990_BW_F2000: chan->tx_width = 2000; break; case FT990_BW_F500: chan->tx_width = 500; break; case FT990_BW_F250: chan->tx_width = 250; break; case FT990_BW_F6000: chan->tx_width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } if (priv->update_data.flag1 & FT990_SF_VFOB) { if (chan->tx_vfo & (RIG_VFO_A | RIG_VFO_MEM)) { chan->tx_vfo = RIG_VFO_B; } else if (chan->vfo & RIG_VFO_MEM) { chan->tx_vfo = RIG_VFO_A; } else { chan->tx_vfo = RIG_VFO_MEM; } } else { if (chan->vfo & RIG_VFO_A) { chan->tx_vfo = RIG_VFO_MEM; } else { chan->tx_vfo = RIG_VFO_A; } } /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } else { /* * RX/TX frequency, mode, bandwidth and vfo are identical in simplex mode */ chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->tx_vfo = chan->vfo; /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, p->status); /* * Repeater shift only possible if transmit mode is FM */ if (chan->tx_mode & RIG_MODE_FM) { chan->rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } /* * Check for skip channel for memory channels */ if (chan->vfo & RIG_VFO_MEM) { chan->flags |= RIG_CHFLAG_SKIP; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 990 has several ways to * get data and several ways to return it. * * Need to use this when doing ft990_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_get_update_data(RIG *rig, unsigned char ci, unsigned short ch) { struct ft990v12_priv_data *priv; int n; int err = -RIG_EINTERNAL; int rl; unsigned char temp[5]; unsigned char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed ch 0x%02x\n", __func__, ch); if (!rig) { return -RIG_EINVAL; } n = 0; // K1MMI: Initialise as the only time n will be updated is for the FT990_NATIVE_ALL_DATA AND FT990_READ_FLAGS priv = (struct ft990v12_priv_data *)STATE(rig)->priv; switch (ci) { case FT990_NATIVE_UPDATE_ALL_DATA: case FT990_NATIVE_UPDATE_MEM_CHNL: case FT990_NATIVE_UPDATE_OP_DATA: case FT990_NATIVE_UPDATE_VFO_DATA: case FT990_NATIVE_UPDATE_MEM_CHNL_DATA: if (ft990uni_get_freq_state < 2) { // if (ci == FT990_NATIVE_UPDATE_MEM_CHNL_DATA) // P4 = 0x01 to 0x5a for channel 1 - 90 { /* err = ft990v12_send_dynamic_cmd(rig, ci, 4, 0, 0, ch); M0EZP: dont send command, rely on the assignment from memory below*/ } else { // err = RIG_OK; K1MMI err = ft990v12_send_static_cmd(rig, ci); // K1MMI: only send for ALL DATA 1492 bytes or READ FLAGS 5 bytes } if (err != RIG_OK) { return err; } switch (ci) { case FT990_NATIVE_UPDATE_ALL_DATA: rl = FT990_ALL_DATA_LENGTH; // K1MMI: prepare to receive 1492 bytes back p = (unsigned char *) &priv->update_data; // K1MMI: This seems like 1492 will be saved here n = read_block(RIGPORT(rig), p, rl); /* M0EZP: copied here from below */ return RIG_OK; break; case FT990_NATIVE_UPDATE_MEM_CHNL: // we already have the channelnumber in the previously saved 1492 bytes p = (unsigned char *) &priv->update_data.channelnumber; rl = FT990_MEM_CHNL_LENGTH; // 1 break; case FT990_NATIVE_UPDATE_OP_DATA: // we already have the current OP and VFOA in the 1492 bytes p = (unsigned char *) &priv->update_data.current_front; rl = FT990_OP_DATA_LENGTH; // 32 break; case FT990_NATIVE_UPDATE_VFO_DATA: // we already have the VFOA and VFOB in the 1492 bytes p = (unsigned char *) &priv->update_data.vfoa; rl = FT990_VFO_DATA_LENGTH; // 32 break; case FT990_NATIVE_UPDATE_MEM_CHNL_DATA: // we already have the 16 structure for the memory channel number p = (unsigned char *) &priv->update_data.channel[ch]; rl = FT990_MEM_CHNL_DATA_LENGTH; // 16 break; default: // M0EZP: shouldn't be here! rig_debug(RIG_DEBUG_TRACE, "%s: Default clause ci 0x%02x\n", __func__, ci); // M0EZP return -RIG_EINVAL; } ft990uni_get_freq_state = ft990uni_get_freq_state + 1; if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); memcpy(&priv->update_data, p, FT990_ALL_DATA_LENGTH); return RIG_OK; } else { return RIG_OK; } case FT990_NATIVE_READ_FLAGS: rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); err = ft990v12_send_static_cmd(rig, ci); // K1MMI: only send for ALL DATA 1492 bytes if (err != RIG_OK) { return err; } p = (unsigned char *)&priv->update_data; rl = FT990_STATUS_FLAGS_LENGTH; // 5 n = read_block(RIGPORT(rig), (unsigned char *)&temp, rl); /* M0EZP: copied here from below */ if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); memcpy(&priv->update_data, p, FT990_STATUS_FLAGS_LENGTH - 2); /* just overwrite first 3 bytes */ return RIG_OK; break; default: // M0EZP: shouldn't be here! rig_debug(RIG_DEBUG_TRACE, "%s: Default clause ci 0x%02x\n", __func__, ci); // M0EZP return -RIG_EINVAL; } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[3] = p1; priv->p_cmd[2] = p2; priv->p_cmd[1] = p3; priv->p_cmd[0] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft990v12_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft990v12_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT990_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT990_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the rit frequency. * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990v12_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft990v12_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft990v12_priv_data *) STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } // Copy native command into privat command storage area memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); // Reset current clarifier offset priv->p_cmd[3] = FT990_CLAR_CLEAR; // Check and set tuning direction - up or down if (rit < 0) { priv->p_cmd[2] = FT990_CLAR_TUNE_DOWN; } else { priv->p_cmd[2] = FT990_CLAR_TUNE_UP; } // Store bcd format into privat command storage area to_bcd(priv->p_cmd, labs(rit) / 10, FT990_BCD_RIT); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft1000mp.h0000644000175000017500000000774114752216205013427 00000000000000/* * ft1000mp.h - (C) Stephane Fillod 2002 (fillods@users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-1000MP using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT1000MP_H #define _FT1000MP_H 1 #define FT1000MP_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ #define FT1000MP_STATUS_UPDATE_LENGTH 16 /* 0x10 U = 02 return size */ #define FT1000MP_PACING_INTERVAL 5 #define FT1000MP_PACING_DEFAULT_VALUE 0 #define FT1000MP_WRITE_DELAY 5 /* Delay sequential fast writes */ #define FT1000MP_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT1000MP_DEFAULT_READ_TIMEOUT 28 * ( 3 + (FT1000MP_PACING_INTERVAL * FT1000MP_PACING_DEFAULT_VALUE)) /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte rate = 1 byte in 2.2917 msec * => 28 bytes in 64 msec * * delay for 1 byte = 2.2917 + (pace_interval * 5) * * pace_interval time to read 345 bytes * ------------ ---------------------- * * 0 64 msec * 1 321 msec * 2 642 msec * 255 16.4 sec * */ /* * Internal MODES - when setting modes via cmd_mode_set() * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW 0x02 #define MODE_SET_CWR 0x03 #define MODE_SET_AM 0x04 #define MODE_SET_AMS 0x05 #define MODE_SET_FM 0x06 #define MODE_SET_FMW 0x07 /* what width is that? */ #define MODE_SET_RTTYL 0x08 #define MODE_SET_RTTYU 0x09 #define MODE_SET_PKTL 0x0a #define MODE_SET_PKTF 0x0b /* * Mode Bitmap. * When READING modes * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 #define MODE_RTTY 0x05 #define MODE_PKT 0x06 /* relevant bits: 5,6,7 */ #define MODE_MASK 0x07 /* * Status Flag Masks when reading * */ #define SF_DLOCK 0x01 #define SF_SPLITA 0x01 #define SF_SPLITB 0x02 #define SF_CLAR 0x04 #define SF_VFOAB 0x10 /* Status byte 0, bit 4, VFO A == 0, VFO B == 1 */ #define SF_VFOMR 0x10 #define SF_RXTX 0x20 #define SF_RESV 0x40 #define SF_PRI 0x80 /* * Local VFO CMD's, according to spec * */ #define FT1000MP_VFO_A 0x00 #define FT1000MP_VFO_B 0x01 /* * Some useful offsets in the status update map (offset) * */ #define FT1000MP_SUMO_DISPLAYED_STATUS 0x00 #define FT1000MP_SUMO_DISPLAYED_FREQ 0x01 #define FT1000MP_SUMO_VFO_A_FREQ 0x01 #define FT1000MP_SUMO_VFO_B_FREQ 0x11 #define FT1000MP_SUMO_VFO_A_CLAR 0x05 #define FT1000MP_SUMO_VFO_B_CLAR 0x15 #define FT1000MP_SUMO_VFO_A_MODE 0x07 #define FT1000MP_SUMO_VFO_B_MODE 0x17 #define FT1000MP_SUMO_VFO_A_IF 0x08 #define FT1000MP_SUMO_VFO_B_IF 0x18 #define FT1000MP_SUMO_VFO_A_MEM 0x09 #define FT1000MP_SUMO_VFO_B_MEM 0x19 /* mask extra mode bit from IF Filter status byte in VFO status block */ #define IF_MODE_MASK 0x80 #endif /* _FT1000MP_H */ hamlib-4.6.2/rigs/yaesu/frg9600.c0000644000175000017500000001267714752216205013254 00000000000000/* * frg9600.c - (C) Stephane Fillod 2002-2004 * * This shared library provides an API for communicating * via serial interface to an FRG-9600 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" /* Private helper function prototypes */ #define FRG9600_MODES (RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define FRG9600_VFOS (RIG_VFO_A) static int frg9600_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int frg9600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* * frg9600 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps frg9600_caps = { RIG_MODEL(RIG_MODEL_FRG9600), .model_name = "FRG-9600", .mfg_name = "Yaesu", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 300, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(60), MHz(905), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, FRG9600_VFOS }, {MHz(60), MHz(460), RIG_MODE_SSB, -1, -1, FRG9600_VFOS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {MHz(60), MHz(905), RIG_MODE_AM | RIG_MODE_FM | RIG_MODE_WFM, -1, -1, FRG9600_VFOS }, {MHz(60), MHz(460), RIG_MODE_SSB, -1, -1, FRG9600_VFOS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_AM, Hz(100)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_WFM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, at -3dB ! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(180)}, RIG_FLT_END, }, .set_freq = frg9600_set_freq, .set_mode = frg9600_set_mode, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #define MODE_SET_LSB 0x10 #define MODE_SET_USB 0x11 #define MODE_SET_AMN 0x14 #define MODE_SET_AMW 0x15 #define MODE_SET_FMN 0x16 #define MODE_SET_WFM 0x17 int frg9600_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x0a, 0x00, 0x00, 0x00, 0x00}; /* store bcd format in cmd (MSB) */ to_bcd_be(cmd + 1, freq / 10, 8); /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg9600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char md; /* * translate mode from generic to frg9600 specific */ switch (mode) { case RIG_MODE_USB: md = MODE_SET_USB; break; case RIG_MODE_LSB: md = MODE_SET_LSB; break; case RIG_MODE_FM: md = MODE_SET_FMN; break; case RIG_MODE_WFM: md = MODE_SET_WFM; break; case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md = MODE_SET_AMN; } else { md = MODE_SET_AMW; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } cmd[0] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } hamlib-4.6.2/rigs/yaesu/ft990v12.h0000755000175000017500000002363714752216205013371 00000000000000/* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft990.h - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* MODIFIED VERSION for FT-990 with ROM v1.2 : June 2022 * The standard version was written for FT-990 with ROM v1.3 and as the CAT spec was different to ROM v1.2 CAT * would not work with the older ROM. This version enables ROM v1.2 to work although it is necessary to accept * that frequent polling functionality is not feasible with this older ROM. With ROM v1.2 polling fetches 1492 * bytes which at 4800 Baud takes about 3.8 seconds during which the FT-990 has a CAT blackout. The longest poll * interval available in WSJT-X is 99 seconds. * Collaboration between M0EZP David Brewerton and K1MMI Edmund Hajjar */ #ifndef _FT990UNI_H #define _FT990UNI_H 1 // Global Definitions #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE /* RX caps */ #define FT990_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) #define FT990_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB) #define FT990_RTTY_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FT990_AM_RX_MODES (RIG_MODE_AM) #define FT990_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TX caps */ #define FT990_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) /* 100 W class */ #define FT990_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT990_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TUNER) /* fix */ /* Other features */ #define FT990_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT990_ANTS 0 #define FT990_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) /* Returned data length in bytes */ #define FT990_ALL_DATA_LENGTH 1492 /* 0x10 P1 = 00 return size */ #define FT990_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT990_OP_DATA_LENGTH 32 /* 0x10 P1 = 02 return size */ #define FT990_VFO_DATA_LENGTH 32 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT990_MEM_CHNL_DATA_LENGTH 16 /* 0x10 P1 = 04, P4 = 0x00-0x59 return size */ #define FT990_READ_METER_LENGTH 5 /* 0xf7 return size */ #define FT990_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define FT990_BCD_DIAL 8 #define FT990_BCD_RIT 3 #define FT990_BCD_RPTR_OFFSET 6 /* Timing values in mS */ #define FT990_PACING_INTERVAL 5 #define FT990_PACING_DEFAULT_VALUE 0 #define FT990_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT990_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT990_DEFAULT_READ_TIMEOUT FT990_ALL_DATA_LENGTH * ( 5 + (FT990_PACING_INTERVAL * FT990_PACING_DEFAULT_VALUE)) /* * The definitions below are copied from the kft990 * project and are hereby made available to the * hamlib project. [BJW] */ // OpCode Declarations #define FT990_CMD_SPLIT 0x01 #define FT990_CMD_RECALLMEM 0x02 #define FT990_CMD_VFO2MEM 0x03 #define FT990_CMD_LOCK 0x04 #define FT990_CMD_SELVFOAB 0x05 #define FT990_CMD_MEM2VFO 0x06 #define FT990_CMD_UP 0x07 #define FT990_CMD_DOWN 0x08 #define FT990_CMD_CLARIFIER 0x09 #define FT990_CMD_SETVFOA 0x0a #define FT990_CMD_SELOPMODE 0x0c #define FT990_CMD_PACING 0x0e #define FT990_CMD_PTT 0x0f #define FT990_CMD_UPDATE 0x10 #define FT990_CMD_TUNER 0x81 #define FT990_CMD_START 0x82 #define FT990_CMD_RPT 0x84 #define FT990_CMD_VFOA2B 0x85 #define FT990_CMD_BW 0x8c #define FT990_CMD_MEMSCANSKIP 0x8d #define FT990_CMD_STEPVFO 0x8e #define FT990_CMD_RDMETER 0xf7 #define FT990_CMD_DIMLEVEL 0xf8 #define FT990_CMD_RPTROFFSET 0xf9 #define FT990_CMD_RDFLAGS 0xfa // Bandwidth Filter #define FT990_BW_F2400 0x00 #define FT990_BW_F2000 0x01 #define FT990_BW_F500 0x02 #define FT990_BW_F250 0x03 #define FT990_BW_F6000 0x04 #define FT990_BW_FMPKTRTTY 0x80 // Operating Mode Status #define FT990_MODE_LSB 0x00 #define FT990_MODE_USB 0x01 #define FT990_MODE_CW 0x02 #define FT990_MODE_AM 0x03 #define FT990_MODE_FM 0x04 #define FT990_MODE_RTTY 0x05 #define FT990_MODE_PKT 0x06 // Operation Mode Selection #define FT990_OP_MODE_LSB 0x00 #define FT990_OP_MODE_USB 0x01 #define FT990_OP_MODE_CW2400 0x02 #define FT990_OP_MODE_CW500 0x03 #define FT990_OP_MODE_AM6000 0x04 #define FT990_OP_MODE_AM2400 0x05 #define FT990_OP_MODE_FM 0x06 #define FT990_OP_MODE_RTTYLSB 0x08 #define FT990_OP_MODE_RTTYUSB 0x09 #define FT990_OP_MODE_PKTLSB 0x0a #define FT990_OP_MODE_PKTFM 0x0b // Clarifier Operation #define FT990_CLAR_TX_EN 0x01 #define FT990_CLAR_RX_EN 0x02 #define FT990_CLAR_RX_OFF 0x00 #define FT990_CLAR_RX_ON 0x01 #define FT990_CLAR_TX_OFF 0x80 #define FT990_CLAR_TX_ON 0x81 #define FT990_CLAR_CLEAR 0xff #define FT990_CLAR_TUNE_UP 0x00 #define FT990_CLAR_TUNE_DOWN 0xff // Repeater Shift Enable #define FT990_RPT_POS_EN 0x04 #define FT990_RPT_NEG_EN 0x08 #define FT990_RPT_MASK 0x0C // Status Flag 1 Masks #define FT990_SF_SPLIT 0x01 #define FT990_SF_VFOB 0x02 #define FT990_SF_FAST 0x04 #define FT990_SF_CAT 0x08 #define FT990_SF_TUNING 0x10 #define FT990_SF_KEY_ENTRY 0x20 #define FT990_SF_MEM_EMPTY 0x40 #define FT990_SF_XMIT 0x80 // Status Flag 2 Masks #define FT990_SF_MEM_SCAN_PAUSE 0x01 #define FT990_SF_MEM_CHECK 0x02 #define FT990_SF_MEM_SCAN 0x04 #define FT990_SF_LOCKED 0x08 #define FT990_SF_MTUNE 0x10 #define FT990_SF_VFO 0x20 #define FT990_SF_MEM 0x40 #define FT990_SF_GEN 0x80 // Status Flag 3 Masks #define FT990_SF_PTT 0x01 #define FT990_SF_TX_INHIBIT 0x02 #define FT990_SF_KEY_TIMER 0x04 #define FT990_SF_MEM_TIMER 0x08 #define FT990_SF_PTT_INHIBIT 0x10 #define FT990_SF_XMIT_MON 0x20 #define FT990_SF_TUNER_ON 0x40 #define FT990_SF_SIDETONE 0x80 #define FT990_EMPTY_MEM 0x80 #define FT990_AMFILTER2400 0x80 // Flags Byte 1 typedef struct _ft990v12_flags1_t { unsigned split: 1; unsigned vfob: 1; unsigned fast: 1; unsigned cat: 1; unsigned tuning: 1; unsigned keyentry: 1; unsigned memempty: 1; unsigned xmit: 1; } ft990v12_flags1_t; // Flags Byte 2 typedef struct _ft990v12_flags2_t { unsigned memscanpause:1; unsigned memcheck: 1; unsigned memscan: 1; unsigned locked: 1; unsigned mtune: 1; unsigned vfo: 1; unsigned mem: 1; unsigned gen: 1; } ft990v12_flags2_t; // Flags Byte 3 typedef struct _ft990v12_status3_t { unsigned ptt: 1; unsigned txinhibit: 1; unsigned keytimer: 1; unsigned memtimer: 1; unsigned pttinhibit: 1; unsigned xmitmon: 1; unsigned tuneron: 1; unsigned sidetone: 1; } ft990v12_flags3_t; typedef union _ft990v12_flags1_u { ft990v12_flags1_t bits; unsigned char byte; } ft990v12_flags1_u; typedef union _ft990v12_flags2_u { ft990v12_flags2_t bits; unsigned char byte; } ft990v12_flags2_u; typedef union _ft990v12_flags3_u { ft990v12_flags3_t bits; unsigned char byte; } ft990v12_flags3_u; typedef struct _ft990v12_status_data_t { ft990v12_flags1_u flags1; ft990v12_flags2_u flags2; ft990v12_flags3_u flags3; unsigned char id1; unsigned char id2; } ft990v12_status_data_t; typedef struct _ft990v12_meter_data_t { unsigned char mdata1; unsigned char mdata2; unsigned char mdata3; unsigned char mdata4; unsigned char id1; } ft990v12_meter_data_t; typedef struct _ft990v12_op_data_t { unsigned char bpf; unsigned char basefreq[3]; unsigned char status; unsigned char coffset[2]; unsigned char mode; unsigned char filter; unsigned char lastssbfilter; unsigned char lastcwfilter; unsigned char lastrttyfilter; unsigned char lastpktfilter; unsigned char lastclariferstate; unsigned char skipscanamfilter; unsigned char amfm100; } ft990v12_op_data_t; // Update Data Structure typedef struct _ft990v12_update_data_t { unsigned char flag1; unsigned char flag2; unsigned char flag3; unsigned char channelnumber; ft990v12_op_data_t current_front; /* ft990_op_data_t current_rear; M0EZP: field not valid for FT990 ROM v1.2 */ ft990v12_op_data_t vfoa; ft990v12_op_data_t vfob; ft990v12_op_data_t channel[90]; } ft990v12_update_data_t; // Command Structure typedef struct _ft990v12_command_t { unsigned char data[4]; unsigned char opcode; } ft990v12_command_t; #endif /* _FT990UNI_H */ hamlib-4.6.2/rigs/yaesu/ft1000d.h0000644000175000017500000002427714752216205013241 00000000000000/* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft1000d.h - (C) 2016 Sean Sharkey (g0oan at icloud.com) * * This shared library provides an API for communicating * via serial interface to an FT-1000D using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT1000D_H #define _FT1000D_H 1 // Global Definitions #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE /* RX caps */ #define FT1000D_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) #define FT1000D_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB) #define FT1000D_RTTY_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FT1000D_AM_RX_MODES (RIG_MODE_AM) #define FT1000D_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TX caps */ #define FT1000D_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) /* 100 W class */ #define FT1000D_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT1000D_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TUNER) /* fix */ /* Other features */ #define FT1000D_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT1000D_ANTS 0 #define FT1000D_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) // Added the below to store currently selected VFO as set by CAT command Opcode 05h #define FT1000D_CURRENTLY_SELECTED_VFO /* Returned data length in bytes */ #define FT1000D_ALL_DATA_LENGTH 1636 /* 0x10 P1 = 00 return size */ #define FT1000D_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT1000D_OP_DATA_LENGTH 16 /* 0x10 P1 = 02 return size */ #define FT1000D_VFO_DATA_LENGTH 32 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT1000D_MEM_CHNL_DATA_LENGTH 16 /* 0x10 P1 = 04, P4 = 0x00-0x59 return size */ #define FT1000D_READ_METER_LENGTH 5 /* 0xf7 return size */ #define FT1000D_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define FT1000D_BCD_DIAL 8 #define FT1000D_BCD_RIT 3 #define FT1000D_BCD_RPTR_OFFSET 6 /* Timing values in mS */ #define FT1000D_PACING_INTERVAL 5 #define FT1000D_PACING_DEFAULT_VALUE 0 #define FT1000D_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT1000D_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT1000D_DEFAULT_READ_TIMEOUT FT1000D_ALL_DATA_LENGTH * ( 5 + (FT1000D_PACING_INTERVAL * FT1000D_PACING_DEFAULT_VALUE)) /* * The definitions below are copied from the kFT1000D * project and are hereby made available to the * hamlib project. [BJW] */ // OpCode Declarations #define FT1000D_CMD_SPLIT 0x01 #define FT1000D_CMD_RECALLMEM 0x02 #define FT1000D_CMD_VFO2MEM 0x03 #define FT1000D_CMD_LOCK 0x04 #define FT1000D_CMD_SELVFOAB 0x05 #define FT1000D_CMD_MEM2VFO 0x06 #define FT1000D_CMD_UP 0x07 #define FT1000D_CMD_DOWN 0x08 #define FT1000D_CMD_CLARIFIER 0x09 #define FT1000D_CMD_SETVFOA 0x0a #define FT1000D_CMD_SELOPMODE 0x0c #define FT1000D_CMD_PACING 0x0e #define FT1000D_CMD_PTT 0x0f #define FT1000D_CMD_UPDATE 0x10 #define FT1000D_CMD_TUNER 0x81 #define FT1000D_CMD_START 0x82 #define FT1000D_CMD_RPT 0x84 #define FT1000D_CMD_VFOA2B 0x85 #define FT1000D_CMD_SUBVFOFREQ 0X8a #define FT1000D_CMD_BW 0x8c #define FT1000D_CMD_MEMSCANSKIP 0x8d #define FT1000D_CMD_STEPVFO 0x8e #define FT1000D_CMD_RDMETER 0xf7 #define FT1000D_CMD_DIMLEVEL 0xf8 #define FT1000D_CMD_RPTROFFSET 0xf9 #define FT1000D_CMD_RDFLAGS 0xfa // Bandwidth Filter #define FT1000D_BW_F2400 0x00 #define FT1000D_BW_F2000 0x01 #define FT1000D_BW_F500 0x02 #define FT1000D_BW_F250 0x03 #define FT1000D_BW_F6000 0x04 #define FT1000D_BW_FMPKTRTTY 0x80 #define FT1000D_SUB_VFOB_BW_F2400 0x80 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F2000 0x81 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F500 0x82 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F250 0x83 /* Added December 2016 */ #define FT1000D_SUB_VFOB_BW_F6000 0x84 /* Added December 2016 */ // Operating Mode Status #define FT1000D_MODE_LSB 0x00 #define FT1000D_MODE_USB 0x01 #define FT1000D_MODE_CW 0x02 #define FT1000D_MODE_AM 0x03 #define FT1000D_MODE_FM 0x04 #define FT1000D_MODE_RTTY 0x05 #define FT1000D_MODE_PKT 0x06 // Operation Mode Selection #define FT1000D_OP_MODE_LSB 0x00 #define FT1000D_OP_MODE_USB 0x01 #define FT1000D_OP_MODE_CW2400 0x02 #define FT1000D_OP_MODE_CW500 0x03 #define FT1000D_OP_MODE_AM6000 0x04 #define FT1000D_OP_MODE_AM2400 0x05 #define FT1000D_OP_MODE_FM 0x06 #define FT1000D_OP_MODE_RTTYLSB 0x08 #define FT1000D_OP_MODE_RTTYUSB 0x09 #define FT1000D_OP_MODE_PKTLSB 0x0a #define FT1000D_OP_MODE_PKTFM 0x0b // Clarifier Operation #define FT1000D_CLAR_TX_EN 0x01 #define FT1000D_CLAR_RX_EN 0x02 #define FT1000D_CLAR_RX_OFF 0x00 #define FT1000D_CLAR_RX_ON 0x01 #define FT1000D_CLAR_TX_OFF 0x80 #define FT1000D_CLAR_TX_ON 0x81 #define FT1000D_CLAR_CLEAR 0xff #define FT1000D_CLAR_TUNE_UP 0x00 #define FT1000D_CLAR_TUNE_DOWN 0xff // Repeater Shift Enable #define FT1000D_RPT_POS_EN 0x04 #define FT1000D_RPT_NEG_EN 0x08 #define FT1000D_RPT_MASK 0x0C // Status Flag 1 Masks #define FT1000D_SF_SPLIT 0x01 /* Added December 2016 */ #define FT1000D_SF_DUAL 0x02 /* Added December 2016 */ #define FT1000D_SF_ANT_TUNER_ACTIVE 0x04 /* Added December 2016 */ #define FT1000D_SF_CAT 0x08 /* Added December 2016 */ #define FT1000D_SF_VFOB_INUSE 0x10 /* Added December 2016 APPEARS NOT TO WORK RIG DOES NOT SET BIT */ #define FT1000D_SF_KEY_ENTRY 0x20 /* Added December 2016 */ #define FT1000D_SF_MEM_EMPTY 0x40 /* Added December 2016 */ #define FT1000D_SF_XMIT 0x80 /* Added December 2016 */ // Status Flag 2 Masks #define FT1000D_SF_MEM_SCAN_PAUSE 0x01 #define FT1000D_SF_MEM_CHECK 0x02 #define FT1000D_SF_MEM_SCAN 0x04 #define FT1000D_SF_LOCKED 0x08 #define FT1000D_SF_MTUNE 0x10 #define FT1000D_SF_VFO 0x20 #define FT1000D_SF_MEM 0x40 #define FT1000D_SF_GEN 0x80 // Status Flag 3 Masks #define FT1000D_SF_PTT 0x01 #define FT1000D_SF_TX_INHIBIT 0x02 #define FT1000D_SF_KEY_TIMER 0x04 #define FT1000D_SF_MEM_TIMER 0x08 #define FT1000D_SF_PTT_INHIBIT 0x10 #define FT1000D_SF_XMIT_MON 0x20 #define FT1000D_SF_TUNER_ON 0x40 #define FT1000D_SF_SUB_VFOB_LOCKED 0x80 #define FT1000D_EMPTY_MEM 0x80 #define FT1000D_AMFILTER2400 0x80 // Flags Byte 1 typedef struct _ft1000d_flags1_t { unsigned split: 1; unsigned dualrx: 1; unsigned tuneact: 1; unsigned cat: 1; unsigned vfobinuse: 1; unsigned keyentry: 1; unsigned memempty: 1; unsigned xmit: 1; } ft1000d_flags1_t; // Flags Byte 2 typedef struct _ft1000d_flags2_t { unsigned memscanpause:1; unsigned memcheck: 1; unsigned memscan: 1; unsigned locked: 1; unsigned mtune: 1; unsigned vfo: 1; unsigned mem: 1; unsigned gen: 1; } ft1000d_flags2_t; // Flags Byte 3 typedef struct _ft1000d_status3_t { unsigned ptt: 1; unsigned txinhibit: 1; unsigned keytimer: 1; unsigned memtimer: 1; unsigned pttinhibit: 1; unsigned xmitmon: 1; unsigned tuneron: 1; unsigned subvfoblock: 1; } ft1000d_flags3_t; typedef union _ft1000d_flags1_u { ft1000d_flags1_t bits; unsigned char byte; } ft1000d_flags1_u; typedef union _ft1000d_flags2_u { ft1000d_flags2_t bits; unsigned char byte; } ft1000d_flags2_u; typedef union _ft1000d_flags3_u { ft1000d_flags3_t bits; unsigned char byte; } ft1000d_flags3_u; typedef struct _ft1000d_status_data_t { ft1000d_flags1_u flags1; ft1000d_flags2_u flags2; ft1000d_flags3_u flags3; unsigned char id1; unsigned char id2; } ft1000d_status_data_t; typedef struct _ft1000d_meter_data_t { unsigned char mdata1; unsigned char mdata2; unsigned char mdata3; unsigned char mdata4; unsigned char id1; } ft1000d_meter_data_t; typedef struct _ft1000d_op_data_t { unsigned char bpf; unsigned char basefreq[3]; unsigned char status; unsigned char coffset[2]; unsigned char mode; unsigned char filter; unsigned char lastssbfilter; unsigned char lastcwfilter; unsigned char lastrttyfilter; unsigned char lastpktfilter; unsigned char lastclariferstate; unsigned char skipscanamfilter; unsigned char amfm100; } ft1000d_op_data_t; // Update Data Structure typedef struct _ft1000d_update_data_t { unsigned char flag1; unsigned char flag2; unsigned char flag3; unsigned char channelnumber; ft1000d_op_data_t current_front; ft1000d_op_data_t current_rear; ft1000d_op_data_t vfoa; ft1000d_op_data_t vfob; ft1000d_op_data_t channel[90]; } ft1000d_update_data_t; // Command Structure typedef struct _ft1000d_command_t { unsigned char data[4]; unsigned char opcode; } ft1000d_command_t; #endif /* _FT1000D_H */ hamlib-4.6.2/rigs/yaesu/ft767gx.c0000644000175000017500000013732314752216205013367 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft767gx.c - (C) Steve Conklin 2007 * adapted from ft757gx.c by Stephane Fillod 2004 * This shared library provides an API for communicating * via serial interface to an FT-767GX using the "CAT" interface * box (FIF-232C) or similar * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO * * 1. Allow cached reads * 2. set_mem/get_mem, get_channel, set_split/get_split, * set_func/get_func * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft767gx.h" static int ft767_init(RIG *rig); static int ft767_cleanup(RIG *rig); static int ft767_open(RIG *rig); static int ft767_close(RIG *rig); static int ft767_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft767_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft767_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft767_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft767_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft767_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft767_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft767_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft767_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); static int ft767_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft767_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); static int ft767_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft767_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int ft767_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft767_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft767_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft767_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); /* Private helper function prototypes */ static int ft767_send_block_and_ack(RIG *rig, unsigned char *cmd, size_t length); static int ft767_get_update_data(RIG *rig); static int ft767_enter_CAT(RIG *rig); static int ft767_leave_CAT(RIG *rig); static int ft767_set_split(RIG *rig, unsigned int split); static unsigned char vfo2rig(RIG *rig, vfo_t vfo); static vfo_t rig2vfo(unsigned char status); static int mode2rig(RIG *rig, rmode_t mode); static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width); /* static int ctcss2rig(RIG *rig, tone_t tone); */ static int rig2ctcss(RIG *rig, unsigned char tn, tone_t *tone); /* * On the rig used by the author of this software, the values returned * by the rig for the CTCSS tones are different than those in the Yaesu * documentation. This could possibly be because he tone module in that * rig is an aftermarket board sold by the piexx company. Leaving the * following undefined uses the values discovered by experimentation. For * The original values defined in the Yaesu documentation, uncomment it. */ /* #define USE_YAESU_PUBLISHED_TONES */ #define FT767GX_VFOS (RIG_VFO_A|RIG_VFO_B) /* Valid command codes */ #define CMD_CAT_SW 0x00 #define CMD_CHECK 0x01 #define CMD_UP10HZ 0x02 #define CMD_DN10HZ 0x03 #define CMD_PROG_UP 0x04 #define CMD_PROG_DN 0x05 #define CMD_BAND_UP 0x06 #define CMD_BAND_DN 0x07 #define CMD_FREQ_SET 0x08 #define CMD_VFOMR 0x09 #define CMD_MULTICMD 0x0A /* This command code overloaded */ #define CMD_TONE_SET 0x0C #define CMD_ACK 0x0B /* subcommands for command code 0x0A */ /* values 0 - 9 select memories */ #define SUBCMD_MEM0 0x00 /* 8 bytes returned */ #define SUBCMD_MEM1 0x01 /* 8 bytes returned */ #define SUBCMD_MEM2 0x02 /* 8 bytes returned */ #define SUBCMD_MEM3 0x03 /* 8 bytes returned */ #define SUBCMD_MEM4 0x04 /* 8 bytes returned */ #define SUBCMD_MEM5 0x05 /* 8 bytes returned */ #define SUBCMD_MEM6 0x06 /* 8 bytes returned */ #define SUBCMD_MEM7 0x07 /* 8 bytes returned */ #define SUBCMD_MEM8 0x08 /* 8 bytes returned */ #define SUBCMD_MEM9 0x09 /* 8 bytes returned */ #define SUBCMD_MODE_LSB 0x10 /* 8 bytes returned */ #define SUBCMD_MODE_USB 0x11 /* 8 bytes returned */ #define SUBCMD_MODE_CW 0x12 /* 8 bytes returned */ #define SUBCMD_MODE_AM 0x13 /* 8 bytes returned */ #define SUBCMD_MODE_FM 0x14 /* 8 bytes returned */ #define SUBCMD_MODE_FSK 0x15 /* 8 bytes returned */ #define SUBCMD_HG_HAM 0x20 /* ham coverage */ #define SUBCMD_HG_GEN 0x21 /* general coverage */ #define SUBCMD_SPLIT 0x30 /* toggle split */ #define SUBCMD_CLAR 0x40 /* toggle clarifier */ #define SUBCMD_MTOV 0x50 /* memory to VFO */ #define SUBCMD_VTOM 0x60 /* VFO to memory */ #define SUBCMD_SWAP 0x70 /* swap VFO, memory */ #define SUBCMD_ACLR 0x80 /* turn off SPLIT, CLAR< OFFSET */ /* * Some useful offsets in the status update map (offset) * * Status Update Chart, FT767GXII */ #define STATUS_FLAGS 0 #define STATUS_CURR_FREQ 1 /* Operating Frequency */ #define STATUS_CURR_TONE 5 #define STATUS_CURR_MODE 6 #define STATUS_VFOA_FREQ 14 #define STATUS_VFOA_MODE 19 #define STATUS_VFOB_FREQ 20 #define STATUS_VFOB_MODE 25 /* Status bit masks */ #define STATUS_MASK_PTT 0x01 #define STATUS_MASK_HG 0x02 #define STATUS_MASK_TXINH 0x04 #define STATUS_MASK_SPLIT 0x08 #define STATUS_MASK_VFO 0x10 #define STATUS_MASK_MEM 0x20 #define STATUS_MASK_CLAR 0x40 #define STATUS_MASK_CAT 0x80 /* mode byte */ #define MODE_LSB 0x0 #define MODE_USB 0x1 #define MODE_CW 0x2 #define MODE_AM 0x3 #define MODE_FM 0x4 #define MODE_FSK 0x5 /* * Things that I need to figure out how to fit in */ //#define VFO_OPERATIONS_LIST (RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_TOGGLE) /* These VFO OPS can only be applied to the current VFO */ // RIG_OP_UP = (1<<5), /*!< UP increment VFO freq by tuning step*/ // RIG_OP_DOWN = (1<<6), /*!< DOWN decrement VFO freq by tuning step*/ // RIG_OP_BAND_UP = (1<<7), /*!< Band UP */ /* #define FT767_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, .ctcss_tone = 1 \ } */ /* * End of things not put in yet */ /* * Receiver caps */ #define FT767GX_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT767GX_HF_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB) /* * TX caps */ #define FT767GX_ALL_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT767GX_HF_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB) #define CTCSS_TONE_LIST \ 670, 710, 747, 770, 797, 825, 854, 885, 915, 948, \ 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, \ 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, \ 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 /* * future - private data * */ struct ft767_priv_data { unsigned char pacing; /* pacing value */ unsigned char current_vfo; /* active VFO from last cmd , can be either RIG_VFO_A or RIG_VFO_B only */ unsigned char update_data[FT767GX_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ unsigned char rx_data[FT767GX_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ unsigned char ack_cmd[5]; }; tone_t static_767gx_ctcss_list[] = { CTCSS_TONE_LIST }; /* * ft767gx rigs capabilities. * Also this struct is READONLY! */ struct rig_caps ft767gx_caps = { RIG_MODEL(RIG_MODEL_FT767), .model_name = "FT-767GX", .mfg_name = "Yaesu", .version = "20230523.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT767GX_WRITE_DELAY, .post_write_delay = FT767GX_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = static_767gx_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = {RIG_CHAN_END, }, /* TODO need memory channel capabilities here */ // .chan_list = {0, 9, RIG_MTYPE_MEM, RIG_CHAN_END, }, /* TODO need memory channel capabilities here */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(100), .endf = 29999999, .modes = FT767GX_ALL_RX_MODES, .low_power = -1, .high_power = -1 }, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1500), 1999900, FT767GX_HF_TX_MODES, .low_power = 5000, .high_power = 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = kHz(3500), 3999900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = kHz(7000), 7499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(10), 10499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(14), 14499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(18), 18499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(21), 21499900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = kHz(24500), 24999900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(28), 29999900, FT767GX_HF_TX_MODES, 5000, 100000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(50), 59999900, FT767GX_ALL_TX_MODES, 5000, 10000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(144), 147999900, FT767GX_ALL_TX_MODES, 5000, 10000, FT767GX_VFOS, RIG_ANT_CURR}, {.startf = MHz(430), 449999990, FT767GX_ALL_TX_MODES, 5000, 10000, FT767GX_VFOS, RIG_ANT_CURR}, RIG_FRNG_END, }, .tuning_steps = { {FT767GX_ALL_RX_MODES, 10}, {FT767GX_ALL_RX_MODES, 100}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* private data */ .rig_init = ft767_init, .rig_cleanup = ft767_cleanup, .rig_open = ft767_open, /* port opened */ .rig_close = ft767_close, /* port closed */ .set_freq = ft767_set_freq, /* set freq */ .get_freq = ft767_get_freq, /* get freq */ .set_mode = ft767_set_mode, /* set mode */ .get_mode = ft767_get_mode, /* get mode */ .set_vfo = ft767_set_vfo, /* set vfo */ .get_vfo = ft767_get_vfo, /* get vfo */ .set_ptt = NULL, /* set ptt */ .get_ptt = ft767_get_ptt, /* get ptt */ .set_ctcss_tone = ft767_set_ctcss_tone, .get_ctcss_tone = ft767_get_ctcss_tone, .set_ctcss_sql = ft767_set_ctcss_sql, .get_ctcss_sql = ft767_get_ctcss_sql, .set_split_freq = ft767_set_split_freq, .get_split_freq = ft767_get_split_freq, .set_split_mode = ft767_set_split_mode, .get_split_mode = ft767_get_split_mode, .set_split_vfo = ft767_set_split_vfo, .get_split_vfo = ft767_get_split_vfo, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * _init * */ int ft767_init(RIG *rig) { struct ft767_priv_data *priv; if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft767_priv_data *) calloc(1, sizeof(struct ft767_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); /* TODO: read pacing from preferences */ priv->pacing = FT767GX_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_A; /* default to VFO_A ? */ priv->ack_cmd[0] = 00; priv->ack_cmd[1] = 00; priv->ack_cmd[2] = 00; priv->ack_cmd[3] = 00; priv->ack_cmd[4] = 0x0B; return RIG_OK; } /* * ft767_cleanup routine * the serial port is closed by the frontend */ int ft767_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * ft767_open routine * */ int ft767_open(RIG *rig) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; rig_flush(RIGPORT(rig)); /* send 0 delay PACING cmd to rig */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); memset(priv->update_data, 0, FT767GX_STATUS_UPDATE_DATA_LENGTH); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); memset(priv->update_data, 0, FT767GX_STATUS_UPDATE_DATA_LENGTH); return retval; } STATE(rig)->vfo_list = RIG_VFO_A | RIG_VFO_B; return RIG_OK; } /* * ft767_close routine * */ int ft767_close(RIG *rig) { int retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } return RIG_OK; } /* * This command only functions when operating on a vfo. * */ int ft767_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_FREQ_SET}; int retval; /* should the vfo be tested? */ /* fill in first four bytes */ to_bcd(cmd, freq / 10, 8); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } int ft767_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_MULTICMD}; int retval; /* fill in p1 */ cmd[3] = mode2rig(rig, mode); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } /* * Return Freq */ int ft767_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* grab freq and convert */ switch (vfo) { case RIG_VFO_CURR: *freq = from_bcd_be(priv->update_data + STATUS_CURR_FREQ, 8); break; case RIG_VFO_A: *freq = from_bcd_be(priv->update_data + STATUS_VFOA_FREQ, 8); break; case RIG_VFO_B: *freq = from_bcd_be(priv->update_data + STATUS_VFOB_FREQ, 8); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } *freq *= 10.0; /* rig reads in 10 Hz increments*/ return RIG_OK; } int ft767_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE( rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } switch (vfo) { case RIG_VFO_CURR: retval = rig2mode(rig, priv->update_data[STATUS_CURR_MODE], mode, width); break; case RIG_VFO_A: retval = rig2mode(rig, priv->update_data[STATUS_VFOA_MODE], mode, width); break; case RIG_VFO_B: retval = rig2mode(rig, priv->update_data[STATUS_VFOB_MODE], mode, width); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } return retval; } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ int ft767_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_VFOMR}; struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_A: cmd[3] = 0x00; break; case RIG_VFO_B: cmd[3] = 0x01; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } priv->current_vfo = vfo; retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } int ft767_get_vfo(RIG *rig, vfo_t *vfo) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } *vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); return RIG_OK; } int ft767_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } *ptt = (priv->update_data[STATUS_FLAGS] & 0x01) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* on this rig, only one tone can be set per VFO or memory, * and it's active for both tx and receive. */ int ft767_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_TONE_SET}; int retval; /* determine whether we have to send high-Q */ switch (tone) { case 747: case 797: case 854: case 915: cmd[1] = 1; /* High Q */ break; default: break; } /* fill in p2 and p1 with bcd tone value */ to_bcd(&cmd[2], tone, 4); /* cmd[3] = tone2rig(rig, tone); */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return retval; } int ft767_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } retval = rig2ctcss(rig, priv->update_data[STATUS_CURR_TONE], tone); return retval; } int ft767_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { return ft767_set_ctcss_tone(rig, vfo, tone); } int ft767_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { return ft767_get_ctcss_tone(rig, vfo, tone); } /* split functions */ int ft767_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; unsigned char freq_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_FREQ_SET}; unsigned char vfo_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_VFOMR}; vfo_t curr_vfo; vfo_t change_vfo; unsigned char curr_split; int retval; retval = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { return retval; } /* This appears to always pass in VFO_CURR as the vfo */ /* My decision is to only update the xmit VFO if we're in split mode */ retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* find out how we're currently configured */ curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to set something */ case RIG_VFO_A: change_vfo = RIG_VFO_B; break; case RIG_VFO_B: change_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } /* fill in first four bytes */ to_bcd(freq_cmd, tx_freq / 10, 8); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* change to the xmit VFO */ vfo_cmd[3] = vfo2rig(rig, change_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } /* change the freq */ retval = ft767_send_block_and_ack(rig, freq_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } /* change back to the rcv VFO */ vfo_cmd[3] = vfo2rig(rig, curr_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return RIG_OK; } int ft767_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; unsigned int offset; vfo_t curr_vfo; unsigned char curr_split; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to get something */ case RIG_VFO_A: offset = STATUS_VFOB_FREQ; break; case RIG_VFO_B: offset = STATUS_VFOA_FREQ; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } *tx_freq = from_bcd_be(priv->update_data + offset, 8); return RIG_OK; } int ft767_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; unsigned char mode_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_MULTICMD}; unsigned char vfo_cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_VFOMR}; vfo_t curr_vfo; vfo_t change_vfo; unsigned char curr_split; int retval; /* This appears to always pass in VFO_CURR as the vfo */ /* My decision is to only update the xmit mode if we're in split mode */ retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* find out how we're currently configured */ curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to set something */ case RIG_VFO_A: change_vfo = RIG_VFO_B; break; case RIG_VFO_B: change_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } /* fill in p1 */ mode_cmd[3] = mode2rig(rig, tx_mode); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* change to the xmit VFO */ vfo_cmd[3] = vfo2rig(rig, change_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send vfo change 1 command: status %d\n", __func__, retval); return retval; } /* change the mode */ retval = ft767_send_block_and_ack(rig, mode_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send mode command: status %d\n", __func__, retval); return retval; } /* change back to the rcv VFO */ vfo_cmd[3] = vfo2rig(rig, curr_vfo); retval = ft767_send_block_and_ack(rig, vfo_cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send vfo change 2command: status %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); } return RIG_OK; } int ft767_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; unsigned int offset; vfo_t curr_vfo; unsigned char curr_split; retval = ft767_get_update_data(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { switch (curr_vfo) { /* we need to get something */ case RIG_VFO_A: offset = STATUS_VFOB_MODE; break; case RIG_VFO_B: offset = STATUS_VFOA_MODE; break; case RIG_VFO_MEM: rig_debug(RIG_DEBUG_ERR, "%s: error, in both split and memory modes\n", __func__); return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: error, unknown vfo value %s\n", __func__, rig_strvfo(curr_vfo)); return RIG_OK; } } else { /* not in split mode, do nothing */ return RIG_OK; } /* get the actual mode */ retval = rig2mode(rig, priv->update_data[offset], tx_mode, tx_width); return retval; } int ft767_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; int retval; vfo_t curr_vfo; vfo_t future_vfo; unsigned char curr_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); if ((tx_vfo != RIG_VFO_A) && (tx_vfo != RIG_VFO_B)) { return -RIG_EINVAL; } retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* find out which VFO we're currently using */ curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); /* * If split is enabled, Set the current VFO to the opposite of * the one specified in tx_vfo. If split is not enabled, then don't change anything. */ switch (split) { case RIG_SPLIT_OFF: /* turn off split, leave everything else alone */ return ft767_set_split(rig, 0); break; case RIG_SPLIT_ON: switch (tx_vfo) { case RIG_VFO_CURR: // we need to switch VFOs if (curr_vfo == RIG_VFO_A) { future_vfo = RIG_VFO_B; } else if (curr_vfo == RIG_VFO_B) { future_vfo = RIG_VFO_B; } else { /* Currently using memory! */ rig_debug(RIG_DEBUG_ERR, "%s: RIG_VFO_CURR requested when it is a memory\n", __func__); return -RIG_EINVAL; } break; case RIG_VFO_A: future_vfo = RIG_VFO_B; break; case RIG_VFO_B: future_vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_flush(RIGPORT(rig)); retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* See whether we need to toggle the split state */ curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; if (curr_split) { curr_split = RIG_SPLIT_ON; } if (curr_split != split) { cmd[3] = SUBCMD_SPLIT; cmd[4] = CMD_MULTICMD; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send split command: status %d\n", __func__, retval); return retval; } } /* now set the rx vfo if needed */ if (curr_vfo != future_vfo) { cmd[3] = vfo2rig(rig, future_vfo); cmd[4] = CMD_VFOMR; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send set vfo command: status %d\n", __func__, retval); return retval; } } /* Make sure clarifier is off */ if (priv->update_data[STATUS_FLAGS] & STATUS_MASK_CLAR) { cmd[3] = SUBCMD_CLAR; cmd[4] = CMD_MULTICMD; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send set clar command: status %d\n", __func__, retval); return retval; } } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } break; default: return -RIG_EINVAL; } return RIG_OK; } int ft767_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE( rig)->priv; int retval; vfo_t curr_vfo; retval = ft767_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: get_update_data failed with status %d\n", __func__, retval); return retval; } /* TODO if SPLIT is enabled, return which VFO is the transmit VFO!! */ if (priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT) { *split = RIG_SPLIT_ON; } else { *split = RIG_SPLIT_OFF; } curr_vfo = rig2vfo(priv->update_data[STATUS_FLAGS]); switch (curr_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; default: /* we don't know how to deal with MEM, anything else is an error */ /* TODO make sure this is what we want to do here */ rig_debug(RIG_DEBUG_ERR, "%s: current vfo is %s with split\n", __func__, rig_strvfo(curr_vfo)); return -RIG_EINVAL; break; } return RIG_OK; } /* End of hamlib API-mapped functions */ /* * This function puts the radio in CAT mode */ int ft767_enter_CAT(RIG *rig) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, CMD_CAT_SW}; rig_debug(RIG_DEBUG_TRACE, "%s: Entered\n", __func__); return ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); } /* * This function takes the radio out of CAT mode */ int ft767_leave_CAT(RIG *rig) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x01, CMD_CAT_SW}; rig_debug(RIG_DEBUG_TRACE, "%s: Entered\n", __func__); return ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); } /* * The Yaesu interface is convoluted and braindead. * * Private helper function. The 767GX has a handshaking system that works like this: * * 5 byte command block sent to rig * (5 to 20 mS delay) * Rig echos 5 byte command block back * Send a 5 byte ACK block to the rig * (5 to 20 mS delay) * * Rig sends back a status update block (5-86 bytes) * The status update block is received in reverse byte order from the way it's structured * * In addition, You must send a command to enable CAT mode, and disable when done. * When in CAT mode, the front panel of the radio is locked out. * * There is an error in the manual, the response length for a TONE SET command * is 26 bytes, not 5. */ int ft767_send_block_and_ack(RIG *rig, unsigned char *cmd, size_t length) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); size_t replylen, cpycnt; unsigned char cmd_echo_buf[5]; int retval; unsigned char *src, *dst; /* Validate command and set length of data returned */ switch (cmd[4]) { case CMD_CHECK: case CMD_CAT_SW: replylen = 86; break; case CMD_UP10HZ: case CMD_DN10HZ: case CMD_PROG_UP: case CMD_PROG_DN: case CMD_BAND_UP: case CMD_BAND_DN: case CMD_FREQ_SET: case CMD_VFOMR: case CMD_ACK: replylen = 5; break; case CMD_TONE_SET: replylen = 26; /* the manual is wrong */ break; case CMD_MULTICMD: if (cmd[3] <= 0x15) { replylen = 8; } else { switch (cmd[3]) { case SUBCMD_HG_HAM: case SUBCMD_HG_GEN: case SUBCMD_SPLIT: case SUBCMD_CLAR: case SUBCMD_MTOV: replylen = 26; break; case SUBCMD_VTOM: replylen = 68; break; case SUBCMD_SWAP: case SUBCMD_ACLR: replylen = 5; break; default: /* invalid or unknown sub-command */ rig_debug(RIG_DEBUG_ERR, "%s: invalid sub-command 0x%x for command 0x%x\n", __func__, cmd[3], cmd[4]); return -RIG_EINVAL; } } break; default: /* invalid or unknown command */ rig_debug(RIG_DEBUG_ERR, "%s: invalid command 0x%x\n", __func__, cmd[4]); return -RIG_EINVAL; } /* send the command block */ write_block(rp, cmd, YAESU_CMD_LENGTH); /* read back the command block echo */ retval = read_block(rp, cmd_echo_buf, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: read_block failed: %s\n", __func__, rigerror(retval)); return retval; } /* see if it matches the command we sent */ if (memcmp(cmd_echo_buf, cmd, YAESU_CMD_LENGTH)) { rig_debug(RIG_DEBUG_ERR, "%s: Command echo doesn't match\n", __func__); return -RIG_EINVAL; } /* send the ACK */ write_block(rp, priv->ack_cmd, YAESU_CMD_LENGTH); /* read back the response (status bytes) */ retval = read_block(rp, priv->rx_data, replylen); // update data if (retval != replylen) { rig_debug(RIG_DEBUG_ERR, "%s: Got unexpected number of bytes %d in response\n", __func__, retval); return -RIG_EINVAL; } /* reverse the data buffer returned from the rig */ src = &priv->rx_data[0]; dst = &priv->update_data[replylen - 1]; cpycnt = replylen; while (cpycnt--) { *dst-- = *src++; } return RIG_OK; } /* * private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * * need to use this when doing ft767_get_* stuff */ int ft767_get_update_data(RIG *rig) { /* unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x01, CMD_CHECK}; */ struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; rig_flush(RIGPORT(rig)); /* Entering CAT updates our data structures */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: status = 0x%02x\n", __func__, priv->update_data[STATUS_FLAGS]); return RIG_OK; } int ft767_set_split(RIG *rig, unsigned int split) { struct ft767_priv_data *priv = (struct ft767_priv_data *)STATE(rig)->priv; int retval; unsigned int curr_split; rig_flush(RIGPORT(rig)); /* Entering CAT updates our data structures */ retval = ft767_enter_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: enter_CAT %d\n", __func__, retval); return retval; } /* See whether we need to toggle */ curr_split = priv->update_data[STATUS_FLAGS] & STATUS_MASK_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s called curr_split = %u, split = %u\n", __func__, curr_split, split); if (curr_split ^ split) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, SUBCMD_SPLIT, CMD_MULTICMD}; retval = ft767_send_block_and_ack(rig, cmd, YAESU_CMD_LENGTH); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to send command: status %d\n", __func__, retval); return retval; } } retval = ft767_leave_CAT(rig); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: leave_CAT %d\n", __func__, retval); return retval; } return RIG_OK; } unsigned char vfo2rig(RIG *rig, vfo_t vfo) { switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_A: return 0x00; break; case RIG_VFO_B: return 0x01; break; case RIG_VFO_MEM: return 0x02; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } } vfo_t rig2vfo(unsigned char status) { if (status & 0x20) { return RIG_VFO_MEM; } else if (status & 0x10) { return RIG_VFO_B; } else { return RIG_VFO_A; } } int mode2rig(RIG *rig, rmode_t mode) { int md; /* * translate mode from generic to ft767 specific */ switch (mode) { case RIG_MODE_LSB: md = SUBCMD_MODE_LSB; break; case RIG_MODE_USB: md = SUBCMD_MODE_USB; break; case RIG_MODE_CW: md = SUBCMD_MODE_CW; break; case RIG_MODE_AM: md = SUBCMD_MODE_AM; break; case RIG_MODE_FM: md = SUBCMD_MODE_FM; break; case RIG_MODE_PKTFM: md = SUBCMD_MODE_FSK; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width) { /* * translate mode from ft767 specific to generic */ switch (md & 0x07) { case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_CW: *mode = RIG_MODE_CW; break; case MODE_AM: *mode = RIG_MODE_AM; break; case MODE_FM: *mode = RIG_MODE_FM; break; case MODE_FSK: *mode = RIG_MODE_PKTFM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return RIG_OK; } int rig2ctcss(RIG *rig, unsigned char tn, tone_t *tone) { /* * translate tone from ft767 specific to generic */ switch (tn) { #ifdef USE_YAESU_PUBLISHED_TONES /* Yaesu documentation */ case 0x3E: *tone = 670; break; case 0x1D: *tone = 670; break; /* High Q */ case 0x3D: *tone = 719; break; case 0x1C: *tone = 719; break; /* High Q */ case 0x1B: *tone = 747; break; /* High Q */ case 0x3C: *tone = 770; break; case 0x1A: *tone = 770; break; /* High Q */ case 0x19: *tone = 797; break; /* High Q */ case 0x3B: *tone = 825; break; case 0x18: *tone = 825; break; /* High Q */ case 0x17: *tone = 854; break; /* High Q */ case 0x3A: *tone = 885; break; case 0x16: *tone = 885; break; /* High Q */ case 0x15: *tone = 915; break; /* High Q */ case 0x39: *tone = 948; break; case 0x38: *tone = 1000; break; case 0x37: *tone = 1035; break; case 0x36: *tone = 1072; break; case 0x35: *tone = 1109; break; case 0x34: *tone = 1148; break; case 0x33: *tone = 1188; break; case 0x32: *tone = 1230; break; case 0x31: *tone = 1273; break; case 0x30: *tone = 1318; break; case 0x2F: *tone = 1365; break; case 0x2E: *tone = 1413; break; case 0x2D: *tone = 1462; break; case 0x2C: *tone = 1514; break; case 0x2B: *tone = 1567; break; case 0x2A: *tone = 1622; break; case 0x29: *tone = 1679; break; case 0x28: *tone = 1738; break; case 0x27: *tone = 1799; break; case 0x26: *tone = 1862; break; case 0x25: *tone = 1928; break; case 0x24: *tone = 2035; break; case 0x23: *tone = 2107; break; case 0x22: *tone = 2181; break; case 0x21: *tone = 2257; break; case 0x20: *tone = 2336; break; case 0x1F: *tone = 2418; break; case 0x1E: *tone = 2503; break; #else /* values found by experimentation */ case 0: *tone = 670; break; case 33: *tone = 670; break; /* High Q */ case 01: *tone = 719; break; case 34: *tone = 719; break; /* High Q */ case 35: *tone = 747; break; /* High Q */ case 2: *tone = 770; break; case 36: *tone = 770; break; /* High Q */ case 37: *tone = 797; break; /* High Q */ case 3: *tone = 825; break; case 38: *tone = 825; break; /* High Q */ case 39: *tone = 854; break; /* High Q */ case 4: *tone = 885; break; case 40: *tone = 885; break; /* High Q */ case 41: *tone = 915; break; /* High Q */ case 5: *tone = 948; break; case 6: *tone = 1000; break; case 7: *tone = 1035; break; case 8: *tone = 1072; break; case 9: *tone = 1109; break; case 10: *tone = 1148; break; case 11: *tone = 1188; break; case 12: *tone = 1230; break; case 13: *tone = 1273; break; case 14: *tone = 1318; break; case 15: *tone = 1365; break; case 16: *tone = 1413; break; case 17: *tone = 1462; break; case 18: *tone = 1514; break; case 19: *tone = 1567; break; case 20: *tone = 1622; break; case 21: *tone = 1679; break; case 22: *tone = 1738; break; case 23: *tone = 1799; break; case 24: *tone = 1862; break; case 25: *tone = 1928; break; case 26: *tone = 2035; break; case 27: *tone = 2107; break; case 28: *tone = 2181; break; case 29: *tone = 2257; break; case 30: *tone = 2336; break; case 31: *tone = 2418; break; case 32: *tone = 2503; break; #endif default: rig_debug(RIG_DEBUG_ERR, "%s: Invalid tone value from rig: 0x%02x\n", __func__, tn); return -RIG_EINVAL; /* sorry, wrong TONE */ break; } return RIG_OK; } hamlib-4.6.2/rigs/yaesu/level_gran_yaesu.h0000644000175000017500000001014414752216205015473 00000000000000 // Once included these values can be overridden in the back-end // Known variants are PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 12 }, .step = { .i = 0 } }, [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 10 }, .step = { .f = 1 } }, /* levels with WPM units */ #if !defined(LVL_KEYSPD) [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, #endif /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 10 } }, #endif [LVL_IF] = { .min = { .i = -1200 }, .max = { .i = 1200 }, .step = { .i = 20 } }, #if !defined(NO_LVL_NOTCHF) [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, #endif /* levels with time units */ [LVL_VOXDELAY] = { .min = { .i = 3 }, .max = { .i = 300 }, .step = { .i = 1 } }, [LVL_BKINDL] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, [LVL_BKIN_DLYMS] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, /* levels with watt units */ [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, /* level with misc units */ [LVL_SWR] = { .min = { .f = 0 }, .max = { .f = 5.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_BAND_SELECT] = { .min = { .i = 0 }, .max = { .i = 16 }, .step = { .i = 1 } }, // most recent rigs seem to have 15 as the maximum -- other values can be set in the backend #if !defined(NO_LVL_NR) [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/15.0f } }, #endif /* levels with 0-1 values -- increment based on rig's range */ #if !defined(NO_LVL_AF) [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_RF) [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_RFPOWER) [LVL_RFPOWER] = { .min = { .f = 5.0/255.0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif [LVL_RFPOWER_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ID_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_VD_METER] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #if !defined(NO_LVL_SQL) [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_MICGAIN) [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_MONITOR_GAIN) [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_COMP) [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #endif #if !defined(NO_LVL_VOXGAIN) [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #endif [LVL_ANTIVOX] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ALC] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, hamlib-4.6.2/rigs/yaesu/ft900.h0000644000175000017500000000676314752216205013025 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft900.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-900 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT900_H #define _FT900_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT900_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT900_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT900_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT900_AM_RX_MODES (RIG_MODE_AM) #define FT900_FM_RX_MODES (RIG_MODE_FM) /* TX caps */ #define FT900_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT900_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT900_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) /* fix */ /* * Other features (used by rig_caps) * */ #define FT900_ANTS 0 /* Returned data length in bytes */ #define FT900_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT900_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT900_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT900_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT900_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT900_ALL_DATA_LENGTH 1941 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ #define FT900_PACING_INTERVAL 5 #define FT900_PACING_DEFAULT_VALUE 0 #define FT900_WRITE_DELAY 5 /* Delay sequential fast writes */ #define FT900_POST_WRITE_DELAY 50 /* Rough safe value for default timeout */ #define FT900_DEFAULT_READ_TIMEOUT 1941 * ( 5 + (FT900_PACING_INTERVAL * FT900_PACING_DEFAULT_VALUE)) /* BCD coded frequency length */ #define FT900_BCD_DIAL 8 #define FT900_BCD_RIT 3 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte * rate = 1 byte in 2.2917 msec => 1941 bytes in 4448 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 1941 bytes * ------------ ---------------------- * * 0 4448 msec (backend default) * 1 6389 msec * 2 8330 msec * 5 14153 msec * 255 499.4 sec * */ #endif /* _FT900_H */ hamlib-4.6.2/rigs/yaesu/ftdx10.c0000644000175000017500000003054214752216205013254 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx10.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX10(D/MP) using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ftdx10.h" const struct newcat_priv_caps ftdx10_priv_caps = { .roofing_filter_count = 6, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 12000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 }, // { .index = 3, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 }, { .index = 4, .set_value = '4', .get_value = '9', .width = 500, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = 'A', .width = 300, .optional = 0 }, } }; const struct confparams ftdx10_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "12 kHz", "3 kHz", "500 Hz", "300 Hz (optional)", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx10_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; struct rig_caps ftdx10_caps = { RIG_MODEL(RIG_MODEL_FTDX10), .model_name = "FTDX-10", .mfg_name = "Yaesu", .version = NEWCAT_VER ".9", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX10_WRITE_DELAY, .post_write_delay = FTDX10_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX10_FUNCS, .has_set_func = FTDX10_FUNCS, .has_get_level = FTDX10_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX10_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX10_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_COMMON | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the FTDX10 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX10_RFPOWER_METER_CAL, .swr_cal = FTDX10_SWR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 501, 510, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* 60M Channels, 5-01 - 5-10, if available */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX10_ALL_RX_MODES, -1, -1, FTDX10_VFO_ALL, FTDX10_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_HF(1, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_6m(1, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX10_ALL_RX_MODES, -1, -1, FTDX10_VFO_ALL, FTDX10_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_HF(2, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_6m(2, FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FTDX10_OTHER_TX_MODES, W(5), W(200), FTDX10_VFO_ALL, FTDX10_TX_ANTS), FRQ_RNG_4m_REGION2(FTDX10_AM_TX_MODES, W(2), W(75), FTDX10_VFO_ALL, FTDX10_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX10_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX10_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX10_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX10_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX10_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX10_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FTDX10_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FTDX10_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx10_ext_tokens, .extlevels = ftdx10_ext_levels, .priv = &ftdx10_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = NULL, .get_ant = NULL, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft840.c0000644000175000017500000014115014752216205013011 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft840.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002-2009 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-840 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft840.h" /* * Native FT840 functions. More to come :-) * */ enum ft840_native_cmd_e { FT840_NATIVE_SPLIT_OFF = 0, FT840_NATIVE_SPLIT_ON, FT840_NATIVE_RECALL_MEM, FT840_NATIVE_VFO_TO_MEM, FT840_NATIVE_VFO_A, FT840_NATIVE_VFO_B, FT840_NATIVE_MEM_TO_VFO, FT840_NATIVE_CLARIFIER_OPS, FT840_NATIVE_FREQ_SET, FT840_NATIVE_MODE_SET, FT840_NATIVE_PACING, FT840_NATIVE_PTT_OFF, FT840_NATIVE_PTT_ON, FT840_NATIVE_MEM_CHNL, FT840_NATIVE_OP_DATA, FT840_NATIVE_VFO_DATA, FT840_NATIVE_MEM_CHNL_DATA, FT840_NATIVE_TUNER_OFF, FT840_NATIVE_TUNER_ON, FT840_NATIVE_TUNER_START, FT840_NATIVE_READ_METER, FT840_NATIVE_READ_FLAGS, FT840_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; /* * * The FT-840 backend is cloned after the FT-890 backend. * * The differences are (as reported by Thomas - DK6KD): * -the 840 has 100 Memory channel, the 890 has 20 * -the 840 has 5 flag bytes, like the 890 but the third isn't specified in * the manual (the 890 has the ptt_enabled bit there, which is used by the * FT-890's get_ptt function), i need to investigate if there is really no * information in the third byte from the 840. * -the 840 RIT offset can not be set by a CAT command. The command exists * but it can only enable/disable RIT, it seems that the following bytes * given to this command containing the offset are ignored. * -the display brightness of the 840 can not be set by CAT * (This is an important feature, isn't it? HI) */ /* * Functions considered to be Beta code (2003-04-11): * set_freq * get_freq * set_mode * get_mode * set_vfo * get_vfo * set_ptt * get_ptt * set_split * get_split * set_rit * get_rit * set_func * get_func * get_level * * Functions considered to be Alpha code (2003-04-11): * vfo_op * * functions not yet implemented (2003-04-11): * set_split_freq * get_split_freq * set_split_mode * get_split_mode * */ /* Enable these as needed: */ #undef USE_FT840_GET_PTT #undef USE_FT840_SET_RIT /* * API local implementation * */ static int ft840_init(RIG *rig); static int ft840_cleanup(RIG *rig); static int ft840_open(RIG *rig); static int ft840_close(RIG *rig); static int ft840_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft840_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft840_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft840_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft840_set_vfo(RIG *rig, vfo_t vfo); static int ft840_get_vfo(RIG *rig, vfo_t *vfo); static int ft840_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); #ifdef USE_FT840_GET_PTT static int ft840_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); #endif /* USE_FT840_GET_PTT */ static int ft840_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft840_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); #ifdef USE_FT840_SET_RIT static int ft840_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); #endif /* USE_FT840_SET_RIT */ static int ft840_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft840_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft840_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft840_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private helper function prototypes */ static int ft840_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft840_send_static_cmd(RIG *rig, unsigned char ci); static int ft840_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft840_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); #ifdef USE_FT840_SET_RIT static int ft840_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); #endif /* USE_FT840_SET_RIT */ /* * Native ft840 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set display freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (19 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (18 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (19 bytes) P4 = 0x01-0x20 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* tuner off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* tuner on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* tuner start*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read meter, S on RX, ALC|PO|SWR on TX */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read status flags */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft840_caps.priv? -N0NB */ struct ft840_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT840_ALL_DATA_LENGTH]; /* returned data--max value, some are less */ unsigned char current_mem; /* private memory channel number */ }; /* * ft840 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft840_caps = { RIG_MODEL(RIG_MODEL_FT840), .model_name = "FT-840", .mfg_name = "Yaesu", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT840_WRITE_DELAY, .post_write_delay = FT840_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_TUNER, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TUNE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 100 */ .rx_range_list1 = { {kHz(100), MHz(30), FT840_ALL_RX_MODES, -1, -1, FT840_VFO_ALL, FT840_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT840_OTHER_TX_MODES, W(5), W(100), FT840_VFO_ALL, FT840_ANTS), FRQ_RNG_HF(1, FT840_AM_TX_MODES, W(2), W(25), FT840_VFO_ALL, FT840_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT840_ALL_RX_MODES, -1, -1, FT840_VFO_ALL, FT840_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT840_OTHER_TX_MODES, W(5), W(100), FT840_VFO_ALL, FT840_ANTS), FRQ_RNG_HF(2, FT840_AM_TX_MODES, W(2), W(25), FT840_VFO_ALL, FT840_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT840_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT840_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT840_AM_RX_MODES, Hz(100)}, /* Normal */ {FT840_AM_RX_MODES, kHz(1)}, /* Fast */ {FT840_FM_RX_MODES, Hz(100)}, /* Normal */ {FT840_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.2)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.2)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM */ RIG_FLT_END, }, .rig_init = ft840_init, .rig_cleanup = ft840_cleanup, .rig_open = ft840_open, /* port opened */ .rig_close = ft840_close, /* port closed */ .set_freq = ft840_set_freq, .get_freq = ft840_get_freq, .set_mode = ft840_set_mode, .get_mode = ft840_get_mode, .set_vfo = ft840_set_vfo, .get_vfo = ft840_get_vfo, .set_ptt = ft840_set_ptt, #ifdef USE_FT840_GET_PTT .get_ptt = ft840_get_ptt, #endif /* USE_FT840_GET_PTT */ .set_split_vfo = ft840_set_split_vfo, .get_split_vfo = ft840_get_split_vfo, #ifdef USE_FT840_SET_RIT .set_rit = ft840_set_rit, #endif /* USE_FT840_SET_RIT */ .get_rit = ft840_get_rit, .set_func = ft840_set_func, .get_level = ft840_get_level, .vfo_op = ft840_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ static int ft840_init(RIG *rig) { struct ft840_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft840_priv_data *) calloc(1, sizeof(struct ft840_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT840_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ return RIG_OK; } /* * rig_cleanup * * the serial port is closed by the frontend * */ static int ft840_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open * */ static int ft840_open(RIG *rig) { struct ft840_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close * */ static int ft840_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq * * Set frequency for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * If vfo differs from stored value then VFO will be set to the * passed vfo. * */ static int ft840_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft840_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { /* force a VFO change if requested vfo value differs from stored value */ err = ft840_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } err = ft840_send_dial_freq(rig, FT840_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq * * Return Freq for a given VFO * */ static int ft840_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft840_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { err = ft840_get_vfo(rig, &priv->current_vfo); if (err != RIG_OK) { return err; } vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_A_FREQ; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_B_FREQ; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT840_NATIVE_OP_DATA; offset = FT840_SUMO_DISPLAYED_FREQ; count = FT840_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft840_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode * * set mode and passband: eg AM, CW etc for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * */ static int ft840_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft840_priv_data *priv; unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft840 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft840_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } break; case RIG_VFO_B: err = ft840_set_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return err; } break; case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_CW_W; break; case RIG_MODE_USB: mode_parm = MODE_SET_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_FM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-840 only supports narrow width in AM and CW modes * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: mode_parm = MODE_SET_CW_N; break; case RIG_MODE_AM: mode_parm = MODE_SET_AM_N; break; default: return -RIG_EINVAL; /* Invalid mode, how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width, how can caller know? */ } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; /* good */ } /* * rig_get_mode * * get mode eg AM, CW etc for a given VFO * */ static int ft840_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft840_priv_data *priv; unsigned char my_mode, m_offset; /* ft840 mode, mode offset */ unsigned char flag, f_offset; /* CW/AM narrow flag */ int err, cmd_index, norm, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT840_NATIVE_VFO_DATA; m_offset = FT840_SUMO_VFO_A_MODE; f_offset = FT840_SUMO_VFO_A_FLAG; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_DATA; m_offset = FT840_SUMO_VFO_B_MODE; f_offset = FT840_SUMO_VFO_B_FLAG; count = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT840_NATIVE_OP_DATA; m_offset = FT840_SUMO_DISPLAYED_MODE; f_offset = FT840_SUMO_DISPLAYED_FLAG; count = FT840_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; } err = ft840_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } my_mode = MODE_MASK & priv->update_data[m_offset]; flag = FLAG_MASK & priv->update_data[f_offset]; rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: flag = 0x%02x\n", __func__, flag); /* * translate mode from ft840 to generic. */ switch (my_mode) { case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_CW: *mode = RIG_MODE_CW; if (flag & FLAG_CW_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_AM: *mode = RIG_MODE_AM; if (flag & FLAG_AM_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft840_set_vfo(RIG *rig, vfo_t vfo) { struct ft840_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* FIXME: Include support for RIG_VFO_MAIN */ switch (vfo) { case RIG_VFO_A: cmd_index = FT840_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_B; priv->current_vfo = vfo; break; case RIG_VFO_MEM: /* reset to memory channel stored by previous get_vfo * The recall mem channel command uses 0x01 though 0x20 */ err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_RECALL_MEM, (priv->current_mem + 1), 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->current_mem); return RIG_OK; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ static int ft840_get_vfo(RIG *rig, vfo_t *vfo) { struct ft840_priv_data *priv; unsigned char status_0; /* ft840 status flag 0 */ unsigned char stat_vfo, stat_mem; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft840_get_update_data(rig, FT840_NATIVE_READ_FLAGS, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT840_SUMO_DISPLAYED_STATUS_0]; stat_vfo = status_0 & SF_VFO_MASK; /* get VFO active bits */ stat_mem = status_0 & SF_MEM_MASK; /* get MEM active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, stat_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: stat_mem = 0x%02x\n", __func__, stat_mem); /* * translate vfo and mem status from ft840 to generic. * * First a test is made on bits 6 and 7 of status_0. Bit 7 is set * when FT-840 is in VFO mode on display. Bit 6 is set when VFO B * is active and cleared when VFO A is active. * * Conversely, bit 7 is cleared when MEM or MEM TUNE mode is selected * Bit 6 still follows last selected VFO (A or B), but this is not * tested right now. */ switch (stat_vfo) { case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; default: switch (stat_mem) { case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; /* * Per Hamlib policy capture and store memory channel number * for future set_vfo command. */ err = ft840_get_update_data(rig, FT840_NATIVE_MEM_CHNL, FT840_MEM_CHNL_LENGTH); if (err != RIG_OK) { return err; } priv->current_mem = priv->update_data[FT840_SUMO_MEM_CHANNEL]; rig_debug(RIG_DEBUG_TRACE, "%s: stored mem channel = 0x%02x\n", __func__, priv->current_mem); break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_ptt * * set the '840 into TX mode * * vfo is respected by calling ft840_set_vfo if * passed vfo != priv->current_vfo * */ static int ft840_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft840_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft840_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT840_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT840_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt * * get current PTT status * */ #ifdef USE_FT840_GET_PTT static int ft840_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft840_priv_data *priv; unsigned char status_2; /* ft840 status flag 2 */ unsigned char stat_ptt; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft840_get_update_data(rig, FT840_NATIVE_READ_FLAGS, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_2 = priv->update_data[FT840_SUMO_DISPLAYED_STATUS_2]; stat_ptt = status_2 & SF_PTT_MASK; /* get PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: ptt status_2 = 0x%02x\n", __func__, status_2); switch (stat_ptt) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } return RIG_OK; } #endif /* USE_FT840_GET_PTT */ /* * rig_set_split_vfo * * set the '840 into split TX/RX mode * * VFO cannot be set as the set split on command only changes the * TX to the other VFO. Setting split off returns the TX to the * main display. * */ static int ft840_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT840_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT840_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo * * Get whether the '840 is in split mode * * vfo value is not used * */ static int ft840_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft840_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft840_get_update_data(rig, FT840_NATIVE_READ_FLAGS, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* get Split active bit */ status_0 = SF_SPLIT & priv->update_data[FT840_SUMO_DISPLAYED_STATUS_0]; rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLIT: *split = RIG_SPLIT_ON; break; default: *split = RIG_SPLIT_OFF; break; } return RIG_OK; } /* * rig_set_rit * * VFO and MEM rit values are independent. * * passed vfo value is respected. * * Clarifier offset is retained in the rig for either VFO when the * VFO is changed. Offset is not retained when in memory tune mode * and VFO mode is selected or another memory channel is selected. * */ #ifdef USE_FT840_SET_RIT static int ft840_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft840_priv_data *priv; // unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9990 || rit > 9990) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); priv = (struct ft840_priv_data *)STATE(rig)->priv; /* * The assumption here is that the user hasn't changed * the VFO manually. Does it really need to be checked * every time? My goal is to reduce the traffic on the * serial line to a minimum, but respect the application's * request to change the VFO with this call. * */ if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous rig_get_vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft840_set_vfo(rig, vfo); } /* * Shuts clarifier off but does not set frequency to 0 Hz */ if (rit == 0) { err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_CLARIFIER_OPS, CLAR_RX_OFF, 0, 0, 0); return RIG_OK; } /* * Clarifier must first be turned on then the frequency can * be set, +9990 Hz to -9990 Hz */ err = ft840_send_dynamic_cmd(rig, FT840_NATIVE_CLARIFIER_OPS, CLAR_RX_ON, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft840_send_rit_freq(rig, FT840_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } #endif /* USE_FT840_SET_RIT */ /* * rig_get_rit * * Rig returns offset as hex from 0x0000 to 0x03e7 for 0 to +9.990 kHz * and 0xffff to 0xfc19 for -1 to -9.990 kHz * */ static int ft840_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft840_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index, length; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: cmd_index = FT840_NATIVE_OP_DATA; offset = FT840_SUMO_DISPLAYED_CLAR; length = FT840_OP_DATA_LENGTH; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_A_CLAR; length = FT840_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT840_NATIVE_VFO_DATA; offset = FT840_SUMO_VFO_B_CLAR; length = FT840_VFO_DATA_LENGTH; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft840_get_update_data(rig, cmd_index, length); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; /* returned value is hex to nearest hundred Hz */ if (f > 0xfc18) /* 0xfc19 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f * 10); *rit = f * 10; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_func * * set the '840 supported functions * * vfo is ignored for tuner as it is an independent function * */ static int ft840_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_TUNER: switch (status) { case OFF: cmd_index = FT840_NATIVE_TUNER_OFF; break; case ON: cmd_index = FT840_NATIVE_TUNER_ON; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_level * * get the '840 meter level * * vfo is ignored for now * * Meter level returned from FT-840 is S meter when rig is in RX * Meter level returned is one of ALC or PO or SWR when rig is in TX * depending on front panel meter selection. Meter selection is NOT * available via CAT. * * TODO: Add support for TX values * */ static int ft840_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft840_priv_data *priv; unsigned char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed level = %s\n", __func__, rig_strlevel(level)); priv = (struct ft840_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: err = ft840_get_update_data(rig, FT840_NATIVE_READ_METER, FT840_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[FT840_SUMO_METER]; /* * My FT-840 returns a range of 0x00 to 0x44 for S0 to S9 and 0x44 to * 0x9d for S9 to S9 +60 * * For ease of calculation I rounded S9 up to 0x48 (72 decimal) and * S9 +60 up to 0xa0 (160 decimal). I calculated a divisor for readings * less than S9 by dividing 72 by 54 and the divisor for readings greater * than S9 by dividing 88 (160 - 72) by 60. The result tracks rather well. * * The greatest error is around S1 and S2 and then from S9 to S9 +35. Such * is life when mapping non-linear S-meters to a linear scale. * */ if (*p > 160) { val->i = 60; } else if (*p <= 72) { val->i = ((72 - *p) / 1.3333) * -1; } else { val->i = ((*p - 72) / 1.4667); } rig_debug(RIG_DEBUG_TRACE, "%s: calculated level = %i\n", __func__, val->i); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op * * VFO operations--tuner start, etc * * vfo is ignored for now * */ static int ft840_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed op = 0x%02x\n", __func__, op); switch (op) { case RIG_OP_TUNE: cmd_index = FT840_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; } err = ft840_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * ************************************ * * Private functions to ft840 backend * * ************************************ */ /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 840 has several ways to * get data and several ways to return it. * * Need to use this when doing ft840_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft840_priv_data *priv; int n, err; /* for read_ */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft840_priv_data *)STATE(rig)->priv; err = ft840_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft840_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft840_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft840_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT840_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT840_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ #ifdef USE_FT840_SET_RIT static int ft840_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft840_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft840_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT840_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %li Hz\n", __func__, from_bcd(priv->p_cmd, FT840_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } #endif /* USE_FT840_SET_RIT */ hamlib-4.6.2/rigs/yaesu/ft891.c0000644000175000017500000005242514752216205013025 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft891.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * (C) Michael Black W9MDB 2016 -- taken from ft991c * * The FT891 is very much like the FT991 * So most of this code is a duplicate of the FT991 * * This shared library provides an API for communicating * via serial interface to an FT-891 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "newcat.h" #include "yaesu.h" #include "ft891.h" /* Prototypes */ static int ft891_init(RIG *rig); static int ft891_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft891_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft891_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft891_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft891_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); const struct confparams ft891_ext_levels[] = { { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft891_ext_tokens[] = { TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; /* * FT-891 rig capabilities */ struct rig_caps ft891_caps = { RIG_MODEL(RIG_MODEL_FT891), .model_name = "FT-891", .mfg_name = "Yaesu", .version = NEWCAT_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT891_WRITE_DELAY, .post_write_delay = FT891_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT891_FUNCS, .has_set_func = FT891_FUNCS, .has_get_level = FT891_LEVELS, .has_set_level = RIG_LEVEL_SET(FT891_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_RF #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_RF #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0f / 30.0f } }, [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDRGEN,BANDMW"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC */ .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT891_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT891_RFPOWER_METER_CAL, .str_cal = FT891_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(470), FT891_ALL_RX_MODES, -1, -1, FT891_VFO_ALL, FT891_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_HF(1, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ FRQ_RNG_6m(1, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_6m(1, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(470), FT891_ALL_RX_MODES, -1, -1, FT891_VFO_ALL, FT891_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_HF(2, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ FRQ_RNG_6m(2, FT891_OTHER_TX_MODES, W(5), W(100), FT891_VFO_ALL, FT891_ANTS), FRQ_RNG_6m(2, FT891_AM_TX_MODES, W(2), W(25), FT891_VFO_ALL, FT891_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT891_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT891_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT891_AM_RX_MODES, Hz(100)}, /* Normal */ {FT891_AM_RX_MODES, kHz(1)}, /* Fast */ {FT891_FM_RX_MODES, Hz(100)}, /* Normal */ {FT891_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT891_CW_RTTY_PKT_RX_MODES, Hz(1700)}, /* Normal CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(2000)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(1400)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(800)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(400)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(200)}, /* CW, RTTY, PKT */ {FT891_CW_RTTY_PKT_RX_MODES, Hz(100)}, /* CW, RTTY, PKT */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(2900)}, /* SSB */ {RIG_MODE_SSB, Hz(2800)}, /* SSB */ {RIG_MODE_SSB, Hz(2700)}, /* SSB */ {RIG_MODE_SSB, Hz(2600)}, /* SSB */ {RIG_MODE_SSB, Hz(2500)}, /* SSB */ {RIG_MODE_SSB, Hz(2250)}, /* SSB */ {RIG_MODE_SSB, Hz(2100)}, /* SSB */ {RIG_MODE_SSB, Hz(1950)}, /* SSB */ {RIG_MODE_SSB, Hz(1650)}, /* SSB */ {RIG_MODE_SSB, Hz(1500)}, /* SSB */ {RIG_MODE_SSB, Hz(1350)}, /* SSB */ {RIG_MODE_SSB, Hz(1100)}, /* SSB */ {RIG_MODE_SSB, Hz(850)}, /* SSB */ {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ {FT891_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY }, {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ {FT891_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FT891_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ RIG_FLT_END, }, .ext_tokens = ft891_ext_tokens, .extlevels = ft891_ext_levels, .priv = NULL, /* private data FIXME: */ .rig_init = ft891_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = ft891_set_mode, .get_mode = newcat_get_mode, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = ft891_set_split_vfo, .get_split_vfo = ft891_get_split_vfo, .get_split_mode = ft891_get_split_mode, .set_split_mode = ft891_set_split_mode, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .set_ts = newcat_set_ts, .get_ts = newcat_get_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ static int ft891_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct newcat_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct newcat_priv_data *)STATE(rig)->priv; // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if ((split == RIG_SPLIT_ON && (vfo == tx_vfo)) || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } switch (split) { case RIG_SPLIT_ON: ci = '1'; break; case RIG_SPLIT_OFF: ci = '0'; break; default: return -RIG_EINVAL; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ST%c;", ci); if (RIG_OK != (err = write_block(RIGPORT(rig), (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)))) { rig_debug(RIG_DEBUG_ERR, "%s: write_block err = %d\n", __func__, err); return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since can only split one way */ static int ft891_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct newcat_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct newcat_priv_data *)STATE(rig)->priv; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ST;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } // Get split mode status *split = priv->ret_data[2] != '0'; // 1=split, 2=split + 5khz rig_debug(RIG_DEBUG_TRACE, "%s: get split = 0x%02x\n", __func__, *split); *tx_vfo = RIG_VFO_A; if (*split) { *tx_vfo = RIG_VFO_B; } rig_debug(RIG_DEBUG_TRACE, "%s: get tx_vfo = 0x%02x\n", __func__, *tx_vfo); return RIG_OK; } /* * rig_get_split_mode* * * Get the '891 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 891 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft891_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct newcat_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct newcat_priv_data *)STATE(rig)->priv; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "OI;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } *tx_mode = priv->ret_data[22]; return RIG_OK; } /* * rig_set_split_mode * * Set the '891 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Passsband is not set here. * FT891 apparentlhy cannot set VFOB mode directly * So we'll just set A and swap A into B * */ static int ft891_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct newcat_priv_data *priv; freq_t b_freq; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); priv = (struct newcat_priv_data *)STATE(rig)->priv; // Remember VFOB frequency if (RIG_OK != (err = newcat_get_freq(rig, RIG_VFO_B, &b_freq))) { return err; } // Change mode on VFOA and make VFOB match VFOA if (RIG_OK != (err = newcat_set_mode(rig, RIG_VFO_A, tx_mode, tx_width))) { return err; } // Copy A to B SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AB;"); if (RIG_OK != (err = write_block(RIGPORT(rig), (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d write_block err = %d\n", __func__, __LINE__, err); return err; } // Restore VFOB frequency if (RIG_OK != (err = newcat_set_freq(rig, RIG_VFO_B, b_freq))) { return err; } #if 0 if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } #endif return RIG_OK; } static int ft891_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct newcat_priv_data *priv; int err; // FT891 can't set VFOB mode directly so we always set VFOA // We will always make VFOB match VFOA mode newcat_set_mode(rig, RIG_VFO_A, mode, width); priv = (struct newcat_priv_data *)STATE(rig)->priv; // Copy A to B SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AB;"); if (RIG_OK != (err = newcat_set_cmd(rig))) { return err; } return RIG_OK; } static int ft891_init(RIG *rig) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called, version %s\n", __func__, rig->caps->version); ret = newcat_init(rig); if (ret != RIG_OK) { return ret; } STATE(rig)->current_vfo = RIG_VFO_A; return RIG_OK; } hamlib-4.6.2/rigs/yaesu/yaesu.c0000644000175000017500000001476714752216205013307 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * yaesu.c - (C) Stephane Fillod 2001-2010 * * This shared library provides an API for communicating * via serial interface to a Yaesu rig * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include /* UNIX standard function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "yaesu.h" struct yaesu_id { rig_model_t model; int id1, id2; }; #define UNKNOWN_ID -1 /* * Identification number as returned by 0xFA opcode. * Note: On the FT736R, the 0xFA opcode sets CTCSS tone code * * Please, if the model number of your rig is listed as UNKNOWN_ID, * send the value to for inclusion. Thanks --SF */ static const struct yaesu_id yaesu_id_list[] = { { RIG_MODEL_FT1000D, 0x10, 0x21 }, /* or 0x10, 0x00 ? */ { RIG_MODEL_FT990, 0x09, 0x90 }, { RIG_MODEL_FT990UNI, 0x09, 0x90 }, { RIG_MODEL_FT890, 0x08, 0x41 }, { RIG_MODEL_FRG100, 0x03, 0x92 }, /* TBC, inconsistency in manual */ { RIG_MODEL_FT1000MP, 0x03, 0x93 }, { RIG_MODEL_FT1000MPMKV, 0x03, 0x93 }, /* or 0x10, 0x00 ? */ { RIG_MODEL_FT1000MPMKVFLD, 0x03, 0x93 }, { RIG_MODEL_VX1700, 0x06, 0x04 }, { RIG_MODEL_NONE, UNKNOWN_ID, UNKNOWN_ID }, /* end marker */ }; /* * initrigs_yaesu is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(yaesu) { rig_debug(RIG_DEBUG_VERBOSE, "yaesu: %s called\n", __func__); ft450d_caps = ft450_caps; ft450d_caps.rig_model = RIG_MODEL_FT450D; ft450d_caps.model_name = "FT-450D"; ft450d_caps.level_gran[LVL_RFPOWER].min.f = .05; ft450d_caps.level_gran[LVL_RFPOWER].step.f = 1.0f / 100.0f; rig_register(&ft100_caps); rig_register(&ft450_caps); rig_register(&ft450d_caps); rig_register(&ft736_caps); rig_register(&ft747_caps); rig_register(&ft757gx_caps); rig_register(&ft757gx2_caps); rig_register(&ft600_caps); rig_register(&ft767gx_caps); rig_register(&ft817_caps); rig_register(&ft847_caps); rig_register(&ft857_caps); rig_register(&ft897_caps); rig_register(&ft840_caps); rig_register(&ft890_caps); rig_register(&ft900_caps); rig_register(&ft920_caps); rig_register(&ft950_caps); rig_register(&ft980_caps); rig_register(&ft990_caps); rig_register(&ft990uni_caps); rig_register(&ft1000_caps); rig_register(&ft1000d_caps); rig_register(&ft1000mp_caps); rig_register(&ft1000mpmkv_caps); rig_register(&ft1000mpmkvfld_caps); rig_register(&ft2000_caps); rig_register(&ftdx3000_caps); rig_register(&ftdx5000_caps); rig_register(&ft9000_caps); rig_register(&ft9000Old_caps); rig_register(&frg100_caps); rig_register(&frg8800_caps); rig_register(&frg9600_caps); rig_register(&vr5000_caps); rig_register(&vx1700_caps); rig_register(&ftdx1200_caps); rig_register(&ft991_caps); rig_register(&ft891_caps); rig_register(&ft847uni_caps); rig_register(&ftdx101d_caps); rig_register(&ft818_caps); rig_register(&ftdx10_caps); rig_register(&ft897d_caps); rig_register(&ftdx101mp_caps); rig_register(&mchfqrp_caps); rig_register(&ft650_caps); rig_register(&ft710_caps); rig_register(&q900_caps); rig_register(&pmr171_caps); return RIG_OK; } /* * proberigs_yaesu * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_yaesu(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(yaesu) { unsigned char idbuf[YAESU_CMD_LENGTH + 1]; static const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xfa}; int id_len = -1, i, id1, id2; int retval = -1; static const int rates[] = { 4800, 57600, 9600, 38400, 0 }; /* possible baud rates */ int rates_idx; if (!port) { return RIG_MODEL_NONE; } if (port->type.rig != RIG_PORT_SERIAL) { return RIG_MODEL_NONE; } port->write_delay = port->post_write_delay = 20; port->parm.serial.stop_bits = 2; port->retry = 1; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { return RIG_MODEL_NONE; } /* send READ STATUS cmd to rig */ retval = write_block(port, cmd, YAESU_CMD_LENGTH); id_len = read_block(port, idbuf, YAESU_CMD_LENGTH); close(port->fd); if (retval == RIG_OK && id_len > 0) { break; } } if (retval != RIG_OK || id_len < 0) { return RIG_MODEL_NONE; } /* * reply should be [Flag1,Flag2,Flag3,ID1,ID2] */ if (id_len != 5 && id_len != 6) { idbuf[YAESU_CMD_LENGTH] = '\0'; rig_debug(RIG_DEBUG_WARN, "probe_yaesu: protocol error," " expected %d, received %d: %s\n", 6, id_len, idbuf); return RIG_MODEL_NONE; } id1 = idbuf[3]; id2 = idbuf[4]; for (i = 0; yaesu_id_list[i].model != RIG_MODEL_NONE; i++) { if (id1 == yaesu_id_list[i].id1 && id2 == yaesu_id_list[i].id2) { rig_debug(RIG_DEBUG_VERBOSE, "probe_yaesu: " "found ID %02xH %02xH\n", id1, id2); if (cfunc) { (*cfunc)(port, yaesu_id_list[i].model, data); } return yaesu_id_list[i].model; } } /* * not found in known table.... * update yaesu_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_yaesu: found unknown device " "with ID %02xH %02xH, please report to Hamlib " "developers.\n", id1, id2); return RIG_MODEL_NONE; } hamlib-4.6.2/rigs/yaesu/ft1200.h0000644000175000017500000001214614752216205013067 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft1200.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * ft1200.h - (C) David Fannin 2015 (kk6df at arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-1200 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FTDX1200_H #define _FTDX1200_H 1 #define FTDX1200_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FTDX1200_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN) #define FTDX1200_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX1200_AM_RX_MODES (RIG_MODE_AM) #define FTDX1200_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FTDX1200_FM_RX_MODES (FTDX1200_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FTDX1200_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX1200_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM) /* 100 W class */ #define FTDX1200_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ /* TBC */ #define FTDX1200_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) /* TBC */ #define FTDX1200_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_TUNER) /* TBC */ #define FTDX1200_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FTDX1200_RFPOWER_METER_CAL \ { \ 6, \ { \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FTDX1200_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FTDX1200_TX_ANTS (RIG_ANT_1|RIG_ANT_2) #define FTDX1200_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX1200_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX1200_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX1200_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX1200_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX1200_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT2000_PACING_INTERVAL 5 // #define FT2000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-2000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FTDX1200_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX1200_POST_WRITE_DELAY 5 #endif /* _FTDX1200_H */ hamlib-4.6.2/rigs/yaesu/ft991.c0000644000175000017500000010761714752216205013032 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft991.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * (C) Michael Black W9MDB 2015 -- taken from ft950.c * * The FT991 is very much like the FT950 except freq max increases for 440MHz * So most of this code is a duplicate of the FT950 * * This shared library provides an API for communicating * via serial interface to an FT-991 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "hamlib/rig.h" #include "misc.h" #include "newcat.h" #include "yaesu.h" #include "ft991.h" /* Prototypes */ static int ft991_init(RIG *rig); static int ft991_set_vfo(RIG *rig, vfo_t vfo); static int ft991_get_vfo(RIG *rig, vfo_t *vfo); static int ft991_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft991_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft991_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft991_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static void debug_ft991info_data(const ft991info *rdata); static int ft991_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft991_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); static int ft991_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft991_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code); static int ft991_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft991_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); static int ft991_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); static int ft991_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); const struct confparams ft991_ext_levels[] = { { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { TOK_MAXPOWER_HF, "MAXPOWER_HF", "Maxpower HF", "Maxpower HF", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_6M, "MAXPOWER_6M", "Maxpower 6m", "Maxpower 6m", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_VHF, "MAXPOWER_VHF", "Maxpower VHF", "Maxpower VHF", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 50, .step = 1 } }, }, { TOK_MAXPOWER_UHF, "MAXPOWER_UHF", "Maxpower UHF", "Maxpower UHF", NULL, RIG_CONF_NUMERIC, { .n = { .min = 5, .max = 50, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft991_ext_tokens[] = { TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_MAXPOWER_HF, TOK_MAXPOWER_6M, TOK_MAXPOWER_UHF, TOK_MAXPOWER_VHF, TOK_BACKEND_NONE }; /* * FT-991 rig capabilities */ struct rig_caps ft991_caps = { RIG_MODEL(RIG_MODEL_FT991), .model_name = "FT-991", .mfg_name = "Yaesu", .version = NEWCAT_VER ".18", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT991_WRITE_DELAY, .post_write_delay = FT991_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT991_FUNCS, .has_set_func = FT991_FUNCS, .has_get_level = FT991_LEVELS, .has_set_level = RIG_LEVEL_SET(FT991_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDAIR,BAND70CM,BAND33CM"}} }, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 12, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT991_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT991_RFPOWER_METER_CAL, .str_cal = FT991_STR_CAL, .id_meter_cal = FT991_ID_CAL, .vd_meter_cal = FT991_VD_CAL, .comp_meter_cal = FT991_COMP_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // P1L-P9U PMS channels { 118, 127, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // 5xx 5MHz band { 1, 5, RIG_MTYPE_VOICE }, { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, // Rig only has 1 model .rx_range_list1 = { {kHz(30), MHz(56), FT991_ALL_RX_MODES, -1, -1, FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(118), MHz(164), FT991_ALL_RX_MODES, -1, -1, FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(420), MHz(470), FT991_ALL_RX_MODES, -1, -1, FT991_VFO_ALL, FT991_ANTS, "Operating"}, RIG_FRNG_END, }, .tx_range_list1 = { {MHz(1.8), MHz(54), FT991_OTHER_TX_MODES, W(5), W(100), FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(1.8), MHz(54), FT991_AM_TX_MODES, W(2), W(25), FT991_VFO_ALL, FT991_ANTS, "Operating"}, /* AM class */ {MHz(144), MHz(148), FT991_OTHER_TX_MODES, W(5), W(50), FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(144), MHz(148), FT991_AM_TX_MODES, W(2), W(25), FT991_VFO_ALL, FT991_ANTS, "Operating"}, /* AM class */ {MHz(430), MHz(450), FT991_OTHER_TX_MODES, W(5), W(50), FT991_VFO_ALL, FT991_ANTS, "Operating"}, {MHz(430), MHz(450), FT991_AM_TX_MODES, W(2), W(25), FT991_VFO_ALL, FT991_ANTS, "Operating"}, /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT991_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT991_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT991_AM_RX_MODES, Hz(100)}, /* Normal */ {FT991_AM_RX_MODES, kHz(1)}, /* Fast */ {FT991_FM_RX_MODES, Hz(100)}, /* Normal */ {FT991_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT991_RTTY_DATA_RX_MODES, Hz(500)}, /* Normal RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(300)}, /* Narrow RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(3000)}, /* Wide RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(2400)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(2000)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(1700)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(1400)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(1200)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(800)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(450)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(400)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(350)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(250)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(200)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(150)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(100)}, /* RTTY, DATA */ {FT991_RTTY_DATA_RX_MODES, Hz(50)}, /* RTTY, DATA */ {FT991_CW_RX_MODES, Hz(2400)}, /* Normal CW */ {FT991_CW_RX_MODES, Hz(500)}, /* Narrow CW */ {FT991_CW_RX_MODES, Hz(3000)}, /* Wide CW */ {FT991_CW_RX_MODES, Hz(2000)}, /* CW */ {FT991_CW_RX_MODES, Hz(1700)}, /* CW */ {FT991_CW_RX_MODES, Hz(1400)}, /* CW */ {FT991_CW_RX_MODES, Hz(1200)}, /* CW */ {FT991_CW_RX_MODES, Hz(800)}, /* CW */ {FT991_CW_RX_MODES, Hz(450)}, /* CW */ {FT991_CW_RX_MODES, Hz(400)}, /* CW */ {FT991_CW_RX_MODES, Hz(350)}, /* CW */ {FT991_CW_RX_MODES, Hz(300)}, /* CW */ {FT991_CW_RX_MODES, Hz(250)}, /* CW */ {FT991_CW_RX_MODES, Hz(200)}, /* CW */ {FT991_CW_RX_MODES, Hz(150)}, /* CW */ {FT991_CW_RX_MODES, Hz(100)}, /* CW */ {FT991_CW_RX_MODES, Hz(50)}, /* CW */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1500)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3200)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(3000)}, /* SSB */ {RIG_MODE_SSB, Hz(2900)}, /* SSB */ {RIG_MODE_SSB, Hz(2800)}, /* SSB */ {RIG_MODE_SSB, Hz(2700)}, /* SSB */ {RIG_MODE_SSB, Hz(2600)}, /* SSB */ {RIG_MODE_SSB, Hz(2500)}, /* SSB */ {RIG_MODE_SSB, Hz(2300)}, /* SSB */ {RIG_MODE_SSB, Hz(2200)}, /* SSB */ {RIG_MODE_SSB, Hz(2100)}, /* SSB */ {RIG_MODE_SSB, Hz(1950)}, /* SSB */ {RIG_MODE_SSB, Hz(1650)}, /* SSB */ {RIG_MODE_SSB, Hz(1350)}, /* SSB */ {RIG_MODE_SSB, Hz(1100)}, /* SSB */ {RIG_MODE_SSB, Hz(850)}, /* SSB */ {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {FT991_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM, PKTFM, C4FM */ {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ RIG_FLT_END, }, .ext_tokens = ft991_ext_tokens, .extlevels = ft991_ext_levels, .priv = NULL, /* private data FIXME: */ .rig_init = ft991_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = ft991_set_vfo, .get_vfo = ft991_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_split_freq = ft991_set_split_freq, .get_split_freq = ft991_get_split_freq, .get_split_mode = ft991_get_split_mode, .set_split_mode = ft991_set_split_mode, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_parm = newcat_get_parm, .set_parm = newcat_set_parm, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = ft991_set_ctcss_tone, .get_ctcss_tone = ft991_get_ctcss_tone, .set_dcs_code = ft991_set_dcs_code, .get_dcs_code = ft991_get_dcs_code, .set_ctcss_sql = ft991_set_ctcss_sql, .get_ctcss_sql = ft991_get_ctcss_sql, .set_dcs_sql = ft991_set_dcs_sql, .get_dcs_sql = ft991_get_dcs_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .set_ts = newcat_set_ts, .get_ts = newcat_get_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .send_voice_mem = newcat_send_voice_mem, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int ft991_get_tx_split(RIG *rig, split_t *in_split) { vfo_t cur_tx_vfo; int rval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !in_split) { return (-RIG_EINVAL); } rval = newcat_get_tx_vfo(rig, &cur_tx_vfo); if (rval != RIG_OK) { return (rval); } if (cur_tx_vfo == RIG_VFO_B || cur_tx_vfo == RIG_VFO_MEM) { *in_split = RIG_SPLIT_ON; } else if (cur_tx_vfo == RIG_VFO_A) { *in_split = RIG_SPLIT_OFF; } else { return (-RIG_EINVAL); } return (rval); } int ft991_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int rval; split_t is_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rval = ft991_get_tx_split(rig, &is_split); if (rval != RIG_OK) { return (rval); } if (CACHE(rig)->freqMainB == tx_freq) { rig_debug(RIG_DEBUG_TRACE, "%s: freq %.0f already set on VFOB\n", __func__, tx_freq); return RIG_OK; } if (is_split == RIG_SPLIT_OFF) { rval = newcat_set_tx_vfo(rig, RIG_VFO_B); if (rval != RIG_OK) { return (rval); } } rval = newcat_set_freq(rig, RIG_VFO_B, tx_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s newcat_set_freq() rval = %d freq = %f\n", __func__, rval, tx_freq); return (rval); } int ft991_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int rval; split_t is_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rval = ft991_get_tx_split(rig, &is_split); if (rval != RIG_OK) { return (rval); } if (is_split == RIG_SPLIT_OFF) { *tx_freq = 0.0; return (rval); } rval = newcat_get_freq(rig, RIG_VFO_B, tx_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s newcat_get_freq() rval = %d freq = %f\n", __func__, rval, *tx_freq); return (rval); } /* * rig_get_split_mode* * * Get the '991 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 991 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft991_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct newcat_priv_data *priv; int err; ft991info *rdata; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !tx_mode || !tx_width) { return -RIG_EINVAL; } priv = (struct newcat_priv_data *)STATE(rig)->priv; rdata = (ft991info *)priv->ret_data; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "OI;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } debug_ft991info_data(rdata); *tx_mode = newcat_rmode(rdata->mode); rig_debug(RIG_DEBUG_VERBOSE, "%s opposite mode %s\n", __func__, rig_strrmode(*tx_mode)); *tx_width = RIG_PASSBAND_NORMAL; return RIG_OK; } static void debug_ft991info_data(const ft991info *rdata) { rig_debug(RIG_DEBUG_VERBOSE, "%s command %2.2s\n", __func__, rdata->command); rig_debug(RIG_DEBUG_VERBOSE, "%s memory_ch %3.3s\n", __func__, rdata->memory_ch); rig_debug(RIG_DEBUG_VERBOSE, "%s vfo_freq %9.9s\n", __func__, rdata->vfo_freq); rig_debug(RIG_DEBUG_VERBOSE, "%s clarifier %5.5s\n", __func__, rdata->clarifier); rig_debug(RIG_DEBUG_VERBOSE, "%s rx_clarifier %c\n", __func__, rdata->rx_clarifier); rig_debug(RIG_DEBUG_VERBOSE, "%s tx_clarifier %c\n", __func__, rdata->tx_clarifier); rig_debug(RIG_DEBUG_VERBOSE, "%s mode %c\n", __func__, rdata->mode); rig_debug(RIG_DEBUG_VERBOSE, "%s vfo_memory %c\n", __func__, rdata->vfo_memory); rig_debug(RIG_DEBUG_VERBOSE, "%s tone_mode %c\n", __func__, rdata->tone_mode); rig_debug(RIG_DEBUG_VERBOSE, "%s fixed %2.2s\n", __func__, rdata->fixed); rig_debug(RIG_DEBUG_VERBOSE, "%s repeater_offset %c\n", __func__, rdata->repeater_offset); rig_debug(RIG_DEBUG_VERBOSE, "%s terminator %c\n", __func__, rdata->terminator); } /* * rig_set_split_mode * * Set the '991 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Pass band is not set here nor does it make sense as the * FT991 cannot receive on VFO B. The FT991 cannot set * VFO B mode directly so we'll just set A and swap A * into B but we must preserve the VFO A mode and VFO B * frequency. * */ static int ft991_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct newcat_priv_data *priv; struct rig_state *state; int err; char restore_commands[NEWCAT_DATA_LEN]; split_t is_split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (CACHE(rig)->modeMainB == tx_mode) { rig_debug(RIG_DEBUG_TRACE, "%s: mode %s already set on VFOB\n", __func__, rig_strrmode(tx_mode)); return RIG_OK; } err = ft991_get_tx_split(rig, &is_split); if (err != RIG_OK) { return (err); } if (is_split == RIG_SPLIT_ON) { err = newcat_set_tx_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return (err); } } state = STATE(rig); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); priv = (struct newcat_priv_data *)state->priv; /* append VFO A mode restore command first as we want to minimize any Rx glitches */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MD0;"); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } SNPRINTF(restore_commands, sizeof(restore_commands), "AB;%.*s", (int)sizeof(restore_commands) - 4, priv->ret_data); /* append VFO B frequency restore command */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "FB;"); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } size_t len = strlen(restore_commands); SNPRINTF(restore_commands + len, sizeof(restore_commands) - len, "%.*s", (int)(sizeof(restore_commands) - len - 1), priv->ret_data); /* Change mode on VFOA */ if (RIG_OK != (err = newcat_set_mode(rig, RIG_VFO_A, tx_mode, RIG_PASSBAND_NOCHANGE))) { return err; } /* Send the copy VFO A to VFO B and restore commands */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", restore_commands); return newcat_set_cmd(rig); } static int ft991_init(RIG *rig) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called, version %s\n", __func__, rig->caps->version); ret = newcat_init(rig); if (ret != RIG_OK) { return ret; } STATE(rig)->current_vfo = RIG_VFO_A; return RIG_OK; } static int ft991_find_current_vfo(RIG *rig, vfo_t *vfo, tone_t *enc_dec_mode, rmode_t *mode) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; ft991info *info = (ft991info *)priv->ret_data; int err; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IF;"); /* Get info */ if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } debug_ft991info_data(info); if (enc_dec_mode != NULL) { *enc_dec_mode = info->tone_mode; } if (mode != NULL) { *mode = newcat_rmode(info->mode); } switch (info->vfo_memory) { case '1': // Memory case '2': // Memory Tune case '3': // Quick Memory case '4': // Quick Memory Tune *vfo = RIG_VFO_MEM; break; case '0': // VFO *vfo = RIG_VFO_A; break; default: rig_debug(RIG_DEBUG_BUG, "%s: unexpected vfo returned 0x%X\n", __func__, info->vfo_memory); return -RIG_EINTERNAL; } return RIG_OK; } static int ft991_get_enabled_ctcss_dcs_mode(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0;"); /* Get enabled mode */ if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } return priv->ret_data[3]; } static int ft991_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int i; ncboolean tone_match; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0, tone_match = FALSE; rig->caps->ctcss_list[i] != 0; i++) { if (tone == rig->caps->ctcss_list[i]) { tone_match = TRUE; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: tone = %u, tone_match = %d, i = %d\n", __func__, tone, tone_match, i); if (tone_match == FALSE && tone != 0) { return -RIG_EINVAL; } if (tone == 0) /* turn off ctcss */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN00%3.3d;CT02;", i); } return newcat_set_cmd(rig); } static int ft991_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int ret; int t; int ret_data_len; tone_t enc_dec_mode; rmode_t rmode; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called with vfo %s\n", __func__, rig_strvfo(vfo)); *tone = 0; ret = ft991_find_current_vfo(rig, &vfo, &enc_dec_mode, &rmode); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_TRACE, "%s current vfo is %s\n", __func__, rig_strvfo(vfo)); if (rmode != RIG_MODE_FM && rmode != RIG_MODE_FMN && rmode != RIG_MODE_C4FM) { return RIG_OK; } if ((enc_dec_mode == '0') || // CTCSS and DCS Disabled (enc_dec_mode == '3') || // DCS Encode and Decode Enabled (enc_dec_mode == '4')) // DCS Encode only { return RIG_OK; // Any of the above not CTCSS return 0 } /* Get CTCSS TONE */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN00;"); if (RIG_OK != (ret = newcat_get_cmd(rig))) { return ret; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* tone index */ rig_debug(RIG_DEBUG_TRACE, "%s ctcss code %d\n", __func__, t); if (t < 0 || t > 49) { return -RIG_EINVAL; } *tone = rig->caps->ctcss_list[t]; return RIG_OK; } static int ft991_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; rmode_t rmode; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); err = ft991_find_current_vfo(rig, &vfo, NULL, &rmode); if (err != RIG_OK) { return err; } if (rmode != RIG_MODE_FM && rmode != RIG_MODE_FMN && rmode != RIG_MODE_C4FM) { return -RIG_EINVAL; // Invalid mode for setting ctcss } if (tone == 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { int i; ncboolean tone_match; for (i = 0, tone_match = FALSE; rig->caps->ctcss_list[i] != 0; i++) { if (tone == rig->caps->ctcss_list[i]) { tone_match = TRUE; break; } } if (tone_match == FALSE) { return -RIG_EINVAL; // Tone not on the list } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN0%3.3d;CT01;", i); } return newcat_set_cmd(rig); } static int ft991_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int ret; int t; int ret_data_len; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *tone = 0; ret = ft991_get_enabled_ctcss_dcs_mode(rig); if (ret < 0) { return ret; } if (ret != '1') // If not CTCSS Encode and Decode return tone of zero. { return RIG_OK; } /* Get CTCSS TONE */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN00;"); if (RIG_OK != (ret = newcat_get_cmd(rig))) { return ret; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* tone index */ rig_debug(RIG_DEBUG_TRACE, "%s ctcss code %d\n", __func__, t); if (t < 0 || t > 49) { return -RIG_EINVAL; } *tone = rig->caps->ctcss_list[t]; return RIG_OK; } static int ft991_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int t; tone_t enc_dec_mode; rmode_t rmode; int ret_data_len; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *code = 0; err = ft991_find_current_vfo(rig, &vfo, &enc_dec_mode, &rmode); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s current vfo is %s\n", __func__, rig_strvfo(vfo)); if (rmode != RIG_MODE_FM && rmode != RIG_MODE_FMN && rmode != RIG_MODE_C4FM) { return RIG_OK; } if ((enc_dec_mode == '0') || // Encode off (enc_dec_mode == '1') || // CTCSS Encode and Decode (enc_dec_mode == '2')) // CTCSS Encode Only { return RIG_OK; // Any of the above not DCS return 0 } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01;"); /* Get DCS code */ if (RIG_OK != (err = newcat_get_cmd(rig))) { return err; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* code index */ if (t < 0 || t > 103) { return -RIG_EINVAL; } *code = rig->caps->dcs_list[t]; rig_debug(RIG_DEBUG_TRACE, "%s dcs code %u\n", __func__, *code); return RIG_OK; } static int ft991_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int i; ncboolean code_match; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0, code_match = FALSE; rig->caps->dcs_list[i] != 0; i++) { if (code == rig->caps->dcs_list[i]) { code_match = TRUE; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: code = %u, code_match = %d, i = %d\n", __func__, code, code_match, i); if (code_match == FALSE && code != 0) { return -RIG_EINVAL; } if (code == 0) /* turn off dcs */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01%3.3d;CT04;", i); } return newcat_set_cmd(rig); } static int ft991_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int i; ncboolean code_match; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); for (i = 0, code_match = FALSE; rig->caps->dcs_list[i] != 0; i++) { if (code == rig->caps->dcs_list[i]) { code_match = TRUE; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: code = %u, code_match = %d, i = %d\n", __func__, code, code_match, i); if (code_match == FALSE && code != 0) { return -RIG_EINVAL; } if (code == 0) /* turn off dcs */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT00;"); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01%3.3d;CT03;", i); } return newcat_set_cmd(rig); } static int ft991_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int codeindex; int ret; int ret_data_len; char *retlvl; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); *code = 0; ret = ft991_get_enabled_ctcss_dcs_mode(rig); if (ret < 0) { return ret; } if (ret != '3') { return RIG_OK; // If not DCS Encode and Decode return zero. } /* Get DCS CODE */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN01;"); if (RIG_OK != (ret = newcat_get_cmd(rig))) { return ret; } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; codeindex = atoi(retlvl); /* code index */ rig_debug(RIG_DEBUG_TRACE, "%s dcs code %d\n", __func__, codeindex); if (codeindex < 0 || codeindex > 103) { return -RIG_EINVAL; } *code = rig->caps->dcs_list[codeindex]; return RIG_OK; } // VFO functions so rigctld can be used without --vfo argument static int ft991_set_vfo(RIG *rig, vfo_t vfo) { STATE(rig)->current_vfo = vfo; RETURNFUNC2(RIG_OK); } static int ft991_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = STATE(rig)->current_vfo; RETURNFUNC2(RIG_OK); } hamlib-4.6.2/rigs/yaesu/Makefile.am0000644000175000017500000000177114752216205014040 00000000000000## Process this file with automake to produce Makefile.in ## Yeasu radios that use the legacy CAT commands YAESUSRC = ft100.c ft100.h ft747.c ft747.h ft817.c ft817.h ft847.c ft847.h \ ft890.c ft890.h ft900.c ft900.h ft920.c ft920.h ft1000mp.c ft1000mp.h \ ft857.c ft857.h ft897.c ft897.h ft990.c ft990.h ft990v12.c ft990v12.h frg8800.c ft757gx.c \ ft757gx.h ft600.h ft600.c ft736.c frg100.c frg100.h frg9600.c ft1000d.c \ ft1000d.h vr5000.c ft767gx.c ft767gx.h ft840.c ft840.h ft980.c ft980.h \ vx1700.c vx1700.h ftdx10.h ft710.c pmr171.c ## Yaesu radios that use the new Kenwood style CAT commands NEWCATSRC = newcat.c newcat.h ft450.c ft450.h ft950.c ft950.h ft991.c ft991.h \ ft2000.c ft2000.h ft9000.c ft9000.h ft5000.c ft5000.h ft1200.c ft1200.h \ ft891.c ft891.h ftdx101.c ftdx101.h ftdx101mp.c ft3000.c ftdx10.c ft710.h noinst_LTLIBRARIES = libhamlib-yaesu.la libhamlib_yaesu_la_SOURCES = yaesu.c yaesu.h level_gran_yaesu.h $(YAESUSRC) $(NEWCATSRC) EXTRA_DIST = README.ft890 README.ft920 Android.mk hamlib-4.6.2/rigs/yaesu/Makefile.in0000644000175000017500000007166414752216216014063 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/yaesu ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_yaesu_la_LIBADD = am__objects_1 = ft100.lo ft747.lo ft817.lo ft847.lo ft890.lo ft900.lo \ ft920.lo ft1000mp.lo ft857.lo ft897.lo ft990.lo ft990v12.lo \ frg8800.lo ft757gx.lo ft600.lo ft736.lo frg100.lo frg9600.lo \ ft1000d.lo vr5000.lo ft767gx.lo ft840.lo ft980.lo vx1700.lo \ ft710.lo pmr171.lo am__objects_2 = newcat.lo ft450.lo ft950.lo ft991.lo ft2000.lo \ ft9000.lo ft5000.lo ft1200.lo ft891.lo ftdx101.lo ftdx101mp.lo \ ft3000.lo ftdx10.lo am_libhamlib_yaesu_la_OBJECTS = yaesu.lo $(am__objects_1) \ $(am__objects_2) libhamlib_yaesu_la_OBJECTS = $(am_libhamlib_yaesu_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/frg100.Plo ./$(DEPDIR)/frg8800.Plo \ ./$(DEPDIR)/frg9600.Plo ./$(DEPDIR)/ft100.Plo \ ./$(DEPDIR)/ft1000d.Plo ./$(DEPDIR)/ft1000mp.Plo \ ./$(DEPDIR)/ft1200.Plo ./$(DEPDIR)/ft2000.Plo \ ./$(DEPDIR)/ft3000.Plo ./$(DEPDIR)/ft450.Plo \ ./$(DEPDIR)/ft5000.Plo ./$(DEPDIR)/ft600.Plo \ ./$(DEPDIR)/ft710.Plo ./$(DEPDIR)/ft736.Plo \ ./$(DEPDIR)/ft747.Plo ./$(DEPDIR)/ft757gx.Plo \ ./$(DEPDIR)/ft767gx.Plo ./$(DEPDIR)/ft817.Plo \ ./$(DEPDIR)/ft840.Plo ./$(DEPDIR)/ft847.Plo \ ./$(DEPDIR)/ft857.Plo ./$(DEPDIR)/ft890.Plo \ ./$(DEPDIR)/ft891.Plo ./$(DEPDIR)/ft897.Plo \ ./$(DEPDIR)/ft900.Plo ./$(DEPDIR)/ft9000.Plo \ ./$(DEPDIR)/ft920.Plo ./$(DEPDIR)/ft950.Plo \ ./$(DEPDIR)/ft980.Plo ./$(DEPDIR)/ft990.Plo \ ./$(DEPDIR)/ft990v12.Plo ./$(DEPDIR)/ft991.Plo \ ./$(DEPDIR)/ftdx10.Plo ./$(DEPDIR)/ftdx101.Plo \ ./$(DEPDIR)/ftdx101mp.Plo ./$(DEPDIR)/newcat.Plo \ ./$(DEPDIR)/pmr171.Plo ./$(DEPDIR)/vr5000.Plo \ ./$(DEPDIR)/vx1700.Plo ./$(DEPDIR)/yaesu.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_yaesu_la_SOURCES) DIST_SOURCES = $(libhamlib_yaesu_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ YAESUSRC = ft100.c ft100.h ft747.c ft747.h ft817.c ft817.h ft847.c ft847.h \ ft890.c ft890.h ft900.c ft900.h ft920.c ft920.h ft1000mp.c ft1000mp.h \ ft857.c ft857.h ft897.c ft897.h ft990.c ft990.h ft990v12.c ft990v12.h frg8800.c ft757gx.c \ ft757gx.h ft600.h ft600.c ft736.c frg100.c frg100.h frg9600.c ft1000d.c \ ft1000d.h vr5000.c ft767gx.c ft767gx.h ft840.c ft840.h ft980.c ft980.h \ vx1700.c vx1700.h ftdx10.h ft710.c pmr171.c NEWCATSRC = newcat.c newcat.h ft450.c ft450.h ft950.c ft950.h ft991.c ft991.h \ ft2000.c ft2000.h ft9000.c ft9000.h ft5000.c ft5000.h ft1200.c ft1200.h \ ft891.c ft891.h ftdx101.c ftdx101.h ftdx101mp.c ft3000.c ftdx10.c ft710.h noinst_LTLIBRARIES = libhamlib-yaesu.la libhamlib_yaesu_la_SOURCES = yaesu.c yaesu.h level_gran_yaesu.h $(YAESUSRC) $(NEWCATSRC) EXTRA_DIST = README.ft890 README.ft920 Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/yaesu/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/yaesu/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-yaesu.la: $(libhamlib_yaesu_la_OBJECTS) $(libhamlib_yaesu_la_DEPENDENCIES) $(EXTRA_libhamlib_yaesu_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_yaesu_la_OBJECTS) $(libhamlib_yaesu_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frg100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frg8800.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frg9600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft100.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft1000d.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft1000mp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft1200.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft2000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft3000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft450.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft600.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft736.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft747.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft757gx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft767gx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft817.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft840.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft847.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft857.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft890.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft891.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft897.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft900.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft9000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft920.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft950.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft980.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft990.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft990v12.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ft991.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftdx10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftdx101.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftdx101mp.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newcat.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmr171.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vr5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vx1700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yaesu.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/frg100.Plo -rm -f ./$(DEPDIR)/frg8800.Plo -rm -f ./$(DEPDIR)/frg9600.Plo -rm -f ./$(DEPDIR)/ft100.Plo -rm -f ./$(DEPDIR)/ft1000d.Plo -rm -f ./$(DEPDIR)/ft1000mp.Plo -rm -f ./$(DEPDIR)/ft1200.Plo -rm -f ./$(DEPDIR)/ft2000.Plo -rm -f ./$(DEPDIR)/ft3000.Plo -rm -f ./$(DEPDIR)/ft450.Plo -rm -f ./$(DEPDIR)/ft5000.Plo -rm -f ./$(DEPDIR)/ft600.Plo -rm -f ./$(DEPDIR)/ft710.Plo -rm -f ./$(DEPDIR)/ft736.Plo -rm -f ./$(DEPDIR)/ft747.Plo -rm -f ./$(DEPDIR)/ft757gx.Plo -rm -f ./$(DEPDIR)/ft767gx.Plo -rm -f ./$(DEPDIR)/ft817.Plo -rm -f ./$(DEPDIR)/ft840.Plo -rm -f ./$(DEPDIR)/ft847.Plo -rm -f ./$(DEPDIR)/ft857.Plo -rm -f ./$(DEPDIR)/ft890.Plo -rm -f ./$(DEPDIR)/ft891.Plo -rm -f ./$(DEPDIR)/ft897.Plo -rm -f ./$(DEPDIR)/ft900.Plo -rm -f ./$(DEPDIR)/ft9000.Plo -rm -f ./$(DEPDIR)/ft920.Plo -rm -f ./$(DEPDIR)/ft950.Plo -rm -f ./$(DEPDIR)/ft980.Plo -rm -f ./$(DEPDIR)/ft990.Plo -rm -f ./$(DEPDIR)/ft990v12.Plo -rm -f ./$(DEPDIR)/ft991.Plo -rm -f ./$(DEPDIR)/ftdx10.Plo -rm -f ./$(DEPDIR)/ftdx101.Plo -rm -f ./$(DEPDIR)/ftdx101mp.Plo -rm -f ./$(DEPDIR)/newcat.Plo -rm -f ./$(DEPDIR)/pmr171.Plo -rm -f ./$(DEPDIR)/vr5000.Plo -rm -f ./$(DEPDIR)/vx1700.Plo -rm -f ./$(DEPDIR)/yaesu.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/frg100.Plo -rm -f ./$(DEPDIR)/frg8800.Plo -rm -f ./$(DEPDIR)/frg9600.Plo -rm -f ./$(DEPDIR)/ft100.Plo -rm -f ./$(DEPDIR)/ft1000d.Plo -rm -f ./$(DEPDIR)/ft1000mp.Plo -rm -f ./$(DEPDIR)/ft1200.Plo -rm -f ./$(DEPDIR)/ft2000.Plo -rm -f ./$(DEPDIR)/ft3000.Plo -rm -f ./$(DEPDIR)/ft450.Plo -rm -f ./$(DEPDIR)/ft5000.Plo -rm -f ./$(DEPDIR)/ft600.Plo -rm -f ./$(DEPDIR)/ft710.Plo -rm -f ./$(DEPDIR)/ft736.Plo -rm -f ./$(DEPDIR)/ft747.Plo -rm -f ./$(DEPDIR)/ft757gx.Plo -rm -f ./$(DEPDIR)/ft767gx.Plo -rm -f ./$(DEPDIR)/ft817.Plo -rm -f ./$(DEPDIR)/ft840.Plo -rm -f ./$(DEPDIR)/ft847.Plo -rm -f ./$(DEPDIR)/ft857.Plo -rm -f ./$(DEPDIR)/ft890.Plo -rm -f ./$(DEPDIR)/ft891.Plo -rm -f ./$(DEPDIR)/ft897.Plo -rm -f ./$(DEPDIR)/ft900.Plo -rm -f ./$(DEPDIR)/ft9000.Plo -rm -f ./$(DEPDIR)/ft920.Plo -rm -f ./$(DEPDIR)/ft950.Plo -rm -f ./$(DEPDIR)/ft980.Plo -rm -f ./$(DEPDIR)/ft990.Plo -rm -f ./$(DEPDIR)/ft990v12.Plo -rm -f ./$(DEPDIR)/ft991.Plo -rm -f ./$(DEPDIR)/ftdx10.Plo -rm -f ./$(DEPDIR)/ftdx101.Plo -rm -f ./$(DEPDIR)/ftdx101mp.Plo -rm -f ./$(DEPDIR)/newcat.Plo -rm -f ./$(DEPDIR)/pmr171.Plo -rm -f ./$(DEPDIR)/vr5000.Plo -rm -f ./$(DEPDIR)/vx1700.Plo -rm -f ./$(DEPDIR)/yaesu.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/yaesu/README.ft8900000644000175000017500000000144314752216205013531 00000000000000Quirks, known bugs, and other notes. ==================================== In this document I'll try to describe the behavior of the Yaesu FT-890 transceiver with Hamlib. Some of these are limitations of the radio while others are programming trade-offs with Hamlib. This document is organized by Hamlib function calls and documents observed behavior with each call. rig_set_rit * RIG_VFO_* value is respected so the rig VFO may be changed with this call. * To "zero" the RIT pass a value > 0 or < 10 with this call. The digit will be dropped as resolution is 10 Hz minimum and the clarifier offset set to 0 Hz. General notes. As with most all Yaesu radios the radio must be polled by the application for status updates, i.e. no transceive mode in CAT. hamlib-4.6.2/rigs/yaesu/ft747.c0000644000175000017500000006563714752216205013036 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft747.c - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * This shared library provides an API for communicating * via serial interface to an FT-747GX using the "CAT" interface * box (FIF-232C) or similar * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO - FS * * 1. rationalise code, more helper functions [started] * 2. get_channel, set_func/get_func * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft747.h" /* * Native FT747 functions. This is what I have to work with :-) * */ enum ft747_native_cmd_e { FT_747_NATIVE_SPLIT_OFF = 0, FT_747_NATIVE_SPLIT_ON, FT_747_NATIVE_RECALL_MEM, FT_747_NATIVE_VFO_TO_MEM, FT_747_NATIVE_DLOCK_OFF, FT_747_NATIVE_DLOCK_ON, FT_747_NATIVE_VFO_A, FT_747_NATIVE_VFO_B, FT_747_NATIVE_M_TO_VFO, FT_747_NATIVE_UP_500K, FT_747_NATIVE_DOWN_500K, FT_747_NATIVE_CLARIFY_OFF, FT_747_NATIVE_CLARIFY_ON, FT_747_NATIVE_FREQ_SET, FT_747_NATIVE_MODE_SET_LSB, FT_747_NATIVE_MODE_SET_USB, FT_747_NATIVE_MODE_SET_CWW, FT_747_NATIVE_MODE_SET_CWN, FT_747_NATIVE_MODE_SET_AMW, FT_747_NATIVE_MODE_SET_AMN, FT_747_NATIVE_MODE_SET_FMW, FT_747_NATIVE_MODE_SET_FMN, FT_747_NATIVE_PACING, FT_747_NATIVE_PTT_OFF, FT_747_NATIVE_PTT_ON, FT_747_NATIVE_UPDATE, FT_747_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft747_native_cmd_e ft747_native_cmd_t; /* Internal MODES - when setting modes via cmd_mode_set() */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CWW 0x02 #define MODE_SET_CWN 0x03 #define MODE_SET_AMW 0x04 #define MODE_SET_AMN 0x05 #define MODE_SET_FMW 0x06 #define MODE_SET_FMN 0x07 /* * Mode Bitmap. Bits 5 and 6 unused * When READING modes */ #define MODE_FM 0x01 #define MODE_AM 0x02 #define MODE_CW 0x04 #define MODE_FMN 0x81 #define MODE_AMN 0x82 #define MODE_CWN 0x84 #define MODE_USB 0x08 #define MODE_LSB 0x10 #define MODE_NAR 0x80 /* All relevant bits */ #define MODE_MASK 0x9f /* * Status Flag Masks when reading */ #define SF_DLOCK 0x01 #define SF_SPLIT 0x02 #define SF_CLAR 0x04 #define SF_VFOAB 0x08 #define SF_VFOMR 0x10 #define SF_RXTX 0x20 #define SF_RESV 0x40 #define SF_PRI 0x80 /* * Local VFO CMD's, according to spec */ #define FT747_VFO_A 0x00 #define FT747_VFO_B 0x01 /* * Some useful offsets in the status update map (offset) * * Manual appears to be full of mistakes regarding offsets etc.. -- FS * */ #define FT747_SUMO_DISPLAYED_MEM 0x17 #define FT747_SUMO_DISPLAYED_MODE 0x18 #define FT747_SUMO_DISPLAYED_STATUS 0x00 #define FT747_SUMO_DISPLAYED_FREQ 0x01 #define FT747_SUMO_VFO_A_FREQ 0x09 #define FT747_SUMO_VFO_B_FREQ 0x11 /* * API local implementation */ static int ft747_init(RIG *rig); static int ft747_cleanup(RIG *rig); static int ft747_open(RIG *rig); static int ft747_close(RIG *rig); static int ft747_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft747_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft747_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft747_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft747_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft747_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft747_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft747_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft747_get_split(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft747_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft747_get_mem(RIG *rig, vfo_t vfo, int *ch); /* Private helper function prototypes */ static int ft747_get_update_data(RIG *rig); static int ft747_send_priv_cmd(RIG *rig, unsigned char ci); /* Native ft747 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ft747_ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory*/ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* vfo to memory*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* dial lock = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* dial lock = on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* memory to vfo*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* up 500 khz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* down 500 khz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarify off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* clarify on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* mode set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* mode set CWW */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* mode set CWN */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* mode set AMW */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* mode set AMN */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* mode set FMW */ { 1, { 0x00, 0x00, 0x00, 0x07, 0x0c } }, /* mode set FMN */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* pacing set */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* ptt off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* request update from rig */ }; /* * Receiver caps */ #define FT747_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT747_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT747_AM_RX_MODES (RIG_MODE_AM) #define FT747_FM_RX_MODES (RIG_MODE_FM) /* * TX caps */ #define FT747_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT747_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ /* * no opcode for RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN * TODO: LOCK */ #define FT747_FUNC_ALL (RIG_FUNC_LOCK) #define FT747_VFOS (RIG_VFO_A|RIG_VFO_B) /* * FT747 channel caps. * Last 2 channels don't have split memory */ #define FT747_SPLIT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .split = 1, \ .tx_freq = 1, \ .tx_mode = 1, \ .tx_width = 1, \ .funcs = RIG_FUNC_LOCK, \ } #define FT747_NOSPLIT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .funcs = RIG_FUNC_LOCK, \ } /* * Private data * */ struct ft747_priv_data { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT747_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ struct timeval status_tv; }; /* * ft747 rigs capabilities. * Also this struct is READONLY! */ struct rig_caps ft747_caps = { RIG_MODEL(RIG_MODEL_FT747), .model_name = "FT-747GX", .mfg_name = "Yaesu", .version = "20241108.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT747_WRITE_DELAY, .post_write_delay = FT747_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = FT747_FUNC_ALL, .has_set_func = FT747_FUNC_ALL, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), /* 9999 */ .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 17, RIG_MTYPE_MEM, FT747_SPLIT_MEM_CAP }, { 18, 19, RIG_MTYPE_MEM, FT747_NOSPLIT_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { { .startf = kHz(100), .endf = 29999900, .modes = FT747_ALL_RX_MODES, .low_power = -1, .high_power = -1, .vfo = FT747_VFOS }, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1500), 1999900, FT747_OTHER_TX_MODES, .low_power = 5000, .high_power = 100000, .vfo = FT747_VFOS}, /* 100W class */ {.startf = kHz(1500), .endf = 1999900, FT747_AM_TX_MODES, .low_power = 2000, .high_power = 25000, .vfo = FT747_VFOS}, /* 25W class */ {.startf = kHz(3500), 3999900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = kHz(3500), 3999900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = kHz(7000), 7499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = kHz(7000), 7499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(10), 10499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(10), 10499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(14), 14499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(14), 14499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(18), 18499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(18), 18499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(21), 21499900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(21), 21499900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = kHz(24500), 24999900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = kHz(24500), 24999900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, {.startf = MHz(28), 29999900, FT747_OTHER_TX_MODES, 5000, 100000, FT747_VFOS}, {.startf = MHz(28), 29999900, FT747_AM_TX_MODES, 2000, 25000, FT747_VFOS}, RIG_FRNG_END, }, .tuning_steps = { {FT747_SSB_CW_RX_MODES, 25}, /* fast off */ {FT747_SSB_CW_RX_MODES, 2500}, /* fast on */ {FT747_AM_RX_MODES, kHz(1)}, /* fast off */ {FT747_AM_RX_MODES, kHz(10)}, /* fast on */ {FT747_FM_RX_MODES, kHz(5)}, /* fast off */ {FT747_FM_RX_MODES, 12500}, /* fast on */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(1.8)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* AM filter with narrow selection */ {RIG_MODE_FM, kHz(19)}, /* FM wide filter, with optional FM unit. */ {RIG_MODE_FM, kHz(8)}, /* FM with optional FM unit */ RIG_FLT_END, }, .priv = NULL, /* private data */ .rig_init = ft747_init, .rig_cleanup = ft747_cleanup, .rig_open = ft747_open, /* port opened */ .rig_close = ft747_close, /* port closed */ .set_freq = ft747_set_freq, /* set freq */ .get_freq = ft747_get_freq, /* get freq */ .set_mode = ft747_set_mode, /* set mode */ .get_mode = ft747_get_mode, /* get mode */ .set_vfo = ft747_set_vfo, /* set vfo */ .get_vfo = ft747_get_vfo, /* get vfo */ .set_split_vfo = ft747_set_split, /* set split */ .get_split_vfo = ft747_get_split, /* get split */ .set_ptt = ft747_set_ptt, /* set ptt */ .set_mem = ft747_set_mem, /* set mem */ .get_mem = ft747_get_mem, /* get mem */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * _init * */ int ft747_init(RIG *rig) { STATE(rig)->priv = (struct ft747_priv_data *) calloc(1, sizeof(struct ft747_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } /* * ft747_cleanup routine * the serial port is closed by the frontend */ int ft747_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * ft747_open routine * */ int ft747_open(RIG *rig) { struct rig_state *rig_s; hamlib_port_t *rp = RIGPORT(rig); struct ft747_priv_data *p; int ret; rig_s = STATE(rig); p = (struct ft747_priv_data *)rig_s->priv; rig_debug(RIG_DEBUG_VERBOSE, "ft747:rig_open: write_delay = %i msec \n", rp->write_delay); rig_debug(RIG_DEBUG_VERBOSE, "ft747:rig_open: post_write_delay = %i msec \n", rp->post_write_delay); /* * Copy native cmd PACING to private cmd storage area */ memcpy(&p->p_cmd, &ft747_ncmd[FT_747_NATIVE_PACING].nseq, YAESU_CMD_LENGTH); p->p_cmd[3] = FT747_PACING_DEFAULT_VALUE; /* get pacing value, and store in private cmd */ rig_debug(RIG_DEBUG_VERBOSE, "ft747: read pacing = %i \n", FT747_PACING_DEFAULT_VALUE); /* send PACING cmd to rig, once for all */ ret = write_block(rp, p->p_cmd, YAESU_CMD_LENGTH); if (ret < 0) { return ret; } rig_force_cache_timeout(&p->status_tv); return RIG_OK; } /* * ft747_close routine * */ int ft747_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* * Example of wrapping backend function inside frontend API * */ int ft747_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft747_priv_data *p; unsigned char *cmd; /* points to sequence to send */ // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz \n"; p = (struct ft747_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "ft747: requested freq = %"PRIfreq" Hz vfo = %s \n", freq, rig_strvfo(vfo)); /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&p->p_cmd, &ft747_ncmd[FT_747_NATIVE_FREQ_SET].nseq, YAESU_CMD_LENGTH); /* store bcd format in p_cmd (LSB), round to nearest 10 Hz even though the rig will internally then round to 25 Hz steps */ to_bcd(p->p_cmd, (freq + 5) / 10, 8); rig_debug(RIG_DEBUG_VERBOSE, fmt, __func__, (int64_t)from_bcd(p->p_cmd, 8) * 10); rig_force_cache_timeout(&p->status_tv); cmd = p->p_cmd; /* get native sequence */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } /* * Return Freq for a given VFO */ int ft747_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft747_priv_data *p; struct rig_cache *cachep = CACHE(rig); freq_t f; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s, freqMainA=%.0f, freqMainB=%.0f\n", __func__, rig_strvfo(vfo), cachep->freqMainA, cachep->freqMainB); if (vfo == RIG_VFO_CURR) { vfo = cachep->vfo; } if (cachep->ptt == RIG_PTT_ON) { *freq = RIG_VFO_B ? cachep->freqMainB : cachep->freqMainA; return RIG_OK; } p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } // the leading 2 bytes are zero so we just use 4 bytes for the freq switch (vfo) { case RIG_VFO_CURR: /* grab freq and convert */ f = from_bcd_be(&(p->update_data[FT747_SUMO_DISPLAYED_FREQ]), 8); break; case RIG_VFO_A: f = from_bcd_be(&(p->update_data[FT747_SUMO_VFO_A_FREQ]), 8); break; case RIG_VFO_B: f = from_bcd_be(&(p->update_data[FT747_SUMO_VFO_B_FREQ]), 8); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_VERBOSE, "ft747: freq = %"PRIfreq" Hz for VFO = %s\n", f, rig_strvfo(vfo)); (*freq) = f; /* return displayed frequency */ return RIG_OK; } /* * set mode : eg AM, CW etc for a given VFO * */ int ft747_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ pbwidth_t width_normal; width_normal = rig_passband_normal(rig, mode); if (width == RIG_PASSBAND_NORMAL) { width = width_normal; } /* * translate mode from generic to ft747 specific */ rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s \n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && width < width_normal) { cmd_index = FT_747_NATIVE_MODE_SET_AMN; } else { cmd_index = FT_747_NATIVE_MODE_SET_AMW; } break; case RIG_MODE_CW: if (width != RIG_PASSBAND_NOCHANGE && width < width_normal) { cmd_index = FT_747_NATIVE_MODE_SET_CWN; } else { cmd_index = FT_747_NATIVE_MODE_SET_CWW; } break; case RIG_MODE_USB: cmd_index = FT_747_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: cmd_index = FT_747_NATIVE_MODE_SET_LSB; break; case RIG_MODE_FM: if (width != RIG_PASSBAND_NOCHANGE && width < width_normal) { cmd_index = FT_747_NATIVE_MODE_SET_FMN; } else { cmd_index = FT_747_NATIVE_MODE_SET_FMW; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } rig_debug(RIG_DEBUG_VERBOSE, "ft747: cmd_index = %i \n", cmd_index); rig_force_cache_timeout(&((struct ft747_priv_data *) STATE(rig)->priv)->status_tv); /* * phew! now send cmd to rig */ return ft747_send_priv_cmd(rig, cmd_index); } int ft747_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft747_priv_data *p; unsigned char mymode; /* ft747 mode */ int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } mymode = p->update_data[FT747_SUMO_DISPLAYED_MODE]; mymode &= MODE_MASK; /* mask out bits 5 and 6 */ rig_debug(RIG_DEBUG_VERBOSE, "ft747: mymode = %x \n", mymode); /* * translate mode from ft747 to generic. */ switch (mymode & 0x1f) { case MODE_FM: (*mode) = RIG_MODE_FM; break; case MODE_AM: (*mode) = RIG_MODE_AM; break; case MODE_CW: (*mode) = RIG_MODE_CW; break; case MODE_USB: (*mode) = RIG_MODE_USB; break; case MODE_LSB: (*mode) = RIG_MODE_LSB; break; default: return -RIG_EPROTO; /* sorry, unknown mode */ break; } if (mymode & MODE_NAR) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ int ft747_set_vfo(RIG *rig, vfo_t vfo) { struct ft747_priv_data *p; unsigned char cmd_index; /* index of sequence to send */ p = (struct ft747_priv_data *)STATE(rig)->priv; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_A: cmd_index = FT_747_NATIVE_VFO_A; break; case RIG_VFO_B: cmd_index = FT_747_NATIVE_VFO_B; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_force_cache_timeout(&p->status_tv); return ft747_send_priv_cmd(rig, cmd_index); } int ft747_get_vfo(RIG *rig, vfo_t *vfo) { struct ft747_priv_data *p; unsigned char status; /* ft747 status flag */ int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } status = p->update_data[FT747_SUMO_DISPLAYED_STATUS]; status &= SF_VFOAB; /* check VFO bit*/ rig_debug(RIG_DEBUG_VERBOSE, "ft747: vfo status = %x \n", status); /* * translate vfo status from ft747 to generic. */ if (status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: VFO = B\n", __func__); (*vfo) = RIG_VFO_B; return RIG_OK; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: VFO = A\n", __func__); (*vfo) = RIG_VFO_A; return RIG_OK; } } int ft747_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; /* index of sequence to send */ cmd_index = split == RIG_SPLIT_ON ? FT_747_NATIVE_SPLIT_ON : FT_747_NATIVE_SPLIT_OFF; rig_force_cache_timeout(&((struct ft747_priv_data *) STATE(rig)->priv)->status_tv); return ft747_send_priv_cmd(rig, cmd_index); } int ft747_get_split(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft747_priv_data *p; unsigned char status; /* ft747 status flag */ int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } status = p->update_data[FT747_SUMO_DISPLAYED_STATUS]; if (((status & SF_VFOAB) && (status & SF_RXTX)) || (!(status & SF_VFOAB) && !(status & SF_RXTX))) { *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_ON; } else { *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_OFF; } return RIG_OK; } int ft747_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; /* index of sequence to send */ switch (ptt) { case RIG_PTT_OFF: cmd_index = FT_747_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT_747_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_force_cache_timeout(&((struct ft747_priv_data *) STATE(rig)->priv)->status_tv); /* * phew! now send cmd to rig */ return ft747_send_priv_cmd(rig, cmd_index); } int ft747_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft747_priv_data *p; p = (struct ft747_priv_data *)STATE(rig)->priv; if (ch < 0 || ch > 0x13) { return -RIG_EINVAL; } /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&p->p_cmd, &ft747_ncmd[FT_747_NATIVE_RECALL_MEM].nseq, YAESU_CMD_LENGTH); p->p_cmd[3] = ch; rig_force_cache_timeout(&p->status_tv); return write_block(RIGPORT(rig), p->p_cmd, YAESU_CMD_LENGTH); } int ft747_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft747_priv_data *p; unsigned char mem_nb; int ret; p = (struct ft747_priv_data *)STATE(rig)->priv; ret = ft747_get_update_data(rig); /* get whole shebang from rig */ if (ret < 0) { return ret; } mem_nb = p->update_data[FT747_SUMO_DISPLAYED_MEM]; if (mem_nb > 0x13) { return -RIG_EPROTO; } *ch = mem_nb; return RIG_OK; } /* * private helper function. Retrieves update data from rig. * using buffer indicated in *priv struct. * * need to use this when doing ft747_get_* stuff */ static int ft747_get_update_data(RIG *rig) { hamlib_port_t *rigport; struct ft747_priv_data *p; //unsigned char last_byte; p = (struct ft747_priv_data *)STATE(rig)->priv; rigport = RIGPORT(rig); if (CACHE(rig)->ptt == RIG_PTT_ON || !rig_check_cache_timeout(&p->status_tv, FT747_CACHE_TIMEOUT)) { return RIG_OK; } if (!STATE(rig)->transmit) /* rig doesn't respond in Tx mode */ { int ret; //int port_timeout; rig_flush(rigport); /* send UPDATE command to fetch data*/ ret = ft747_send_priv_cmd(rig, FT_747_NATIVE_UPDATE); if (ret < 0) { return ret; } ret = read_block(rigport, p->update_data, FT747_STATUS_UPDATE_DATA_LENGTH); if (ret < 0) { return ret; } #if 0 // skip this extra byte -- we will flush it before doing a read port_timeout = rigport->timeout; rigport->timeout = 20; /* ms */ /* read sometimes-missing last byte (345th), but don't fail */ read_block(rigport, &last_byte, 1); rigport->timeout = port_timeout; #endif } /* update cache date */ gettimeofday(&p->status_tv, NULL); return RIG_OK; } /* * private helper function to send a private command * sequence . Must only be complete sequences. */ static int ft747_send_priv_cmd(RIG *rig, unsigned char ci) { if (!ft747_ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_VERBOSE, "%s: attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } return write_block(RIGPORT(rig), ft747_ncmd[ci].nseq, YAESU_CMD_LENGTH); } hamlib-4.6.2/rigs/yaesu/ft450.h0000644000175000017500000001051414752216205013012 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft450.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-450 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT450_H #define _FT450_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT450_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ /* FT450 USER-L == RIG_MODE_PKTLSB */ /* FT450 USER-U == RIG_MODE_PKTUSB */ /* */ #define FT450_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define FT450_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT450_AM_RX_MODES (RIG_MODE_AM) #define FT450_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FT450_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT450_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT450_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT450_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT450_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|\ RIG_LEVEL_BAND_SELECT) #define FT450_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_MN|RIG_FUNC_TUNER|\ RIG_FUNC_RIT|RIG_FUNC_XIT\ ) #define FT450_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT450_RFPOWER_METER_CAL \ { \ 6, \ { \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT450_STR_CAL { 3, \ { \ { 10, -60 }, /* S0 */ \ { 125, 0 }, /* S9 */ \ { 240, 60 } /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT450_ANTS 0 #define FT450_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT450_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT450_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT450_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT450_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT450_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT450_PACING_INTERVAL 5 // #define FT450_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-450 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT450_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT450_POST_WRITE_DELAY 5 #endif /* _FT450_H */ hamlib-4.6.2/rigs/yaesu/ft991.h0000644000175000017500000001557614752216205013041 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft991.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT991_H #define _FT991_H 1 #define FT991_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT991_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_C4FM|RIG_MODE_FM|RIG_MODE_AMN|RIG_MODE_FMN) #define FT991_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT991_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FT991_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_C4FM) #define FT991_FM_RX_MODES (FT991_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FT991_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT991_RTTY_DATA_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) /* TRX caps */ #define FT991_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|\ RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */ #define FT991_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FT991_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_BKIN_DLYMS|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT991_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_CSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER|RIG_FUNC_APF) #define FT991_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT991_RFPOWER_METER_CAL \ { \ 7, \ { \ {0, 0.0f}, \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT991_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } #define FT991_ID_CAL { 7, \ { \ { 0, 0.0f }, \ { 53, 5.0f }, \ { 65, 6.0f }, \ { 78, 7.0f }, \ { 86, 8.0f }, \ { 98, 9.0f }, \ { 107, 10.0f } \ } \ } /* TBC */ #define FT991_VD_CAL { 2, \ { \ { 0, 0.0f }, \ { 192, 13.8f }, \ } \ } #define FT991_COMP_CAL { 9, \ { \ { 0, 0.0f }, \ { 40, 2.5f }, \ { 60, 5.0f }, \ { 85, 7.5f }, \ { 135, 10.0f }, \ { 150, 12.5f }, \ { 175, 15.0f }, \ { 195, 17.5f }, \ { 220, 20.0f } \ } \ } /* * Other features (used by rig_caps) * */ // The FT991 does not have antenna selection #define FT991_ANTS (RIG_ANT_CURR) #define FT991_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT991_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT991_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT991_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT991_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT991_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT991_PACING_INTERVAL 5 // #define FT991_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-991 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT991_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT991_POST_WRITE_DELAY 2 typedef struct { char command[2]; /* depends on command "IF", "MR", "MW" "OI" */ char memory_ch[3]; /* 001 -> 117 */ char vfo_freq[9]; /* 9 digit value in Hz */ char clarifier[5]; /* '+' | '-', 0000 -> 9999 Hz */ char rx_clarifier; /* '0' = off, '1' = on */ char tx_clarifier; /* '0' = off, '1' = on */ char mode; /* '1'=LSB, '2'=USB, '3'=CW, '4'=FM, '5'=AM, */ /* '6'=RTTY-LSB, '7'=CW-R, '8'=DATA-LSB, */ /* '9'=RTTY-USB,'A'=DATA-FM, 'B'=FM-N, */ /* 'C'=DATA-USB, 'D'=AM-N, 'E'=C4FM */ char vfo_memory; /* '0'=VFO, '1'=Memory, '2'=Memory Tune, */ /* '3'=Quick Memory Bank, '4'=QMB-MT, '5'=PMS, '6'=HOME */ char tone_mode; /* '0' = off, CTCSS '1' ENC, '2' ENC/DEC, */ /* '3' = DCS ENC/DEC, '4' = ENC */ char fixed[2]; /* Always '0', '0' */ char repeater_offset; /* '0' = Simplex, '1' Plus, '2' minus */ char terminator; /* ';' */ } ft991info; #endif /* _FT991_H */ hamlib-4.6.2/rigs/yaesu/vx1700.h0000644000175000017500000000462514752216205013123 00000000000000/* * Copyright (c) 2010-2011 by Mikhail Kshevetskiy (mikhail.kshevetskiy@gmail.com) * * Code based on VX-1700 CAT manual: * http://www.vertexstandard.com/downloadFile.cfm?FileID=3397&FileCatID=135&FileName=VX-1700_CAT_MANUAL_10_14_2008.pdf&FileContentType=application%2Fpdf * * WARNING: this manual have two errors * 1) Status Update Command (10h), U=01 returns 0..199 for channels 1..200 * 2) Frequency Data (bytes 1--4 of 9-Byte VFO Data Assignment, Status Update * Command (10h), U=02 and U=03) uses bytes 1--3 for frequency, byte 4 is * not used and always zero. Thus bytes 0x15,0xBE,0x68,0x00 means * frequency = 10 * 0x15BE68 = 10 * 1425000 = 14.25 MHz * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _VX1700_H #define _VX1700_H 1 #include #define VX1700_MIN_CHANNEL 1 #define VX1700_MAX_CHANNEL 200 #define VX1700_MODES (RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_SAH) #define VX1700_VFO_ALL (RIG_VFO_A|RIG_VFO_MEM) #define VX1700_ANTS RIG_ANT_1 #define VX1700_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO|RIG_OP_FROM_VFO) #define VX1700_FILTER_WIDTH_NARROW kHz(0.5) #define VX1700_FILTER_WIDTH_WIDE kHz(2.2) #define VX1700_FILTER_WIDTH_SSB kHz(2.2) #define VX1700_FILTER_WIDTH_AM kHz(6.0) /* Returned data length in bytes */ #define VX1700_MEM_CHNL_LENGTH 1 /* 0x10 p1=01 return size */ #define VX1700_OP_DATA_LENGTH 19 /* 0x10 p1=02 return size */ #define VX1700_VFO_DATA_LENGTH 18 /* 0x10 p1=03 return size */ #define VX1700_READ_METER_LENGTH 5 /* 0xf7 return size */ #define VX1700_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define VX1700_BCD_DIAL 8 #endif /* _VX1700_H */ hamlib-4.6.2/rigs/yaesu/ft857.h0000644000175000017500000000452114752216205013026 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft857.h - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * * ...derived but heavily modified from: * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT857_H #define _FT857_H 1 /* * No need to wait between written characters. */ #define FT857_WRITE_DELAY 0 /* * Wait 'delay' milliseconds after writing a command sequence. * * Setting this to zero means no delay but wait for an acknowledgement * from the rig after a command. This is undocumented but seems to work. * It's also the most optimal way as long as it works... * * A non-zero value disables waiting for the ack. Processing a command * seems to take about 60 ms so set this to 80 or so to be safe. */ #define FT857_POST_WRITE_DELAY 0 /* * Read timeout. */ #define FT857_TIMEOUT 200 /* * The time the TX, RX and FREQ/MODE status are cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is deliberately set lower than the time taken to process * a single command (~ 60 ms) so that a sequence * * rig_get_freq(); * rig_set_freq(); * rig_get_freq(); * * doesn't return a bogus (cached) value in the last rig_get_freq(). */ #define FT857_CACHE_TIMEOUT 50 int ft857_set_vfo(RIG *rig, vfo_t vfo); int ft857_get_vfo(RIG *rig, vfo_t *vfo); #endif /* _FT857_H */ hamlib-4.6.2/rigs/yaesu/ft920.h0000644000175000017500000000666514752216205013030 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft920.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003, 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2002 (fillods at users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-920 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT920_H #define _FT920_H 1 #define TRUE 1 #define FALSE 0 #define FT920_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT920_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_WFM) #define FT920_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT920_AM_RX_MODES (RIG_MODE_AM) #define FT920_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_WFM) /* TX caps */ #define FT920_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM ) /* 100 W class */ #define FT920_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ /* Other features */ #define FT920_ANTS 0 /* FIXME: declare Ant A & B and RX input */ #define FT920_FUNC_ALL (RIG_FUNC_TUNER | RIG_FUNC_LOCK) /* fix */ /* Returned data length in bytes */ #define FT920_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT920_STATUS_FLAGS_LENGTH 8 /* 0xfa return size */ #define FT920_VFO_DATA_LENGTH 28 /* 0x10 P1 = 02, 03 return size */ #define FT920_MEM_CHNL_DATA_LENGTH 14 /* 0x10 P1 = 04, P4 = 0x00-0x89 return size */ /* Delay sequential fast writes * * It is thought that it takes the rig about 60 mS to process a command * so a default of 80 mS should be long enough to prevent commands from * stacking up. */ #define FT920_POST_WRITE_DELAY 80 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte rate = 1 byte * in 2.2917 msec => 28 bytes in 64 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 28 bytes * ------------- --------------------- * * 0 64 msec * 1 92 msec * 2 120 msec * 5 204 msec * 255 7.2 sec * */ /* Timing values in mS */ #define FT920_PACING_DEFAULT_VALUE 0 /* time between characters from 920 */ #define FT920_WRITE_DELAY 0 /* time between characters to 920 */ /* Rough safe value for default timeout */ #define FT920_DEFAULT_READ_TIMEOUT 28 * ( 5 + FT920_PACING_DEFAULT_VALUE) /* BCD coded frequency length */ #define FT920_BCD_DIAL 8 #define FT920_BCD_RIT 3 #endif /* _FT920_H */ hamlib-4.6.2/rigs/yaesu/ft920.c0000644000175000017500000023247114752216205013017 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft920.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Nate Bargmann 2002-2005 (n0nb at arrl.net) * (C) Stephane Fillod 2002-2010 (fillods at users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-920 using the "CAT" interface * Documentation can be found online at: * http://www.yaesu.com/amateur/pdf/manuals/ft_920.pdf * pages 86 to 90 * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft920.h" /* * Functions considered to be Stable (2010-01-29): * set_vfo * get_vfo * set_freq * get_freq * set_mode * get_mode * set_split * get_split * set_split_freq * get_split_freq * set_split_mode * get_split_mode * set_rit * get_rit * set_xit * get_xit * set_ptt * get_ptt */ /* * Native FT920 functions. More to come :-) * */ enum ft920_native_cmd_e { FT920_NATIVE_SPLIT_OFF = 0, FT920_NATIVE_SPLIT_ON, FT920_NATIVE_RECALL_MEM, FT920_NATIVE_VFO_TO_MEM, FT920_NATIVE_VFO_A, FT920_NATIVE_VFO_B, FT920_NATIVE_MEM_TO_VFO, FT920_NATIVE_CLARIFIER_OPS, FT920_NATIVE_VFO_A_FREQ_SET, FT920_NATIVE_MODE_SET, FT920_NATIVE_PACING, FT920_NATIVE_PTT_OFF, FT920_NATIVE_PTT_ON, FT920_NATIVE_MEM_CHNL, FT920_NATIVE_OP_DATA, FT920_NATIVE_VFO_DATA, FT920_NATIVE_MEM_CHNL_DATA, FT920_NATIVE_TUNER_BYPASS, FT920_NATIVE_TUNER_INLINE, FT920_NATIVE_TUNER_START, FT920_NATIVE_VFO_B_FREQ_SET, FT920_NATIVE_VFO_A_PASSBAND_WIDE, FT920_NATIVE_VFO_A_PASSBAND_NAR, FT920_NATIVE_VFO_B_PASSBAND_WIDE, FT920_NATIVE_VFO_B_PASSBAND_NAR, FT920_NATIVE_STATUS_FLAGS, FT920_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; /* * Internal MODES - when setting modes via FT920_NATIVE_MODE_SET * */ /* VFO A */ #define MODE_SET_A_LSB 0x00 #define MODE_SET_A_USB 0x01 #define MODE_SET_A_CW_U 0x02 #define MODE_SET_A_CW_L 0x03 #define MODE_SET_A_AM_W 0x04 #define MODE_SET_A_AM_N 0x05 #define MODE_SET_A_FM_W 0x06 #define MODE_SET_A_FM_N 0x07 #define MODE_SET_A_DATA_L 0x08 #define MODE_SET_A_DATA_U 0x0a #define MODE_SET_A_DATA_F 0x0b /* VFO B */ #define MODE_SET_B_LSB 0x80 #define MODE_SET_B_USB 0x81 #define MODE_SET_B_CW_U 0x82 #define MODE_SET_B_CW_L 0x83 #define MODE_SET_B_AM_W 0x84 #define MODE_SET_B_AM_N 0x85 #define MODE_SET_B_FM_W 0x86 #define MODE_SET_B_FM_N 0x87 #define MODE_SET_B_DATA_L 0x88 #define MODE_SET_B_DATA_U 0x8a #define MODE_SET_B_DATA_F 0x8b /* * Internal Clarifier parms - when setting clarifier via * FT920_NATIVE_CLARIFIER_OPS * */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_TX_OFF 0x80 #define CLAR_TX_ON 0x81 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* Tuner status values used to set the * tuner state and indicate tuner status. */ #define TUNER_BYPASS 0 #define TUNER_INLINE 1 #define TUNER_TUNING 2 /* * Local VFO CMD's, according to spec * */ //#define FT920_VFO_A 0x00 //#define FT920_VFO_B 0x01 /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA, P1 = 01 requests the FT-920 to return its status flags. * These flags consist of 8 bytes and are documented in the FT-920 manual * on page 89. * */ #define FT920_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_VFOA 0x00 /* bits 0 & 1, VFO A TX/RX == 0 */ #define SF_SPLITA (1<<0) /* Split operation with VFO-B on TX */ #define SF_SPLITB (1<<1) /* Split operation with VFO-B on RX */ #define SF_VFOB (SF_SPLITA|SF_SPLITB) /* bits 0 & 1, VFO B TX/RX == 3 */ #define SF_TUNER_TUNE (1<<2) /* Antenna tuner On and Tuning for match*/ #define SF_PTT_OFF (0<<7) /* Receive mode (PTT line open) */ #define SF_PTT_ON (1<<7) /* Transmission in progress (PTT line grounded) */ #define SF_PTT_MASK (SF_PTT_ON) #define FT920_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define SF_QMB (1<<3) /* Quick Memory Bank (QMB) selected */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_VFO (1<<5) /* VFO operation selected */ #define SF_MR (1<<6) /* Memory Mode selected */ #define SF_GC (1<<7) /* General Coverage Reception selected */ #define SF_VFO_MASK (SF_QMB|SF_MT|SF_VFO|SF_MR) #define FT920_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 2 */ #define SF_TUNER_INLINE (1<<1) /* Antenna tuner is inline or bypass */ #define SF_VFOB_LOCK (1<<2) /* VFO B tuning lock status */ #define SF_VFOA_LOCK (1<<3) /* VFO A tuning lock status */ /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03 * * The FT-920 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (28 bytes) * CAT command 0x10, P1 = 03 returns VFO A data and the sub display data (sub display is always VFO B) (28 bytes) * CAT command 0x10, P1 = 04, P4 = 0x00-0x89 returns memory channel data (14 bytes) * In all cases the format is (from the FT-920 manual page 90): * * Offset Value * 0x00 Band Selection (not documented!) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x05 Clarifier Offset (Hex value) * 0x07 Mode Data * 0x08 Flag * 0x09 Filter Data 1 * 0x0a Filter Data 2 * 0x0b CTCSS Encoder Data * 0x0c CTCSS Decoder Data * 0x0d Memory recall Flag * * Memory Channel data has the same layout and offsets * VFO B data has the same layout, but the offset starts at 0x0e and * continues through 0x1b * */ #define FT920_SUMO_DISPLAYED_FREQ 0x01 /* Current main display, can be VFO A, Memory data, Memory tune */ #define FT920_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT920_SUMO_DISPLAYED_CLAR 0x05 /* RIT/XIT offset -- current display */ #define FT920_SUMO_VFO_A_CLAR 0x05 /* RIT/XIT offset -- VFO A */ #define FT920_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT920_SUMO_VFO_A_MODE 0x07 /* VFO A mode, not necessarily currently displayed! */ #define FT920_SUMO_VFO_B_FREQ 0x0f /* Current sub display && VFO B */ #define FT920_SUMO_VFO_B_CLAR 0x13 /* RIT/XIT offset -- VFO B */ #define FT920_SUMO_VFO_B_MODE 0x15 /* Current sub display && VFO B */ /* * Mode Bitmap from offset 0x07 or 0x16 in VFO Record. * Bits 5 and 6 ignored * used when READING modes from FT-920 * */ #define MODE_LSB 0x00 #define MODE_CW_L 0x01 /* CW listening on LSB */ #define MODE_AM 0x02 #define MODE_FM 0x03 #define MODE_DATA_L 0x04 /* DATA on LSB */ #define MODE_DATA_U 0x05 /* DATA on USB (who does that? :) */ #define MODE_DATA_F 0x06 /* DATA on FM */ #define MODE_USB 0x40 #define MODE_CW_U 0x41 /* CW listening on USB */ /* Narrow filter selected */ #define MODE_LSBN 0x80 /* Not sure this actually exists */ #define MODE_CW_LN 0x81 #define MODE_AMN 0x82 #define MODE_FMN 0x83 #define MODE_DATA_LN 0x84 #define MODE_DATA_UN 0x85 #define MODE_DATA_FN 0x86 #define MODE_USBN 0xc0 /* Not sure this actually exists */ #define MODE_CW_UN 0xc1 /* All relevant bits */ #define MODE_MASK 0xc7 /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 /* * API local implementation * */ static int ft920_init(RIG *rig); static int ft920_cleanup(RIG *rig); static int ft920_open(RIG *rig); static int ft920_close(RIG *rig); static int ft920_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft920_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft920_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft920_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft920_set_vfo(RIG *rig, vfo_t vfo); static int ft920_get_vfo(RIG *rig, vfo_t *vfo); static int ft920_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft920_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft920_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft920_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int ft920_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft920_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft920_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft920_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft920_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft920_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); /* not documented in my FT-920 manual, but it works! - N0NB */ static int ft920_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft920_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft920_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft920_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); /* Private helper function prototypes */ static int ft920_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft920_send_static_cmd(RIG *rig, unsigned char ci); static int ft920_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft920_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft920_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); /* * Native ft920 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set vfo A freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (28 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (28 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (14 bytes) P4 = 0x00-0x89 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* Tuner bypass */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* Tuner inline */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* Tuner start tuning for match */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* set vfo B frequency */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8c } }, /* VFO A wide filter */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x8c } }, /* VFO A narrow filter */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x8c } }, /* VFO B wide filter */ { 1, { 0x00, 0x00, 0x00, 0x82, 0x8c } }, /* VFO B narrow filter */ { 1, { 0x00, 0x00, 0x00, 0x01, 0xFA } }, /* Read status flags */ /* { 0, { 0x00, 0x00, 0x00, 0x00, 0x70 } }, */ /* keyer commands */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft920_caps.priv? I'm guessing not as it's private to the backend. -N0NB */ struct ft920_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ vfo_t split_vfo; /* TX VFO in split mode */ split_t split; /* split active or not */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT920_VFO_DATA_LENGTH]; /* returned data--max value, some are less */ }; /* * ft920 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft920_caps = { RIG_MODEL(RIG_MODEL_FT920), .model_name = "FT-920", .mfg_name = "Yaesu", .version = "20220060.0", /* YYYYMMDD */ .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT920_WRITE_DELAY, .post_write_delay = FT920_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = FT920_FUNC_ALL, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .announces = RIG_ANN_NONE, .vfo_ops = RIG_OP_NONE, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 122 (!) */ .rx_range_list1 = { {kHz(100), MHz(30), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, /* General coverage + ham */ {MHz(48), MHz(56), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, /* 6m! */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_HF(1, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ FRQ_RNG_6m(1, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_6m(1, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, {MHz(48), MHz(56), FT920_ALL_RX_MODES, -1, -1, FT920_VFO_ALL, FT920_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_HF(2, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ FRQ_RNG_6m(2, FT920_OTHER_TX_MODES, W(5), W(100), FT920_VFO_ALL, FT920_ANTS), FRQ_RNG_6m(2, FT920_AM_TX_MODES, W(2), W(25), FT920_VFO_ALL, FT920_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT920_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT920_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT920_AM_RX_MODES, Hz(100)}, /* Normal */ {FT920_AM_RX_MODES, kHz(1)}, /* Fast */ {FT920_FM_RX_MODES, Hz(100)}, /* Normal */ {FT920_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-920 has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.4)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(15)}, /* normal AM filter (stock radio has no AM filter!) */ {RIG_MODE_AM, kHz(2.4)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM with optional FM unit */ {RIG_MODE_WFM, kHz(12)}, /* WideFM, with optional FM unit. */ {RIG_MODE_PKTLSB, kHz(1.8)},/* Alias of MODE_DATA_L */ {RIG_MODE_PKTLSB, kHz(0.5)},/* Alias of MODE_DATA_LN */ {RIG_MODE_PKTUSB, kHz(2.4)}, /* Alias for MODE DATA_U */ {RIG_MODE_PKTUSB, kHz(0.5)},/* Alias of MODE_DATA_UN */ {RIG_MODE_PKTFM, kHz(12)}, /* Alias for MODE_DATA _F */ {RIG_MODE_PKTFM, kHz(6)}, /* Alias for MODE_DATA_FN */ RIG_FLT_END, }, .str_cal = EMPTY_STR_CAL, .cfgparams = NULL, .priv = NULL, /* private data FIXME: ?? */ .rig_init = ft920_init, .rig_cleanup = ft920_cleanup, .rig_open = ft920_open, /* port opened */ .rig_close = ft920_close, /* port closed */ .set_freq = ft920_set_freq, .get_freq = ft920_get_freq, .set_mode = ft920_set_mode, .get_mode = ft920_get_mode, .set_vfo = ft920_set_vfo, .get_vfo = ft920_get_vfo, .set_ptt = ft920_set_ptt, .get_ptt = ft920_get_ptt, .get_dcd = NULL, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_split_freq = ft920_set_split_freq, .get_split_freq = ft920_get_split_freq, .set_split_mode = ft920_set_split_mode, .get_split_mode = ft920_get_split_mode, .set_split_vfo = ft920_set_split_vfo, .get_split_vfo = ft920_get_split_vfo, .set_rit = ft920_set_rit, .get_rit = ft920_get_rit, .set_xit = ft920_set_xit, .get_xit = ft920_get_xit, .set_ts = NULL, .get_ts = NULL, .set_dcs_code = NULL, .get_dcs_code = NULL, .set_tone = NULL, .get_tone = NULL, .set_ctcss_tone = NULL, .get_ctcss_tone = NULL, .set_dcs_sql = NULL, .get_dcs_sql = NULL, .set_tone_sql = NULL, .get_tone_sql = NULL, .set_ctcss_sql = NULL, .get_ctcss_sql = NULL, .power2mW = NULL, .mW2power = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .reset = NULL, .set_ant = NULL, .get_ant = NULL, .set_level = NULL, .get_level = NULL, .set_func = ft920_set_func, .get_func = ft920_get_func, .set_parm = NULL, .get_parm = NULL, .set_ext_level = NULL, .get_ext_level = NULL, .set_ext_parm = NULL, .get_ext_parm = NULL, .set_conf = NULL, .get_conf = NULL, .send_dtmf = NULL, .recv_dtmf = NULL, .send_morse = NULL, .set_bank = NULL, .set_mem = NULL, .get_mem = NULL, .vfo_op = NULL, .scan = NULL, .set_trn = NULL, .get_trn = NULL, .decode_event = NULL, .set_channel = NULL, .get_channel = NULL, .get_info = NULL, .set_chan_all_cb = NULL, .get_chan_all_cb = NULL, .set_mem_all_cb = NULL, .get_mem_all_cb = NULL, .clone_combo_set = NULL, .clone_combo_get = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init* * */ static int ft920_init(RIG *rig) { struct ft920_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft920_priv_data *) calloc(1, sizeof(struct ft920_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; /* whoops! memory shortage! */ } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT920_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_A; /* default to VFO_A */ return RIG_OK; } /* * rig_cleanup* * * the serial port is closed by the frontend * */ static int ft920_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open* * */ static int ft920_open(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, rp->post_write_delay); /* Copy native cmd PACING to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[FT920_NATIVE_PACING].nseq, YAESU_CMD_LENGTH); /* get pacing value, and store in private cmd */ priv->p_cmd[P1] = priv->pacing; rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = write_block(rp, priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } /* TODO: more initialization as necessary */ return RIG_OK; } /* * rig_close* * */ static int ft920_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set freq for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * freq | input | frequency to passed VFO * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: If vfo is set to RIG_VFO_CUR then vfo from * priv_data is used. * */ static int ft920_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft920_priv_data *priv; int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: /* force main display to VFO */ case RIG_VFO_VFO: err = ft920_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A_FREQ_SET; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B_FREQ_SET; break; default: return -RIG_EINVAL; /* sorry, unsupported VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = 0x%02x\n", __func__, cmd_index); err = ft920_send_dial_freq(rig, cmd_index, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq* * * Return Freq for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * *freq | output | displayed frequency based on passed VFO * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * */ static int ft920_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft920_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_A_FREQ; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_VFO_B_FREQ; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_DISPLAYED_FREQ; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft920_get_update_data(rig, cmd_index, FT920_VFO_DATA_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (((((p[0] << 8) + p[1]) << 8) + p[2]) << 8) + p[3]; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode* * * Set mode and passband: eg AM, CW etc for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * mode | input | supported modes (see ft920.h) * width | input | supported widths (see ft920.h) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: If vfo is set to RIG_VFO_CUR then vfo from * priv_data is used. * */ static int ft920_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft920_priv_data *priv; unsigned char cmd_index = FT920_NATIVE_VFO_A_PASSBAND_WIDE; /* index of sequence to send */ unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft920 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft920_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_A_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_A_CW_U; break; case RIG_MODE_USB: mode_parm = MODE_SET_A_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_A_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_A_FM_W; break; case RIG_MODE_RTTY: mode_parm = MODE_SET_A_DATA_L; break; case RIG_MODE_PKTLSB: mode_parm = MODE_SET_A_DATA_L; break; case RIG_MODE_PKTUSB: mode_parm = MODE_SET_A_DATA_U; break; case RIG_MODE_PKTFM: mode_parm = MODE_SET_A_DATA_F; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } break; /* Now VFO B */ case RIG_VFO_B: case RIG_VFO_SUB: switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_B_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_B_CW_U; break; case RIG_MODE_USB: mode_parm = MODE_SET_B_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_B_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_B_FM_W; break; case RIG_MODE_RTTY: mode_parm = MODE_SET_B_DATA_L; break; case RIG_MODE_PKTLSB: mode_parm = MODE_SET_B_DATA_L; break; case RIG_MODE_PKTUSB: mode_parm = MODE_SET_B_DATA_U; break; case RIG_MODE_PKTFM: mode_parm = MODE_SET_B_DATA_F; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-920 doesn't appear to support narrow width in USB or LSB modes * * Yeah, it's ugly... -N0NB * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == RIG_PASSBAND_NORMAL || width == rig_passband_normal(rig, mode)) { switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A_PASSBAND_WIDE; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B_PASSBAND_WIDE; break; } } else { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_RTTY: switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A_PASSBAND_NAR; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B_PASSBAND_NAR; break; } break; default: return -RIG_EINVAL; /* Invalid mode; how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width; how can caller know? */ } } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft920_send_dynamic_cmd(rig, FT920_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; /* Whew! */ } /* * rig_get_mode* * * Get mode and passband: eg AM, CW etc for a given VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * *mode | output | supported modes (see ft920.h) * *width | output | supported widths (see ft920.h) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * */ static int ft920_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft920_priv_data *priv; unsigned char mymode, offset; /* ft920 mode, flag offset */ int err, cmd_index, norm; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_DISPLAYED_MODE; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_B_MODE; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_DISPLAYED_MODE; break; default: return -RIG_EINVAL; } err = ft920_get_update_data(rig, cmd_index, FT920_VFO_DATA_LENGTH); if (err != RIG_OK) { return err; } mymode = priv->update_data[offset]; mymode &= MODE_MASK; rig_debug(RIG_DEBUG_TRACE, "%s: mymode = 0x%02x\n", __func__, mymode); /* * translate mode from ft920 to generic. * * FIXME: FT-920 has 3 DATA modes, LSB, USB, and FM * do we need more bit fields in rmode_t? -N0NB * */ switch (mymode) { case MODE_USBN: /* not sure this even exists */ *mode = RIG_MODE_USB; norm = FALSE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_LSBN: /* not sure this even exists */ *mode = RIG_MODE_LSB; norm = FALSE; break; case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_CW_UN: case MODE_CW_LN: *mode = RIG_MODE_CW; norm = FALSE; break; case MODE_CW_U: case MODE_CW_L: *mode = RIG_MODE_CW; norm = TRUE; break; case MODE_AMN: *mode = RIG_MODE_AM; norm = FALSE; break; case MODE_AM: *mode = RIG_MODE_AM; norm = TRUE; break; case MODE_FMN: *mode = RIG_MODE_FM; norm = FALSE; break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; case MODE_DATA_LN: *mode = RIG_MODE_PKTLSB; norm = FALSE; break; case MODE_DATA_L: *mode = RIG_MODE_PKTLSB; norm = TRUE; break; case MODE_DATA_UN: *mode = RIG_MODE_PKTUSB; norm = FALSE; break; case MODE_DATA_U: *mode = RIG_MODE_PKTUSB; norm = TRUE; break; case MODE_DATA_F: *mode = RIG_MODE_PKTFM; norm = TRUE; break; case MODE_DATA_FN: *mode = RIG_MODE_PKTFM; norm = FALSE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo* * * Get active VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | RIG_VFO_A, RIG_VFO_B * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Set vfo and store requested vfo for later * RIG_VFO_CURR requests. * */ static int ft920_set_vfo(RIG *rig, vfo_t vfo) { struct ft920_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_B; priv->current_vfo = vfo; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo* * * Get active VFO * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * *vfo | output | RIG_VFO_A, RIG_VFO_B, RIG_VFO_MEM * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested * vfo/mem back to the frontend. * */ static int ft920_get_vfo(RIG *rig, vfo_t *vfo) { struct ft920_priv_data *priv; unsigned char status_0; /* ft920 status flag 0 */ unsigned char status_1; /* ft920 status flag 1 */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; status_0 &= SF_VFOB; /* get VFO B (sub display) active bits */ status_1 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_1]; status_1 &= SF_VFO_MASK; /* get VFO/MEM (main display) active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, status_1); /* * translate vfo status from ft920 to generic. * * Figuring out whether VFO B is the active RX vfo is tough as * Status Flag 0 bits 0 & 1 contain this information. Testing * Status Flag 1 only gives us the state of the main display. * */ switch (status_0) { case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; case SF_SPLITB: /* Split operation, RX on VFO B */ *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; } /* * Okay now test for the active MEM/VFO status of the main display * */ switch (status_1) { case SF_QMB: case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; break; case SF_VFO: switch (status_0) { case SF_SPLITA: /* Split operation, RX on VFO A */ *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; } break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_split_vfo* * * Set the '920 into split TX/RX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | not used * split | input | RIG_SPLIT_ON, RIG_SPLIT_OFF * tx_vfo | input | VFO to use for TX (not used) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: VFO cannot be set as the set split_on command only * changes the TX to the sub display. Setting split off * returns the TX to the main display. * */ static int ft920_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); switch (tx_vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: case RIG_VFO_VFO: break; case RIG_VFO_B: case RIG_VFO_SUB: break; default: return -RIG_EINVAL; } switch (split) { case RIG_SPLIT_OFF: cmd_index = FT920_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT920_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get whether the '920 is in split mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | not used * *split | output | RIG_SPLIT_ON, RIG_SPLIT_OFF * *tx_vfo | output | not used * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * */ static int ft920_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft920_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; status_0 &= SF_VFOB; /* get VFO B (sub display) active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLITA: /* VFOB (sub display) is TX Got that? */ *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_ON; break; case SF_SPLITB: /* VFOA is TX */ *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_ON; break; case SF_VFOA: *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_OFF; break; case SF_VFOB: *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_OFF; break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_split_freq* * * Set the '920 split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_freq | input | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if 920 is in split mode and if so sets * the frequency of the TX VFO. If not in split mode * does nothing and returns. * */ static int ft920_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, tx_freq); err = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (err != RIG_OK) { return err; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_set_freq(rig, priv->split_vfo, tx_freq); if (err != RIG_OK) { return err; } break; default: break; } return RIG_OK; } /* * rig_get_split_freq* * * Get the '920 split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_freq | output | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 920 is in split mode, if so it * checks which VFO is set for TX and then gets the * frequency of that VFO and stores it into *tx_freq. * If not in split mode returns 0 Hz. * */ static int ft920_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_get_freq(rig, priv->split_vfo, tx_freq); if (err != RIG_OK) { return err; } break; default: *tx_freq = 0; break; } return RIG_OK; } /* * rig_set_split_mode * * Set the '920 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if 920 is in split mode and if so sets * the mode and passband of the TX VFO. If not in split mode * does nothing and returns. * */ static int ft920_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_set_mode(rig, priv->split_vfo, tx_mode, tx_width); if (err != RIG_OK) { return err; } break; default: break; } return RIG_OK; } /* * rig_get_split_mode* * * Get the '920 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 920 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft920_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* '920 is in split mode */ err = ft920_get_mode(rig, priv->split_vfo, tx_mode, tx_width); if (err != RIG_OK) { return err; } break; default: *tx_mode = RIG_MODE_NONE; *tx_width = 0; break; } return RIG_OK; } /* * rig_set_rit* * * Set the RIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: vfo is ignored as RIT cannot be changed on sub VFO * * FIXME: Should rig be forced into VFO mode if RIG_VFO_A * or RIG_VFO_VFO is received? * * VFO and MEM rit values are independent. The sub display * carries an RIT value only if A<>B button is pressed or * set_vfo is called with RIG_VFO_B and the main display has * an RIT value. */ static int ft920_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); if (rit == 0) { offset = CLAR_RX_OFF; } else { offset = CLAR_RX_ON; } rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft920_send_dynamic_cmd(rig, FT920_NATIVE_CLARIFIER_OPS, offset, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft920_send_rit_freq(rig, FT920_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rit* * * Get the RIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *rit | output | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Value of vfo is ignored as it's not needed. * * Rig returns offset as hex from 0x0000 to 0x270f for * 0 to +9999 Hz and 0xffff to 0xd8f1 for -1 to -9999 Hz * * VFO and MEM rit values are independent. The sub display * carries an RIT value only if A<>B button is pressed or * set_vfo is called with RIG_VFO_B and the main display has * an RIT value. */ static int ft920_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft920_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft920_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT920_NATIVE_OP_DATA; offset = FT920_SUMO_DISPLAYED_CLAR; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_A_CLAR; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd_index = FT920_NATIVE_VFO_DATA; offset = FT920_SUMO_VFO_B_CLAR; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft920_get_update_data(rig, cmd_index, FT920_VFO_DATA_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; if (f > 0xd8f0) /* 0xd8f1 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f); *rit = f; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_xit * * Set the XIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: vfo is ignored as XIT cannot be changed on sub VFO * * FIXME: Should rig be forced into VFO mode if RIG_VFO_A * or RIG_VFO_VFO is received? */ static int ft920_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed xit = %li\n", __func__, xit); if (xit == 0) { offset = CLAR_TX_OFF; } else { offset = CLAR_TX_ON; } rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft920_send_dynamic_cmd(rig, FT920_NATIVE_CLARIFIER_OPS, offset, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft920_send_rit_freq(rig, FT920_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_xit* * * Get the XIT offset * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *xit | output | -9999 to 9999 Hz * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Value of vfo is ignored as it's not needed * * Rig returns offset as hex from 0x0000 to 0x270f for * 0 to +9999 Hz and 0xffff to 0xd8f1 for -1 to -9999 Hz */ static int ft920_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } err = ft920_get_rit(rig, vfo, xit); /* abuse get_rit and store in *xit */ if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_ptt* * * Set the '920 into TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | RIG_PTT_OFF, RIG_PTT_ON * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: vfo is respected by calling ft920_set_vfo if * passed vfo != priv->current_vfo * * This command is not documented in my '920 manual, * but it works! -N0NB * */ static int ft920_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft920_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft920_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT920_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT920_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } hl_usleep(200 * 1000); // give the rig some time before we try set_freq return RIG_OK; } /* * rig_get_ptt* * * Get current PTT status * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *ptt | output | RIG_PTT_OFF, RIG_PTT_ON * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Get the PTT state */ static int ft920_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft920_priv_data *priv; unsigned char stat_0; /* ft920 status flag 0 */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* * The FT-920 status gives two flags for PTT, one if the PTT * line is grounded externally and the other if the PTT line * is grounded as the result of a CAT command. However, the * 7th bit of status byte 0 is set or cleared in each case * and gives an accurate state of the PTT line. */ stat_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; stat_0 &= SF_PTT_MASK; /* get external PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: stat_0 = 0x%02x\n", __func__, stat_0); switch (stat_0) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | TUNER * status | input | 0 = bypass, 1 =inline, 2 = start tuning * | | (toggle) * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Set the tuner to on, off, or start */ static int ft920_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct ft920_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s, func = %s, status = %d\n", __func__, rig_strvfo(vfo), rig_strfunc(func), status); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft920_set_vfo(rig, vfo); } switch (func) { case RIG_FUNC_TUNER: switch (status) { case TUNER_BYPASS: cmd_index = FT920_NATIVE_TUNER_BYPASS; break; case TUNER_INLINE: cmd_index = FT920_NATIVE_TUNER_INLINE; break; case TUNER_TUNING: cmd_index = FT920_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; /* wrong tuner status! */ } break; default: return -RIG_EINVAL; /* wrong function! */ } err = ft920_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get rig function * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | TUNER * *status | output | 0 = bypass, 1 = inline, 2 = tuning * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Read the tuner status from status flags */ static int ft920_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft920_priv_data *priv; unsigned char stat_0, stat_2; /* ft920 status flags 0, 2 */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s, func = %s\n", __func__, rig_strvfo(vfo), rig_strfunc(func)); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft920_set_vfo(rig, vfo); } /* Get flags for VFO status */ err = ft920_get_update_data(rig, FT920_NATIVE_STATUS_FLAGS, FT920_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* * The FT-920 status gives three flags for the tuner state, * one if the tuner is On/tuning, another if the tuner is * "inline" and the last if the "WAIT" light is on. * * Currently, will only check if tuner is tuning and inline. */ stat_0 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_0]; // stat_0 &= SF_TUNER_TUNE; /* get tuning state */ stat_2 = priv->update_data[FT920_SUMO_DISPLAYED_STATUS_2]; // stat_2 &= SF_TUNER_INLINE; /* get tuner inline state */ rig_debug(RIG_DEBUG_TRACE, "%s: stat_0 = 0x%02x, stat_2 = 0x%02x\n", __func__, stat_0, stat_2); switch (func) { case RIG_FUNC_TUNER: if (stat_0 & SF_TUNER_TUNE) { *status = TUNER_TUNING; } else if (stat_2 & SF_TUNER_INLINE) { *status = TUNER_INLINE; } else { *status = TUNER_BYPASS; } break; case RIG_FUNC_LOCK: switch (vfo) { case RIG_VFO_A: if (stat_2 & SF_VFOA_LOCK) { *status = TRUE; } else { *status = FALSE; } break; case RIG_VFO_B: if (stat_2 & SF_VFOB_LOCK) { *status = TRUE; } else { *status = FALSE; } break; } break; default: return -RIG_EINVAL; /* wrong function! */ } return RIG_OK; } /* * ************************************ * * Private functions to ft920 backend * * ************************************ */ /* * Private helper function to retrieve update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 920 has several ways to * get data and several ways to return it. * * Need to use this when doing ft920_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft920_priv_data *priv; int n; /* for read_ */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft920_priv_data *)STATE(rig)->priv; err = ft920_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } /* * If we've been passed a command index (ci) that is marked * as dynamic (0), then bail out. */ if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft920_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* * If we've been passed a command index (ci) that is marked * as static (1), then bail out. */ if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempted to modify a complete command sequence: %i\n", __func__, ci); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the Main or Sub display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft920_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft920_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* * If we've been passed a command index (ci) that is marked * as static (1), then bail out. */ if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT920_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT920_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT/XIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ static int ft920_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft920_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft920_priv_data *)STATE(rig)->priv; /* * If we've been passed a command index (ci) that is marked * as static (1), then bail out. */ if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT920_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %d Hz\n", __func__, (int)from_bcd(priv->p_cmd, FT920_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft600.c0000644000175000017500000004313014752216205013002 00000000000000/* * hamlib - (C) Frank Singleton 2000-2003 * (C) Stephane Fillod 2000-2010 * * ft600.c -(C) KÄrlis Millers YL3ALK 2019 * * This shared library provides an API for communicating * via serial interface to an FT-600 using the "CAT" interface. * The starting point for this code was Chris Karpinsky's ft100 implementation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft600.h" #include "misc.h" #include "bandplan.h" enum ft600_native_cmd_e { FT600_NATIVE_CAT_LOCK_ON = 0, FT600_NATIVE_CAT_LOCK_OFF, FT600_NATIVE_CAT_PTT_ON, FT600_NATIVE_CAT_PTT_OFF, FT600_NATIVE_CAT_SET_FREQ, FT600_NATIVE_CAT_SET_MODE_LSB, FT600_NATIVE_CAT_SET_MODE_USB, FT600_NATIVE_CAT_SET_MODE_DIG, FT600_NATIVE_CAT_SET_MODE_CW, FT600_NATIVE_CAT_SET_MODE_AM, FT600_NATIVE_CAT_CLAR_ON, FT600_NATIVE_CAT_CLAR_OFF, FT600_NATIVE_CAT_SET_CLAR_FREQ, FT600_NATIVE_CAT_SET_VFOAB, FT600_NATIVE_CAT_SET_VFOA, FT600_NATIVE_CAT_SET_VFOB, FT600_NATIVE_CAT_SPLIT_ON, FT600_NATIVE_CAT_SPLIT_OFF, FT600_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT600_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT600_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT600_NATIVE_CAT_SET_RPT_OFFSET, /* fix me */ FT600_NATIVE_CAT_SET_DCS_ON, FT600_NATIVE_CAT_SET_CTCSS_ENC_ON, FT600_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON, FT600_NATIVE_CAT_SET_CTCSS_DCS_OFF, /* em xif */ FT600_NATIVE_CAT_SET_CTCSS_FREQ, FT600_NATIVE_CAT_SET_DCS_CODE, FT600_NATIVE_CAT_GET_RX_STATUS, FT600_NATIVE_CAT_GET_TX_STATUS, FT600_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT600_NATIVE_CAT_PWR_WAKE, FT600_NATIVE_CAT_PWR_ON, FT600_NATIVE_CAT_PWR_OFF, FT600_NATIVE_CAT_READ_STATUS, FT600_NATIVE_CAT_READ_METERS, FT600_NATIVE_CAT_READ_FLAGS }; /* * we are able to get way more info * than we can set * */ typedef struct { // unsigned char band_no; unsigned char freq[16]; // unsigned char mode; // unsigned char ctcss; // unsigned char dcs; // unsigned char flag1; // unsigned char flag2; // unsigned char clarifier[2]; // unsigned char not_used; // unsigned char step1; // unsigned char step2; // unsigned char filter; // cppcheck-suppress * unsigned char stuffing[16]; } FT600_STATUS_INFO; static int ft600_init(RIG *rig); static int ft600_open(RIG *rig); static int ft600_cleanup(RIG *rig); static int ft600_close(RIG *rig); static int ft600_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft600_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft600_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft600_get_vfo(RIG *rig, vfo_t *vfo); static int ft600_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft600_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); struct ft600_priv_data { FT600_STATUS_INFO status; unsigned char s_meter; }; /* prototypes */ static int ft600_send_priv_cmd(RIG *rig, unsigned char cmd_index); static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set main LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* mode set main USB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* mode set main DIG */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* mode set main CW */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* mode set main AM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set clar freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo a */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo b */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* set RPT shift MINUS */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* set RPT shift PLUS */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set RPT offset freq */ /* fix me */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x92 } }, /* set DCS on */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x92 } }, /* set CTCSS/DCS enc/dec on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x92 } }, /* set CTCSS/DCS enc on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x92 } }, /* set CTCSS/DCS off */ /* em xif */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x90 } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x91 } }, /* set DCS code */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get RX status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get TX status */ { 0, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* get FREQ and MODE status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr wakeup sequence */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr off */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* read status block */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* read meter block */ { 1, { 0x00, 0x00, 0x00, 0x01, 0xfa } } /* read flags block */ }; #define FT600_GET_RIG_LEVELS (RIG_LEVEL_RAWSTR) #define FT600_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_PKTUSB|RIG_MODE_CW|RIG_MODE_AM) #define FT600_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT600_OTHER_TX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_PKTUSB|RIG_MODE_CW) #define FT600_AM_TX_MODES (RIG_MODE_AM) #define FT600_VFO_ALL (RIG_VFO_A) #define FT600_ANT (RIG_ANT_1) #define FT600_DUMMY_S_METER_VALUE 0; //FOR TESTS /* S-meter calibration, ascending order of RAW values */ #define FT600_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 11, -48 }, \ { 21, -42 }, \ { 34, -36 }, \ { 50, -30 }, \ { 59, -24 }, \ { 75, -18 }, \ { 93, -12 }, \ { 103, -6 }, \ { 124, 0 }, /* S9 */ \ { 145, 10 }, \ { 160, 20 }, \ { 183, 30 }, \ { 204, 40 }, \ { 222, 50 }, \ { 246, 60 } /* S9+60dB */ \ }} struct rig_caps ft600_caps = { RIG_MODEL(RIG_MODEL_FT600), .model_name = "FT-600", .mfg_name = "Yaesu", .version = "20231001.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT600_WRITE_DELAY, .post_write_delay = FT600_POST_WRITE_DELAY, .timeout = 100, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = FT600_GET_RIG_LEVELS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = RIG_FUNC_NONE, .dcs_list = RIG_FUNC_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan .list = 78 */ .rx_range_list1 = { {kHz(50), kHz(29999), FT600_ALL_RX_MODES, -1, -1, FT600_VFO_ALL}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT600_OTHER_TX_MODES, W(40), W(100), FT600_VFO_ALL, FT600_ANT), FRQ_RNG_HF(1, FT600_AM_TX_MODES, W(25), W(25), FT600_VFO_ALL, FT600_ANT), }, .tuning_steps = { {FT600_ALL_RX_MODES, 10}, {FT600_ALL_RX_MODES, 100}, {FT600_ALL_RX_MODES, 1000}, RIG_TS_END, }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .str_cal = FT600_STR_CAL, .priv = NULL, .rig_init = ft600_init, .rig_cleanup = ft600_cleanup, .rig_open = ft600_open, .rig_close = ft600_close, .set_freq = ft600_set_freq, .get_freq = ft600_get_freq, .set_mode = ft600_set_mode, .get_mode = ft600_get_mode, .set_vfo = NULL, .get_vfo = ft600_get_vfo, .set_ptt = ft600_set_ptt, .get_ptt = NULL, .get_level = ft600_get_level, .set_level = NULL, .get_dcd = NULL, .set_rptr_shift = NULL, .get_rptr_shift = NULL, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_split_freq = NULL, .get_split_freq = NULL, .set_split_mode = NULL, .get_split_mode = NULL, .set_split_vfo = NULL, .get_split_vfo = NULL, .set_rit = NULL, .get_rit = NULL, .set_xit = NULL, .get_xit = NULL, .set_ts = NULL, .get_ts = NULL, .set_dcs_code = NULL, .get_dcs_code = NULL, .set_ctcss_tone = NULL, .get_ctcss_tone = NULL, .set_dcs_sql = NULL, .get_dcs_sql = NULL, .set_ctcss_sql = NULL, .get_ctcss_sql = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .reset = NULL, .set_ant = NULL, .get_ant = NULL, .set_func = NULL, .get_func = NULL, .set_parm = NULL, .get_parm = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static int ft600_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct ft600_priv_data *) calloc(1, sizeof(struct ft600_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } static int ft600_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } static int ft600_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } static int ft600_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s:called\n", __func__); return RIG_OK; } static int ft600_send_priv_cmd(RIG *rig, unsigned char cmd_index) { rig_debug(RIG_DEBUG_VERBOSE, "%s called (%d)\n", __func__, cmd_index); if (!rig) { return -RIG_EINVAL; } return write_block(RIGPORT(rig), (unsigned char *) &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); } static int ft600_read_status(RIG *rig) { struct ft600_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft600_priv_data *)STATE(rig)->priv; rig_flush(rp); ret = ft600_send_priv_cmd(rig, FT600_NATIVE_CAT_READ_STATUS); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &priv->status, FT600_STATUS_UPDATE_DATA_LENGTH); rig_debug(RIG_DEBUG_VERBOSE, "%s: read status=%i \n", __func__, ret); if (ret < 0) { return ret; } return RIG_OK; } static int ft600_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft600_priv_data *priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft600_priv_data *)STATE(rig)->priv; ret = ft600_send_priv_cmd(rig, FT600_NATIVE_CAT_READ_METERS); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "%s: read tx status=%i \n", __func__, ret); ret = read_block(RIGPORT(rig), &priv->s_meter, 5); if (ret < 0) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "S_METER: %u ", priv->s_meter); //val->i = FT600_DUMMY_S_METER_VALUE; //DUMMY val->i = priv->s_meter; return RIG_OK; } static int ft600_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "ft600: requested freq = %"PRIfreq" Hz \n", freq); cmd_index = FT600_NATIVE_CAT_SET_FREQ; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); freq = (int)freq / 10; to_bcd(p_cmd, freq, 8); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft600_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft600_priv_data *priv = (struct ft600_priv_data *)STATE(rig)->priv; freq_t f; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: get_freq\n", __func__); if (!freq) { return -RIG_EINVAL; } ret = ft600_read_status(rig); if (ret != RIG_OK) { return ret; } f = ((((priv->status.freq[1] << 8) + priv->status.freq[2]) << 8) + priv->status.freq[3]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz\n", __func__, f); *freq = f; return RIG_OK; } static int ft600_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: cmd_index = FT600_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: cmd_index = FT600_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } return ft600_send_priv_cmd(rig, cmd_index); } static int ft600_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft600_priv_data *priv = (struct ft600_priv_data *)STATE(rig)->priv; int ret; if (!mode) { return -RIG_EINVAL; } *width = RIG_PASSBAND_NORMAL; ret = ft600_read_status(rig); if (ret < 0) { return ret; } switch (priv->status.freq[6]) { case 0x00: *mode = RIG_MODE_LSB; *width = Hz(5000); break; case 0x01: *mode = RIG_MODE_USB; *width = Hz(5000); break; case 0x02: *mode = RIG_MODE_CW; *width = Hz(1200); break; case 0x04: *mode = RIG_MODE_AM; *width = Hz(6000); break; case 0x05: *mode = RIG_MODE_PKTUSB; *width = Hz(5000); break; default: *mode = RIG_MODE_NONE; *width = RIG_PASSBAND_NORMAL; }; return RIG_OK; } static int ft600_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s, width %d\n", __func__, rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_LSB: cmd_index = FT600_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_USB: cmd_index = FT600_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_PKTUSB: cmd_index = FT600_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_CW: cmd_index = FT600_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_AM: cmd_index = FT600_NATIVE_CAT_SET_MODE_AM; break; default: return -RIG_EINVAL; } ret = ft600_send_priv_cmd(rig, cmd_index); if (ret != RIG_OK) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } #if 1 if (mode != RIG_MODE_FM && mode != RIG_MODE_WFM && width <= kHz(6)) { unsigned char p_cmd[YAESU_CMD_LENGTH]; p_cmd[0] = 0x00; p_cmd[1] = 0x00; p_cmd[2] = 0x00; p_cmd[3] = 0x00; /* to be filled in */ p_cmd[4] = 0x8C; /* Op: filter selection */ if (width <= 300) { p_cmd[3] = 0x03; } else if (width <= 500) { p_cmd[3] = 0x02; } else if (width <= 2400) { p_cmd[3] = 0x00; } else { p_cmd[3] = 0x01; } ret = write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); if (ret != RIG_OK) { return ret; } } #endif return RIG_OK; } static int ft600_get_vfo(RIG *rig, vfo_t *vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } *vfo = RIG_VFO_A; return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft897.c0000644000175000017500000012534514752216205013035 00000000000000/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- * * ft897.c - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * (C) Stephane Fillod 2009 * * ...derived but heavily modified from: * * ft817.c - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-897 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Unimplemented features supported by the FT-897: * * - DCS encoder/squelch ON/OFF, similar to RIG_FUNC_TONE/TSQL. * Needs frontend support. * * - RX status command returns info that is not used: * * - discriminator centered (yes/no flag) * - received ctcss/dcs matched (yes/no flag) * * The manual also indicates that CTCSS and DCS codes can be set * separately for tx and rx, but this doesn't seem to work. It * doesn't work from front panel either. * * DONE (--sf): * * - VFO A/B toggle. Needs frontend support (RIG_OP_TOGGLE) * * - Split ON/OFF. Maybe some sort of split operation could * be supported with this and the above??? * * - TX status command returns info that is not used: * * - split on/off flag * - high swr flag */ #include #include #include /* String function definitions */ #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft897.h" #include "ft817.h" /* We use functions from the 817 code */ #include "ft857.h" //Needed for ft857_set_vfo, ft857_get_vfo #include "misc.h" #include "tones.h" #include "bandplan.h" enum ft897_native_cmd_e { FT897_NATIVE_CAT_LOCK_ON = 0, FT897_NATIVE_CAT_LOCK_OFF, FT897_NATIVE_CAT_PTT_ON, FT897_NATIVE_CAT_PTT_OFF, FT897_NATIVE_CAT_SET_FREQ, FT897_NATIVE_CAT_SET_MODE_LSB, FT897_NATIVE_CAT_SET_MODE_USB, FT897_NATIVE_CAT_SET_MODE_CW, FT897_NATIVE_CAT_SET_MODE_CWR, FT897_NATIVE_CAT_SET_MODE_AM, FT897_NATIVE_CAT_SET_MODE_FM, FT897_NATIVE_CAT_SET_MODE_FM_N, FT897_NATIVE_CAT_SET_MODE_DIG, FT897_NATIVE_CAT_SET_MODE_PKT, FT897_NATIVE_CAT_CLAR_ON, FT897_NATIVE_CAT_CLAR_OFF, FT897_NATIVE_CAT_SET_CLAR_FREQ, FT897_NATIVE_CAT_SET_VFOAB, FT897_NATIVE_CAT_SPLIT_ON, FT897_NATIVE_CAT_SPLIT_OFF, FT897_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT897_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT897_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT897_NATIVE_CAT_SET_RPT_OFFSET, FT897_NATIVE_CAT_SET_DCS_ON, FT897_NATIVE_CAT_SET_DCS_DEC_ON, FT897_NATIVE_CAT_SET_DCS_ENC_ON, FT897_NATIVE_CAT_SET_CTCSS_ON, FT897_NATIVE_CAT_SET_CTCSS_DEC_ON, FT897_NATIVE_CAT_SET_CTCSS_ENC_ON, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF, FT897_NATIVE_CAT_SET_CTCSS_FREQ, FT897_NATIVE_CAT_SET_DCS_CODE, FT897_NATIVE_CAT_GET_RX_STATUS, FT897_NATIVE_CAT_GET_TX_STATUS, FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT897_NATIVE_CAT_PWR_WAKE, FT897_NATIVE_CAT_PWR_ON, FT897_NATIVE_CAT_PWR_OFF, FT897_NATIVE_CAT_EEPROM_READ, FT897_NATIVE_CAT_GET_TX_METER, FT897_NATIVE_SIZE /* end marker */ }; struct ft897_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[YAESU_CMD_LENGTH + 1]; /* tx meter status */ struct timeval tm_status_tv; unsigned char tm_status[3]; }; static int ft897_init(RIG *rig); static int ft897_open(RIG *rig); static int ft897_cleanup(RIG *rig); static int ft897_close(RIG *rig); static int ft897_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft897_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft897_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft897_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft897_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft897_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft897_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft897_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft897_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); // static int ft897_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ft897_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft897_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); // static int ft897_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); // static int ft897_set_parm(RIG *rig, setting_t parm, value_t val); // static int ft897_get_parm(RIG *rig, setting_t parm, value_t *val); static int ft897_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft897_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t code); static int ft897_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft897_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft897_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft897_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft897_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft897_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); /* Native ft897 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x88 } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM-N */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main DIG */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main PKT */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* clar on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf5 } }, /* set clar freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* split off */ { 1, { 0x09, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 1, { 0x49, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift PLUS */ { 1, { 0x89, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on */ { 1, { 0x0b, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS decoder on */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS encoder on */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS on */ { 1, { 0x3a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS decoder on */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS encoder on */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status */ { 1, { 0xff, 0xff, 0xff, 0xff, 0xff } }, /* pwr wakeup sequence */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* pwr on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8f } }, /* pwr off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbb } }, /* eeprom read */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xbd } }, /* tx meter status, i.e ALC, MOD, PWR, SWR */ }; enum ft897_digi { FT897_DIGI_RTTY_L = 0, FT897_DIGI_RTTY_U, FT897_DIGI_PSK_L, FT897_DIGI_PSK_U, FT897_DIGI_USER_L, FT897_DIGI_USER_U, }; #define FT897_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT897_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB) #define FT897_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) #define FT897_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT897_AM_TX_MODES (RIG_MODE_AM) #define FT897_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT897_ANTS RIG_ANT_CURR struct rig_caps ft897_caps = { RIG_MODEL(RIG_MODEL_FT897), .model_name = "FT-897", .mfg_name = "Yaesu", .version = "20220404.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT897_WRITE_DELAY, .post_write_delay = FT897_POST_WRITE_DELAY, .timeout = FT897_TIMEOUT, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER | RIG_LEVEL_SWR | RIG_LEVEL_RAWSTR | RIG_LEVEL_ALC, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .vfo_ops = RIG_OP_TOGGLE, .rx_range_list1 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(1, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(1, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(1, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(2, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(2, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(2, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT897_SSB_CW_RX_MODES, 10}, {FT897_SSB_CW_RX_MODES, 100}, {FT897_AM_FM_RX_MODES, 10}, {FT897_AM_FM_RX_MODES, 100}, RIG_TS_END, }, /* filter selection is not supported by CAT functions * per testing by Rich Newsom, WA4SXZ */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, // {RIG_MODE_SSB, kHz(2.2)}, // {RIG_MODE_CW, kHz(2.2)}, // {RIG_MODE_CWR, kHz(2.2)}, // {RIG_MODE_RTTY, kHz(2.2)}, // {RIG_MODE_AM, kHz(6)}, // {RIG_MODE_FM, kHz(15)}, // {RIG_MODE_PKTFM, kHz(15)}, // {RIG_MODE_FM, kHz(9)}, // {RIG_MODE_PKTFM, kHz(9)}, // {RIG_MODE_WFM, kHz(230)}, /* ?? */ RIG_FLT_END, }, .rig_init = ft897_init, .rig_cleanup = ft897_cleanup, .rig_open = ft897_open, .rig_close = ft897_close, // .get_vfo = ft857_get_vfo, // set_vfo not working on serial# 5n660296 // .set_vfo = ft857_set_vfo, .set_vfo = NULL, .set_freq = ft897_set_freq, .get_freq = ft897_get_freq, .set_mode = ft897_set_mode, .get_mode = ft897_get_mode, .set_ptt = ft897_set_ptt, .get_ptt = ft897_get_ptt, .get_dcd = ft897_get_dcd, .set_rptr_shift = ft897_set_rptr_shift, .set_rptr_offs = ft897_set_rptr_offs, .set_split_vfo = ft897_set_split_vfo, .get_split_vfo = ft897_get_split_vfo, .set_rit = ft897_set_rit, .set_dcs_code = ft897_set_dcs_code, .set_ctcss_tone = ft897_set_ctcss_tone, .set_dcs_sql = ft897_set_dcs_sql, .set_ctcss_sql = ft897_set_ctcss_sql, .set_powerstat = ft817_set_powerstat, .get_level = ft897_get_level, .set_func = ft897_set_func, .vfo_op = ft897_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft897d_caps = { RIG_MODEL(RIG_MODEL_FT897D), .model_name = "FT-897D", .mfg_name = "Yaesu", .version = "20220407.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT897_WRITE_DELAY, .post_write_delay = FT897_POST_WRITE_DELAY, .timeout = FT897_TIMEOUT, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER | RIG_LEVEL_SWR | RIG_LEVEL_RAWSTR | RIG_LEVEL_ALC, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .vfo_ops = RIG_OP_TOGGLE, .rx_range_list1 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_6m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(1, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(1, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(1, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(1, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT897_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT897_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT897_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT897_OTHER_TX_MODES, W(10), W(100), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_HF(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_2m(2, FT897_OTHER_TX_MODES, W(5), W(50), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_2m(2, FT897_AM_TX_MODES, W(2.5), W(25), FT897_VFO_ALL, FT897_ANTS), FRQ_RNG_70cm(2, FT897_OTHER_TX_MODES, W(2), W(20), FT897_VFO_ALL, FT897_ANTS), /* AM class */ FRQ_RNG_70cm(2, FT897_AM_TX_MODES, W(0.5), W(5), FT897_VFO_ALL, FT897_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT897_SSB_CW_RX_MODES, 10}, {FT897_SSB_CW_RX_MODES, 100}, {FT897_AM_FM_RX_MODES, 10}, {FT897_AM_FM_RX_MODES, 100}, RIG_TS_END, }, /* filter selection is not supported by CAT functions * per testing by Rich Newsom, WA4SXZ */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, // {RIG_MODE_SSB, kHz(2.2)}, // {RIG_MODE_CW, kHz(2.2)}, // {RIG_MODE_CWR, kHz(2.2)}, // {RIG_MODE_RTTY, kHz(2.2)}, // {RIG_MODE_AM, kHz(6)}, // {RIG_MODE_FM, kHz(15)}, // {RIG_MODE_PKTFM, kHz(15)}, // {RIG_MODE_FM, kHz(9)}, // {RIG_MODE_PKTFM, kHz(9)}, // {RIG_MODE_WFM, kHz(230)}, /* ?? */ RIG_FLT_END, }, .rig_init = ft897_init, .rig_cleanup = ft897_cleanup, .rig_open = ft897_open, .rig_close = ft897_close, .get_vfo = ft857_get_vfo, .set_vfo = ft857_set_vfo, .set_freq = ft897_set_freq, .get_freq = ft897_get_freq, .set_mode = ft897_set_mode, .get_mode = ft897_get_mode, .set_ptt = ft897_set_ptt, .get_ptt = ft897_get_ptt, .get_dcd = ft897_get_dcd, .set_rptr_shift = ft897_set_rptr_shift, .set_rptr_offs = ft897_set_rptr_offs, .set_split_vfo = ft897_set_split_vfo, .get_split_vfo = ft897_get_split_vfo, .set_rit = ft897_set_rit, .set_dcs_code = ft897_set_dcs_code, .set_ctcss_tone = ft897_set_ctcss_tone, .set_dcs_sql = ft897_set_dcs_sql, .set_ctcss_sql = ft897_set_ctcss_sql, .set_powerstat = ft817_set_powerstat, .get_level = ft897_get_level, .set_func = ft897_set_func, .vfo_op = ft897_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ---------------------------------------------------------------------- */ int ft897_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if ((STATE(rig)->priv = calloc(1, sizeof(struct ft897_priv_data))) == NULL) { return -RIG_ENOMEM; } return RIG_OK; } int ft897_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int ft897_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft897_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } static int check_cache_timeout(struct timeval *tv) { struct timeval curr; long t; if (tv->tv_sec == 0 && tv->tv_usec == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache invalid\n", __func__); return 1; } gettimeofday(&curr, NULL); if ((t = timediff(&curr, tv)) < FT897_CACHE_TIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "%s: using cache (%ld ms)\n", __func__, t); return 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache timed out (%ld ms)\n", __func__, t); return 1; } } static int ft897_read_eeprom(RIG *rig, unsigned short addr, unsigned char *out) { unsigned char data[YAESU_CMD_LENGTH]; int n; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); memcpy(data, (char *)ncmd[FT897_NATIVE_CAT_EEPROM_READ].nseq, YAESU_CMD_LENGTH); data[0] = addr >> 8; data[1] = addr & 0xfe; write_block(rp, data, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, 2)) < 0) { return n; } if (n != 2) { return -RIG_EIO; } *out = data[addr % 2]; return RIG_OK; } static int ft897_get_status(RIG *rig, int status) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); struct timeval *tv; unsigned char *data; int len; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS: data = p->fm_status; len = YAESU_CMD_LENGTH; tv = &p->fm_status_tv; break; case FT897_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; tv = &p->rx_status_tv; break; case FT897_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; tv = &p->tx_status_tv; break; case FT897_NATIVE_CAT_GET_TX_METER: data = p->tm_status; len = 2; tv = &p->tm_status_tv; break; default: rig_debug(RIG_DEBUG_ERR, "%s: internal error!\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); write_block(rp, ncmd[status].nseq, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, len)) < 0) { return n; } if (n != len) { return -RIG_EIO; } if (status == FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS) { if ((n = ft897_read_eeprom(rig, 0x0078, &p->fm_status[5])) < 0) { return n; } p->fm_status[5] >>= 5; } gettimeofday(tv, NULL); return RIG_OK; } /* ---------------------------------------------------------------------- */ int ft897_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } *freq = from_bcd_be(p->fm_status, 8) * 10; return RIG_OK; } int ft897_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } switch (p->fm_status[4] & 0x7f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x06: *mode = RIG_MODE_WFM; break; case 0x08: *mode = RIG_MODE_FM; break; case 0x0a: switch (p->fm_status[5]) { case FT897_DIGI_RTTY_L: *mode = RIG_MODE_RTTY; break; case FT897_DIGI_RTTY_U: *mode = RIG_MODE_RTTYR; break; case FT897_DIGI_PSK_L: *mode = RIG_MODE_PKTLSB; break; case FT897_DIGI_PSK_U: *mode = RIG_MODE_PKTUSB; break; case FT897_DIGI_USER_L: *mode = RIG_MODE_PKTLSB; break; case FT897_DIGI_USER_U: *mode = RIG_MODE_PKTUSB; break; } break; case 0x0c: *mode = RIG_MODE_PKTFM; break; default: *mode = RIG_MODE_NONE; } if (p->fm_status[4] & 0x80) /* narrow */ { *width = rig_passband_narrow(rig, *mode); } else { *width = RIG_PASSBAND_NORMAL; } return RIG_OK; } int ft897_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } *ptt = ((p->tx_status & 0x80) == 0); return RIG_OK; } static int ft897_get_pometer_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } /* Valid only if PTT is on */ if ((p->tx_status & 0x80) == 0) { val->f = ((p->tx_status & 0x0F) / 15.0); } else { val->f = 0.0; } return RIG_OK; } static int ft897_get_swr_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } /* Valid only if PTT is on */ if ((p->tx_status & 0x80) == 0) { val->f = (p->tx_status & 0x40) ? 30.0 : 1.0; /* or infinity? */ } else { val->f = 0.0; } return RIG_OK; } static int ft897_get_smeter_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } n = (p->rx_status & 0x0F) - 9; val->i = n * ((n > 0) ? 10 : 6); return RIG_OK; } static int ft897_get_rawstr_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } val->i = p->rx_status & 0x0F; return RIG_OK; } static int ft897_get_alc_level(RIG *rig, value_t *val) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); /* have to check PTT first - only 1 byte (0xff) returned in RX and two bytes returned in TX */ if ((p->tx_status & 0x80) == 0) { if (check_cache_timeout(&p->tm_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_METER)) < 0) { return n; } } /* returns 2 bytes when in TX mode: byte[0]: bits 7:4 --> power byte[0]: bits 3:0 --> ALC byte[1]: bits 7:4 --> SWR byte[1]: bits 3:0 --> MOD */ val->f = p->tm_status[0] >> 4; } else { val->f = 0; } return RIG_OK; } int ft897_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (level) { case RIG_LEVEL_STRENGTH: return ft897_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return ft897_get_rawstr_level(rig, val); case RIG_LEVEL_RFPOWER: return ft897_get_pometer_level(rig, val); case RIG_LEVEL_SWR: return ft897_get_swr_level(rig, val); case RIG_LEVEL_ALC: return ft897_get_alc_level(rig, val); default: return -RIG_EINVAL; } return RIG_OK; } int ft897_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete sequences. */ static int ft897_send_cmd(RIG *rig, int index) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: incomplete sequence\n", __func__); return -RIG_EINTERNAL; } write_block(RIGPORT(rig), ncmd[index].nseq, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* * The same for incomplete commands. */ static int ft897_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* ---------------------------------------------------------------------- */ int ft897_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: requested freq = %"PRIfreq" Hz\n", __func__, freq); /* fill in the frequency */ to_bcd_be(data, (freq + 5) / 10, 8); /*invalidate frequency cache*/ rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_FREQ, data); } int ft897_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: index = FT897_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: index = FT897_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_USB: index = FT897_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: index = FT897_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_RTTY: case RIG_MODE_PKTUSB: /* user has to have correct DIG mode setup on rig */ index = FT897_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_FM: index = FT897_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_CWR: index = FT897_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_PKTFM: index = FT897_NATIVE_CAT_SET_MODE_PKT; break; default: return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL) { return -RIG_EINVAL; } rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft897_send_cmd(rig, index); } int ft897_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (ptt) { case RIG_PTT_ON: index = FT897_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: index = FT897_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } n = ft897_send_cmd(rig, index); rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft897_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (op) { case RIG_OP_TOGGLE: rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->tx_status_tv); index = FT897_NATIVE_CAT_SET_VFOAB; break; default: return -RIG_EINVAL; } n = ft897_send_cmd(rig, index); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft897_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (split) { case RIG_SPLIT_OFF: index = FT897_NATIVE_CAT_SPLIT_OFF; break; case RIG_SPLIT_ON: index = FT897_NATIVE_CAT_SPLIT_ON; break; default: return -RIG_EINVAL; } n = ft897_send_cmd(rig, index); rig_force_cache_timeout(&((struct ft897_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft897_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft897_priv_data *p = (struct ft897_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) if ((n = ft897_get_status(rig, FT897_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } if (p->tx_status & 0x80) { // TX status not valid when in RX unsigned char c; if ((n = ft897_read_eeprom(rig, 0x008d, &c)) < 0) /* get split status */ { return n; } *split = (c & 0x80) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } else { *split = (p->tx_status & 0x20) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } return RIG_OK; } int ft897_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_LOCK_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_OFF); } #if 0 case RIG_FUNC_CODE: /* this doesn't exist */ if (status) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ENC_ON); } else { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } #endif default: return -RIG_EINVAL; } } int ft897_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set DCS code (%u)\n", code); if (code == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ENC_ON); } int ft897_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ENC_ON); } int ft897_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set DCS sql (%u)\n", code); if (code == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_DCS_ON); } int ft897_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_CTCSS_ON); } int ft897_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set repeter shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return ft897_send_cmd(rig, FT897_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } int ft897_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set repeter offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_RPT_OFFSET, data); } int ft897_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft897: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = ft897_send_icmd(rig, FT897_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_OFF); } else { ft897_send_cmd(rig, FT897_NATIVE_CAT_CLAR_ON); }*/ return RIG_OK; } /* ---------------------------------------------------------------------- */ hamlib-4.6.2/rigs/yaesu/README.ft9200000644000175000017500000001362114752216205013524 00000000000000Quirks, known bugs, and other notes. ==================================== In this document I'll try to describe the behavior of the Yaesu FT-920 transceiver with Hamlib. Some of these are limitations of the radio while others are programming trade-offs with Hamlib. This document is organized by Hamlib function calls and documents observed behavior with each call. rig_set_mode * No matter the status of the main display, MEM or VFO, display will be set to VFO mode if RIG_VFO_A or RIG_VFO_VFO is passed. * If radio is in MEM or MEM TUNE state, main display mode can be changed when RIG_VFO_MEM or RIG_VFO_MAIN is passed. * When RIG_VFO_CURR is passed, the display will be set per the VFO stored by the last rig_get_vfo call. * Modes DATA USB and DATA FM cannot be set at this time (Hamlib limitation). See below. * My FT-920 does not support USB/LSB narrow so attempting to set a narrow passband with these modes will return an Invalib Parameter error. rig_get_mode * Modes DATA USB and DATA FM cannot be returned as rig.h only has RIG_MODE_RTTY (Hamlib limitation). * DATA LSB is mapped to RIG_MODE_RTTY. * I would like to hear from anyone who gets a narrow passband value in USB/LSB mode returned. rig_set_freq * When passed RIG_VFO_A or RIG_VFO_VFO the main display is forced to VFO mode and then the frequency is set. * When passed RIG_VFO_B or RIG_VFO_SUB, the sub display frequency is set. * When passed RIG_VFO_MEM, or RIG_VFO_MAIN, the main display frequency is set regardless of whether the main display is in memory (thus activating MEM Tune) or VFO mode. * When RIG_VFO_CURR is passed, the display will be set per the VFO stored by the last rig_get_vfo call. * RIG_TARGETABLE_ALL is properly handled (I think). rig_get_freq * When passed RIG_VFO_A or RIG_VFO_VFO, the radio returns the frequency in the main VFO, even if the main display is in MEM or MEM Tune. * When passed RIG_VFO_B or RIG_VFO_SUB, the sub-display frequency is returned. * When passed RIG_VFO_MEM or RIG_VFO_MAIN, the current main display frequency is returned regardless of main display mode. * When passed RIG_VFO_CURR, the display will be read per the VFO stored by the last rig_get_vfo call. rig_set_vfo * When called with RIG_VFO_A or RIG_VFO_VFO, the radio appears to do nothing, however, rig_state->current_vfo will be updated. * When called with RIG_VFO_B, the radio will swap the main and sub displays, the same as if the front panel A<>B button is pressed. * No provision exists to make VFO-B (sub display) the active RX through CAT. rig_get_split * Both split capabilities are tested, i.e. RX A/TX B and RX B/TX A, but Hamlib only supports an indication that the radio is split. * The VFO value passed is not used by the ft920 backend lib. FIXME: Is this a problem? rig_set_split * When called with RIG_SPLIT_OFF the radio will make TX A active if TX B was active, otherwise no change. * When called with RIG_SPLIT_ON the radio will make TX B active if TX A was active, otherwise no change. * The FT-920 has no capability to change the active RX to RX B (sub display) through CAT. Thus if VFO-B is active RX/TX the setting RIG_SPLIT_ON will make no visible change on the radio. * The VFO value passed is not used by the ft920 backend lib. FIXME: Is this a problem? rig_set_split_freq * Backend simply wraps rig_set_freq--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_get_split_freq * Backend simply wraps rig_get_freq--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_set_split_mode * Backend simply wraps rig_set_mode--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_get_split_mode * Backend simply wraps rig_get_mode--calling app needs to specify target VFO to set frequency. Should backend determine split and set "proper" VFO? rig_set_rit * Hamlib specifies that passing 0 as the RIT frequency disables RIT. Thus there is no way to meet the spec and mimic the front panel RIT off function whilst keeping the RIT offset on the display. The Hamlib spec causes behavior analogous to shutting RIT off and then pressing the Clear button. * There is no direct way to set RIT offset of VFOB/SUB. However, rig_set_vfo can be used to swap VFO B and main, then set RIT, then call rig_set_vfo to swap VFO B and main. FIXME: Should backend do this automatically? rig_get_rit * Backend returns clarifier offset regardless of whether RIT is on. * vfo is honored and stored RIT is returned. rig_set_xit * Hamlib specifies that passing 0 as the XIT frequency disables XIT. Thus there is no way to meet the spec and mimic the front panel XIT off function whilst keeping the XIT offset on the display. The Hamlib spec causes behavior analogous to shutting XIT off and then pressing the Clear button. * There is no direct way to set XIT offset of VFOB/SUB. However, rig_set_vfo can be used to swap VFO B and main, then set XIT, then call rig_set_vfo to swap VFO B and main. FIXME: Should backend do this automatically? rig_get_xit * Backend returns clarifier offset regardless of whether XIT is on. * vfo is honored and stored XIT is returned. General notes. As with most all Yaesu radios the radio must be polled by the application for status updates, i.e. no transceive mode in CAT. hamlib-4.6.2/rigs/yaesu/ft2000.h0000644000175000017500000001226414752216205013067 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft2000.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-2000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT2000_H #define _FT2000_H 1 #define FT2000_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT2000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN) #define FT2000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT2000_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FT2000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFM) #define FT2000_PKTSSB_RX_MODES (RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) /* TRX caps */ #define FT2000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN) /* 100 W class */ #define FT2000_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FT2000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT2000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER|RIG_FUNC_APF) #define FT2000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // From measurements on FT2000D by Stan UA3SAQ // We'll reuse this for now and divide by 2 for FT2000 #define FT2000D_RFPOWER_METER_CAL { 12, \ { \ {0, 0.0f}, \ {51, 10.0f}, \ {67, 20.0f}, \ {97, 40.0f}, \ {123, 60.0f}, \ {140, 80.0f}, \ {161, 100.0f}, \ {168, 120.0f}, \ {184, 140.0f}, \ {195, 160.0f}, \ {215, 180.0f}, \ {224, 200.0f}, \ } \ } #define FT2000_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT2000_TX_ANTS (RIG_ANT_1|RIG_ANT_2) #define FT2000_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT2000_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT2000_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT2000_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT2000_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT2000_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT2000_PACING_INTERVAL 5 // #define FT2000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-2000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT2000_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT2000_POST_WRITE_DELAY 5 #endif /* _FT2000_H */ hamlib-4.6.2/rigs/yaesu/frg8800.c0000644000175000017500000001560614752216205013250 00000000000000/* * frg8800.c - (C) Stephane Fillod 2002-2004 * * This shared library provides an API for communicating * via serial interface to an FRG-8800 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" /* Private helper function prototypes */ #define FRG8800_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define FRG8800_VFOS (RIG_VFO_A) #define FRG8800_ANTS 0 static int frg8800_open(RIG *rig); static int frg8800_close(RIG *rig); static int frg8800_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int frg8800_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int frg8800_set_powerstat(RIG *rig, powerstat_t status); /* * frg8800 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps frg8800_caps = { RIG_MODEL(RIG_MODEL_FRG8800), .model_name = "FRG-8800", .mfg_name = "Yaesu", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 300, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(29.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, {MHz(118), MHz(173.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(150), MHz(29.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, {MHz(118), MHz(173.999), FRG8800_MODES, -1, -1, FRG8800_VFOS, FRG8800_ANTS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {FRG8800_MODES, Hz(25)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_WFM, kHz(230)}, /* optional unit */ RIG_FLT_END, }, .rig_open = frg8800_open, .rig_close = frg8800_close, .set_freq = frg8800_set_freq, .set_mode = frg8800_set_mode, .set_powerstat = frg8800_set_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; #define MODE_SET_AM 0x00 #define MODE_SET_LSB 0x01 #define MODE_SET_USB 0x02 #define MODE_SET_CW 0x03 #define MODE_SET_FM 0x0c #define MODE_SET_FMW 0x04 /* * frg8800_open routine * */ int frg8800_open(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* send Ext Cntl ON: Activate CAT */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_close(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x80, 0x00}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* send Ext Cntl OFF: Deactivate CAT */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* store bcd format in cmd (LSB) */ to_bcd(cmd, freq / 10, 8); /* Byte1: 100Hz's and 25Hz step code */ cmd[0] = (cmd[0] & 0xf0) | (1 << ((((long long)freq) % 100) / 25)); /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x80}; unsigned char md; rig_debug(RIG_DEBUG_TRACE, "%s: frg8800_set_mode called %s\n", __func__, rig_strrmode(mode)); /* * translate mode from generic to frg8800 specific */ switch (mode) { case RIG_MODE_AM: md = MODE_SET_AM; break; case RIG_MODE_CW: md = MODE_SET_CW; break; case RIG_MODE_USB: md = MODE_SET_USB; break; case RIG_MODE_LSB: md = MODE_SET_LSB; break; case RIG_MODE_FM: md = MODE_SET_FM; break; case RIG_MODE_WFM: md = MODE_SET_FMW; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md |= 0x08; } cmd[3] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg8800_set_powerstat(RIG *rig, powerstat_t status) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x80}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cmd[3] = status == RIG_POWER_OFF ? 0xff : 0xfe; /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } hamlib-4.6.2/rigs/yaesu/ft767gx.h0000644000175000017500000000321014752216205013357 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * * ft767gx.h - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * adapted from ft757gx.h by Steve Conklin * This shared library provides an API for communicating * via serial interface to an FT-767GX using the "CAT" interface * box (FIF-232C) or similar (max232 + some capacitors :-) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT767GX_H #define _FT767GX_H 1 #define FT767GX_STATUS_UPDATE_DATA_LENGTH 86 #define FT767GX_PACING_INTERVAL 5 #define FT767GX_PACING_DEFAULT_VALUE 0 #define FT767GX_WRITE_DELAY 0 /* Sequential fast writes confuse my FT767GX without this delay */ #define FT767GX_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT767GX_DEFAULT_READ_TIMEOUT 345 * ( 3 + (FT767GX_PACING_INTERVAL * FT767GX_PACING_DEFAULT_VALUE)) #endif /* _FT767GX_H */ hamlib-4.6.2/rigs/yaesu/ft900.c0000644000175000017500000015416614752216205013021 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft900.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002-2005 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-900 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "cal.h" #include "yaesu.h" #include "ft900.h" /* * Functions considered to be Beta code (2003-04-11): * set_freq * get_freq * set_mode * get_mode * set_vfo * get_vfo * set_ptt * get_ptt * set_split * get_split * set_rit * get_rit * set_func * get_func * get_level * * Functions considered to be Alpha code (2003-04-11): * vfo_op * * functions not yet implemented (2003-04-11): * set_split_freq * get_split_freq * set_split_mode * get_split_mode * */ /* * Native FT900 functions. More to come :-) * */ enum ft900_native_cmd_e { FT900_NATIVE_SPLIT_OFF = 0, FT900_NATIVE_SPLIT_ON, FT900_NATIVE_RECALL_MEM, FT900_NATIVE_VFO_TO_MEM, FT900_NATIVE_VFO_A, FT900_NATIVE_VFO_B, FT900_NATIVE_MEM_TO_VFO, FT900_NATIVE_CLARIFIER_OPS, FT900_NATIVE_FREQ_SET, FT900_NATIVE_MODE_SET, FT900_NATIVE_PACING, FT900_NATIVE_PTT_OFF, FT900_NATIVE_PTT_ON, FT900_NATIVE_MEM_CHNL, FT900_NATIVE_OP_DATA, FT900_NATIVE_VFO_DATA, FT900_NATIVE_MEM_CHNL_DATA, FT900_NATIVE_TUNER_OFF, FT900_NATIVE_TUNER_ON, FT900_NATIVE_TUNER_START, FT900_NATIVE_READ_METER, FT900_NATIVE_READ_FLAGS, FT900_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft900_native_cmd_e ft900_native_cmd_t; /* * Internal MODES - when setting modes via FT900_NATIVE_MODE_SET * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW_W 0x02 #define MODE_SET_CW_N 0x03 #define MODE_SET_AM_W 0x04 #define MODE_SET_AM_N 0x05 #define MODE_SET_FM 0x06 /* * Internal Clarifier parms - when setting clarifier via * FT900_NATIVE_CLARIFIER_OPS * * The manual seems to be incorrect with regard to P1 and P2 values * P1 = 0x00 clarifier off * P1 = 0x01 clarifier on * P1 = 0xff clarifier set * P2 = 0x00 clarifier up * P2 = 0xff clarifier down */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA requests the FT-900 to return its status flags. * These flags consist of 3 bytes (plus 2 filler bytes) and are documented * in the FT-900 manual on page 33. * */ #define FT900_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_GC (1<<1) /* General Coverage Reception selected */ #define SF_SPLIT (1<<2) /* Split active */ #define SF_MCK (1<<3) /* memory Checking in progress */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_MR (1<<5) /* Memory Mode selected */ #define SF_A (0<<6) /* bit 6 clear, VFO A */ #define SF_B (1<<6) /* bit 6 set, VFO B */ #define SF_VFO (1<<7) /* bit 7 set, VFO A or B active */ #define SF_VFOA (SF_VFO|SF_A) /* bit 7 set, bit 6 clear, VFO A */ #define SF_VFOB (SF_VFO|SF_B) /* bit 7 set, bit 6 set, VFO B */ #define SF_VFO_MASK (SF_VFOB) /* bits 6 and 7 */ #define SF_MEM_MASK (SF_MCK|SF_MT|SF_MR) /* bits 3, 4 and 5 */ #define FT900_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define FT900_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 1 */ #define SF_PTT_OFF (0<<7) /* bit 7 set, PTT open */ #define SF_PTT_ON (1<<7) /* bit 7 set, PTT closed */ #define SF_PTT_MASK (SF_PTT_ON) /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03, 04 * * The FT-900 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (19 bytes) * CAT command 0x10, P1 = 03 returns VFO A & B data (18 bytes) * CAT command 0x10, P1 = 04, P4 = 0x01-0x20 returns memory channel data (19 bytes) * In all cases the format is (from the FT-900 manual page 32): * * Offset Value * 0x00 Band Selection (BPF selection: 0x00 - 0x30 (bit 7 =1 on a blanked memory)) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x04 Clarifier Offset (signed value between -999d (0xfc19) and +999d (0x03e7)) * 0x06 Mode Data * 0x07 CTCSS tone code (0x00 - 0x20) * 0x08 Flags (Operating flags -- manual page 33) * * Memory Channel data has the same layout and offsets as the operating * data record. * When either of the 19 byte records is read (P1 = 02, 04), the offset is * +1 as the leading byte is the memory channel number. * The VFO data command (P1 = 03) returns 18 bytes and the VFO B data has * the same layout, but the offset starts at 0x09 and continues through 0x12 * */ #define FT900_SUMO_MEM_CHANNEL 0x00 /* Memory Channel from 0xfa, P1 = 1 */ #define FT900_SUMO_DISPLAYED_FREQ 0x02 /* Current main display, can be VFO A, Memory data, Memory tune (3 bytes) */ #define FT900_SUMO_DISPLAYED_CLAR 0x05 /* RIT offset -- current display */ #define FT900_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT900_SUMO_DISPLAYED_FLAG 0x09 #define FT900_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT900_SUMO_VFO_A_CLAR 0x04 /* RIT offset -- VFO A */ #define FT900_SUMO_VFO_A_MODE 0x06 /* VFO A mode, not necessarily currently displayed! */ #define FT900_SUMO_VFO_A_FLAG 0x08 #define FT900_SUMO_VFO_B_FREQ 0x0a /* Current sub display && VFO B */ #define FT900_SUMO_VFO_B_CLAR 0x0d /* RIT offset -- VFO B */ #define FT900_SUMO_VFO_B_MODE 0x0f /* Current sub display && VFO B */ #define FT900_SUMO_VFO_B_FLAG 0x11 /* * Read meter offset * * FT-900 returns the level of the S meter when in RX and ALC or PO or SWR * when in TX. The level is replicated in the first four bytes sent by the * rig with the final byte being a constant 0xf7 * * The manual states that the returned value will range between 0x00 and 0xff * while "in practice the highest value returned will be around 0xf0". The * manual is silent when this value is returned as my rig returns 0x00 for * S0, 0x44 for S9 and 0x9D for S9 +60. * */ #define FT900_SUMO_METER 0x00 /* Meter level */ /* * Narrow filter selection flag from offset 0x08 or 0x11 * in VFO/Memory Record * * used when READING modes from FT-900 * */ #define FLAG_AM_N (1<<6) #define FLAG_CW_N (1<<7) #define FLAG_MASK (FLAG_AM_N|FLAG_CW_N) /* * Mode Bitmap from offset 0x06 or 0x0f in VFO/Memory Record. * * used when READING modes from FT-900 * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 /* All relevant bits */ #define MODE_MASK (MODE_LSB|MODE_USB|MODE_CW|MODE_AM|MODE_FM) /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 /* * Two calibration sets for the smeter/power readings */ #define FT900_STR_CAL_SMETER { 3, \ { \ { 0, -54 }, /* S0 */ \ {0x44, 0 }, /* S9 */ \ {0x9d, 60 }, /* +60dB */ \ } } #define FT900_STR_CAL_POWER { 5, \ { \ { 0, 0 }, /* 0W */ \ {0x44, 10 }, /* 10W */ \ {0x69, 25 }, /* 25W */ \ {0x92, 50 }, /* 50W */ \ {0xCE, 100 }, /* 100W */ \ } } /* * API local implementation * */ static int ft900_init(RIG *rig); static int ft900_cleanup(RIG *rig); static int ft900_open(RIG *rig); static int ft900_close(RIG *rig); static int ft900_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft900_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft900_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft900_set_vfo(RIG *rig, vfo_t vfo); static int ft900_get_vfo(RIG *rig, vfo_t *vfo); static int ft900_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft900_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft900_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft900_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft900_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft900_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft900_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft900_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private helper function prototypes */ static int ft900_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft900_send_static_cmd(RIG *rig, unsigned char ci); static int ft900_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft900_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft900_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); /* * Native ft900 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set display freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (19 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (18 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (19 bytes) P4 = 0x01-0x20 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* tuner off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* tuner on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* tuner start*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read meter, S on RX, ALC|PO|SWR on TX */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read status flags */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft900_caps.priv? -N0NB */ struct ft900_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT900_ALL_DATA_LENGTH]; /* returned data--max value, some are less */ unsigned char current_mem; /* private memory channel number */ int ptt; /* ptt status needed for meter reading */ }; /* * ft900 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft900_caps = { RIG_MODEL(RIG_MODEL_FT900), .model_name = "FT-900", .mfg_name = "Yaesu", .version = "20241122.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT900_WRITE_DELAY, .post_write_delay = FT900_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_TUNER, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TUNE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 32 */ .rx_range_list1 = { {kHz(100), MHz(30), FT900_ALL_RX_MODES, -1, -1, FT900_VFO_ALL, FT900_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT900_OTHER_TX_MODES, W(5), W(100), FT900_VFO_ALL, FT900_ANTS), FRQ_RNG_HF(1, FT900_AM_TX_MODES, W(2), W(25), FT900_VFO_ALL, FT900_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT900_ALL_RX_MODES, -1, -1, FT900_VFO_ALL, FT900_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT900_OTHER_TX_MODES, W(5), W(100), FT900_VFO_ALL, FT900_ANTS), FRQ_RNG_HF(2, FT900_AM_TX_MODES, W(2), W(25), FT900_VFO_ALL, FT900_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT900_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT900_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT900_AM_RX_MODES, Hz(100)}, /* Normal */ {FT900_AM_RX_MODES, kHz(1)}, /* Fast */ {FT900_FM_RX_MODES, Hz(100)}, /* Normal */ {FT900_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.2)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.2)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft900_init, .rig_cleanup = ft900_cleanup, .rig_open = ft900_open, /* port opened */ .rig_close = ft900_close, /* port closed */ .set_freq = ft900_set_freq, .get_freq = ft900_get_freq, .set_mode = ft900_set_mode, .get_mode = ft900_get_mode, .set_vfo = ft900_set_vfo, .get_vfo = ft900_get_vfo, .set_ptt = ft900_set_ptt, .get_ptt = ft900_get_ptt, .set_split_vfo = ft900_set_split_vfo, .get_split_vfo = ft900_get_split_vfo, .set_rit = ft900_set_rit, .get_rit = ft900_get_rit, .set_func = ft900_set_func, .get_level = ft900_get_level, .vfo_op = ft900_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ static int ft900_init(RIG *rig) { struct ft900_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft900_priv_data *) calloc(1, sizeof(struct ft900_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT900_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ return RIG_OK; } /* * rig_cleanup * * the serial port is closed by the frontend * */ static int ft900_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open * */ static int ft900_open(RIG *rig) { struct ft900_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close * */ static int ft900_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq * * Set frequency for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * If vfo differs from stored value then VFO will be set to the * passed vfo. * */ static int ft900_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft900_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { /* force a VFO change if requested vfo value differs from stored value */ err = ft900_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } err = ft900_send_dial_freq(rig, FT900_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq * * Return Freq for a given VFO * */ static int ft900_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft900_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { err = ft900_get_vfo(rig, &priv->current_vfo); if (err != RIG_OK) { return err; } vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_A_FREQ; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_B_FREQ; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT900_NATIVE_OP_DATA; offset = FT900_SUMO_DISPLAYED_FREQ; count = FT900_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft900_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode * * set mode and passband: eg AM, CW etc for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * */ static int ft900_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft900_priv_data *priv; unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %li Hz\n", __func__, width); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft900 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft900_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } break; case RIG_VFO_B: err = ft900_set_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return err; } break; case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_CW_W; break; case RIG_MODE_USB: mode_parm = MODE_SET_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_FM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: mode %s not supported by FT900\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-900 only supports narrow width in AM and CW modes * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: mode_parm = MODE_SET_CW_N; break; case RIG_MODE_AM: mode_parm = MODE_SET_AM_N; break; default: return -RIG_EINVAL; /* Invalid mode, how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width, how can caller know? */ } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; /* good */ } /* * rig_get_mode * * get mode eg AM, CW etc for a given VFO * */ static int ft900_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft900_priv_data *priv; unsigned char my_mode, m_offset; /* ft900 mode, mode offset */ unsigned char flag, f_offset; /* CW/AM narrow flag */ int err, cmd_index, norm, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT900_NATIVE_VFO_DATA; m_offset = FT900_SUMO_VFO_A_MODE; f_offset = FT900_SUMO_VFO_A_FLAG; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_DATA; m_offset = FT900_SUMO_VFO_B_MODE; f_offset = FT900_SUMO_VFO_B_FLAG; count = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT900_NATIVE_OP_DATA; m_offset = FT900_SUMO_DISPLAYED_MODE; f_offset = FT900_SUMO_DISPLAYED_FLAG; count = FT900_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; } err = ft900_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } my_mode = MODE_MASK & priv->update_data[m_offset]; flag = FLAG_MASK & priv->update_data[f_offset]; rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: flag = 0x%02x\n", __func__, flag); /* * translate mode from ft900 to generic. */ switch (my_mode) { case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_CW: *mode = RIG_MODE_CW; if (flag & FLAG_CW_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_AM: *mode = RIG_MODE_AM; if (flag & FLAG_AM_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft900_set_vfo(RIG *rig, vfo_t vfo) { struct ft900_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* FIXME: Include support for RIG_VFO_MAIN */ switch (vfo) { case RIG_VFO_A: cmd_index = FT900_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_B; priv->current_vfo = vfo; break; case RIG_VFO_MEM: /* reset to memory channel stored by previous get_vfo * The recall mem channel command uses 0x01 though 0x20 */ err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_RECALL_MEM, (priv->current_mem + 1), 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->current_mem); return RIG_OK; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ static int ft900_get_vfo(RIG *rig, vfo_t *vfo) { struct ft900_priv_data *priv; unsigned char status_0; /* ft900 status flag 0 */ unsigned char stat_vfo, stat_mem; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft900_get_update_data(rig, FT900_NATIVE_READ_FLAGS, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT900_SUMO_DISPLAYED_STATUS_0]; stat_vfo = status_0 & SF_VFO_MASK; /* get VFO active bits */ stat_mem = status_0 & SF_MEM_MASK; /* get MEM active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, stat_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: stat_mem = 0x%02x\n", __func__, stat_mem); /* * translate vfo and mem status from ft900 to generic. * * First a test is made on bits 6 and 7 of status_0. Bit 7 is set * when FT-900 is in VFO mode on display. Bit 6 is set when VFO B * is active and cleared when VFO A is active. * * Conversely, bit 7 is cleared when MEM or MEM TUNE mode is selected * Bit 6 still follows last selected VFO (A or B), but this is not * tested right now. */ switch (stat_vfo) { case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; default: switch (stat_mem) { case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; /* * Per Hamlib policy capture and store memory channel number * for future set_vfo command. */ err = ft900_get_update_data(rig, FT900_NATIVE_MEM_CHNL, FT900_MEM_CHNL_LENGTH); if (err != RIG_OK) { return err; } priv->current_mem = priv->update_data[FT900_SUMO_MEM_CHANNEL]; rig_debug(RIG_DEBUG_TRACE, "%s: stored mem channel = 0x%02x\n", __func__, priv->current_mem); break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_ptt * * set the '900 into TX mode * * vfo is respected by calling ft900_set_vfo if * passed vfo != priv->current_vfo * */ static int ft900_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft900_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft900_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT900_NATIVE_PTT_OFF; priv->ptt = 0; break; case RIG_PTT_ON: cmd_index = FT900_NATIVE_PTT_ON; priv->ptt = 1; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt * * get current PTT status * */ static int ft900_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft900_priv_data *priv; unsigned char status_2; /* ft900 status flag 2 */ unsigned char stat_ptt; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft900_get_update_data(rig, FT900_NATIVE_READ_FLAGS, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_2 = priv->update_data[FT900_SUMO_DISPLAYED_STATUS_2]; stat_ptt = status_2 & SF_PTT_MASK; /* get PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: ptt status_2 = 0x%02x\n", __func__, status_2); switch (stat_ptt) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } priv->ptt = *ptt; return RIG_OK; } /* * rig_set_split_vfo * * set the '900 into split TX/RX mode * * VFO cannot be set as the set split on command only changes the * TX to the other VFO. Setting split off returns the TX to the * main display. * */ static int ft900_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT900_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT900_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo * * Get whether the '900 is in split mode * * vfo value is not used * */ static int ft900_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft900_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft900_get_update_data(rig, FT900_NATIVE_READ_FLAGS, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* get Split active bit */ status_0 = SF_SPLIT & priv->update_data[FT900_SUMO_DISPLAYED_STATUS_0]; rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLIT: *split = RIG_SPLIT_ON; break; default: *split = RIG_SPLIT_OFF; break; } return RIG_OK; } /* * rig_set_rit * * VFO and MEM rit values are independent. * * passed vfo value is respected. * * Clarifier offset is retained in the rig for either VFO when the * VFO is changed. Offset is not retained when in memory tune mode * and VFO mode is selected or another memory channel is selected. * */ static int ft900_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft900_priv_data *priv; // unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9990 || rit > 9990) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); priv = (struct ft900_priv_data *)STATE(rig)->priv; /* * The assumption here is that the user hasn't changed * the VFO manually. Does it really need to be checked * every time? My goal is to reduce the traffic on the * serial line to a minimum, but respect the application's * request to change the VFO with this call. * */ if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous rig_get_vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft900_set_vfo(rig, vfo); } /* * Shuts clarifier off but does not set frequency to 0 Hz */ if (rit == 0) { err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_CLARIFIER_OPS, CLAR_RX_OFF, 0, 0, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: clarifier off error: %s\n", __func__, rigerror(err)); } return err; } /* * Clarifier must first be turned on then the frequency can * be set, +9990 Hz to -9990 Hz */ err = ft900_send_dynamic_cmd(rig, FT900_NATIVE_CLARIFIER_OPS, CLAR_RX_ON, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft900_send_rit_freq(rig, FT900_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rit * * Rig returns offset as hex from 0x0000 to 0x03e7 for 0 to +9.990 kHz * and 0xffff to 0xfc19 for -1 to -9.990 kHz * */ static int ft900_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft900_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index, length; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: cmd_index = FT900_NATIVE_OP_DATA; offset = FT900_SUMO_DISPLAYED_CLAR; length = FT900_OP_DATA_LENGTH; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_A_CLAR; length = FT900_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT900_NATIVE_VFO_DATA; offset = FT900_SUMO_VFO_B_CLAR; length = FT900_VFO_DATA_LENGTH; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft900_get_update_data(rig, cmd_index, length); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; /* returned value is hex to nearest hundred Hz */ if (f > 0xfc18) /* 0xfc19 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f * 10); *rit = f * 10; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_func * * set the '900 supported functions * * vfo is ignored for tuner as it is an independent function * */ static int ft900_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %i\n", __func__, status); switch (func) { case RIG_FUNC_TUNER: switch (status) { case OFF: cmd_index = FT900_NATIVE_TUNER_OFF; break; case ON: cmd_index = FT900_NATIVE_TUNER_ON; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_level * * get the '900 meter level * * vfo is ignored for now * * Meter level returned from FT-900 is S meter when rig is in RX * Meter level returned is one of ALC or PO or SWR when rig is in TX * depending on front panel meter selection. Meter selection is NOT * available via CAT. * * TODO: Add support for TX values * */ static int ft900_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft900_priv_data *priv; unsigned char *p; int err; cal_table_t cal = FT900_STR_CAL_SMETER; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed level = %s\n", __func__, rig_strlevel(level)); priv = (struct ft900_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: err = ft900_get_update_data(rig, FT900_NATIVE_READ_METER, FT900_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[FT900_SUMO_METER]; /* * My FT-900 returns a range of 0x00 to 0x44 for S0 to S9 and 0x44 to * 0x9d for S9 to S9 +60 * * For ease of calculation I rounded S9 up to 0x48 (72 decimal) and * S9 +60 up to 0xa0 (160 decimal). I calculated a divisor for readings * less than S9 by dividing 72 by 54 and the divisor for readings greater * than S9 by dividing 88 (160 - 72) by 60. The result tracks rather well. * * The greatest error is around S1 and S2 and then from S9 to S9 +35. Such * is life when mapping non-linear S-meters to a linear scale. * */ if (priv->ptt) { cal = (cal_table_t)FT900_STR_CAL_POWER; } val->i = (int)rig_raw2val(*p, &cal); rig_debug(RIG_DEBUG_TRACE, "%s: calculated level = %i\n", __func__, val->i); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op * * VFO operations--tuner start, etc * * vfo is ignored for now * */ static int ft900_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed op = 0x%02x\n", __func__, op); switch (op) { case RIG_OP_TUNE: cmd_index = FT900_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; } err = ft900_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * ************************************ * * Private functions to ft900 backend * * ************************************ */ /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 900 has several ways to * get data and several ways to return it. * * Need to use this when doing ft900_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft900_priv_data *priv; int err; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft900_priv_data *)STATE(rig)->priv; err = ft900_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft900_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft900_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft900_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT900_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT900_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ static int ft900_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft900_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft900_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT900_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %ld Hz\n", __func__, (long)from_bcd(priv->p_cmd, FT900_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft857.c0000644000175000017500000011627214752216205013030 00000000000000/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- * * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft857.h - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * * ...derived but heavily modified from: * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-857 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Unimplemented features supported by the FT-857: * * - DCS encoder/squelch ON/OFF, similar to RIG_FUNC_TONE/TSQL. * Needs frontend support. * * - RX status command returns info that is not used: * * - discriminator centered (yes/no flag) * - received ctcss/dcs matched (yes/no flag) * * - TX status command returns info that is not used: * * - high swr flag * * The manual also indicates that CTCSS and DCS codes can be set * separately for tx and rx, but this doesn't seem to work. It * doesn't work from front panel either. */ #include #include /* String function definitions */ #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft857.h" #include "ft817.h" /* We use functions from the 817 code */ #include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" enum ft857_native_cmd_e { FT857_NATIVE_CAT_LOCK_ON = 0, FT857_NATIVE_CAT_LOCK_OFF, FT857_NATIVE_CAT_PTT_ON, FT857_NATIVE_CAT_PTT_OFF, FT857_NATIVE_CAT_SET_FREQ, FT857_NATIVE_CAT_SET_MODE_LSB, FT857_NATIVE_CAT_SET_MODE_USB, FT857_NATIVE_CAT_SET_MODE_CW, FT857_NATIVE_CAT_SET_MODE_CWR, FT857_NATIVE_CAT_SET_MODE_AM, FT857_NATIVE_CAT_SET_MODE_FM, FT857_NATIVE_CAT_SET_MODE_FM_N, FT857_NATIVE_CAT_SET_MODE_DIG, FT857_NATIVE_CAT_SET_MODE_PKT, FT857_NATIVE_CAT_CLAR_ON, FT857_NATIVE_CAT_CLAR_OFF, FT857_NATIVE_CAT_SET_CLAR_FREQ, FT857_NATIVE_CAT_SET_VFOAB, FT857_NATIVE_CAT_SPLIT_ON, FT857_NATIVE_CAT_SPLIT_OFF, FT857_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT857_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT857_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT857_NATIVE_CAT_SET_RPT_OFFSET, FT857_NATIVE_CAT_SET_DCS_ON, FT857_NATIVE_CAT_SET_DCS_DEC_ON, FT857_NATIVE_CAT_SET_DCS_ENC_ON, FT857_NATIVE_CAT_SET_CTCSS_ON, FT857_NATIVE_CAT_SET_CTCSS_DEC_ON, FT857_NATIVE_CAT_SET_CTCSS_ENC_ON, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF, FT857_NATIVE_CAT_SET_CTCSS_FREQ, FT857_NATIVE_CAT_SET_DCS_CODE, FT857_NATIVE_CAT_GET_RX_STATUS, FT857_NATIVE_CAT_GET_TX_STATUS, FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT857_NATIVE_CAT_PWR_WAKE, FT857_NATIVE_CAT_PWR_ON, FT857_NATIVE_CAT_PWR_OFF, FT857_NATIVE_CAT_EEPROM_READ, FT857_NATIVE_SIZE /* end marker */ }; static int ft857_init(RIG *rig); static int ft857_open(RIG *rig); static int ft857_cleanup(RIG *rig); static int ft857_close(RIG *rig); static int ft857_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft857_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft857_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft857_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft857_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int ft857_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static int ft857_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft857_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); // static int ft857_set_vfo(RIG *rig, vfo_t vfo); // static int ft857_get_vfo(RIG *rig, vfo_t *vfo); static int ft857_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft857_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); // static int ft857_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ft857_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft857_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); // static int ft857_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); // static int ft857_set_parm(RIG *rig, setting_t parm, value_t val); // static int ft857_get_parm(RIG *rig, setting_t parm, value_t *val); static int ft857_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft857_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t code); static int ft857_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft857_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft857_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft857_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft857_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft857_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft857_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); // static int ft857_set_powerstat(RIG *rig, powerstat_t status); struct ft857_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[YAESU_CMD_LENGTH + 1]; }; /* Native ft857 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x88 } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM-N */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main DIG */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main PKT */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* clar on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf5 } }, /* set clar freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* split off */ { 1, { 0x09, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 1, { 0x49, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift PLUS */ { 1, { 0x89, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on */ { 1, { 0x0b, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS decoder on */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS encoder on */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS on */ { 1, { 0x3a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS decoder on */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS encoder on */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status */ { 1, { 0xff, 0xff, 0xff, 0xff, 0xff } }, /* pwr wakeup sequence */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* pwr on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8f } }, /* pwr off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbb } }, /* eeprom read */ }; enum ft857_digi { FT857_DIGI_RTTY_L = 0, FT857_DIGI_RTTY_U, FT857_DIGI_PSK_L, FT857_DIGI_PSK_U, FT857_DIGI_USER_L, FT857_DIGI_USER_U, }; #define FT857_PWR_CAL { 9, \ { \ { 0x00, 0.0f }, \ { 0x01, 10.0f }, \ { 0x02, 15.0f }, \ { 0x03, 20.0f }, \ { 0x04, 34.0f }, \ { 0x05, 50.0f }, \ { 0x06, 66.0f }, \ { 0x07, 82.f }, \ { 0x08, 100.0f } \ } } #define FT857_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT857_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB) #define FT857_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) #define FT857_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB) #define FT857_AM_TX_MODES (RIG_MODE_AM) #define FT857_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT857_ANTS 0 static int ft857_send_icmd(RIG *rig, int index, const unsigned char *data); struct rig_caps ft857_caps = { RIG_MODEL(RIG_MODEL_FT857), .model_name = "FT-857", .mfg_name = "Yaesu", .version = "20230206.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT857_WRITE_DELAY, .post_write_delay = FT857_POST_WRITE_DELAY, .timeout = FT857_TIMEOUT, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RFPOWER | RIG_LEVEL_RFPOWER_METER_WATTS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .vfo_ops = RIG_OP_TOGGLE, .rx_range_list1 = { {kHz(100), MHz(56), FT857_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT857_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT857_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT857_OTHER_TX_MODES, W(10), W(100), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_6m(1, FT857_OTHER_TX_MODES, W(10), W(100), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_HF(1, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_6m(1, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_2m(1, FT857_OTHER_TX_MODES, W(5), W(50), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_2m(1, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_70cm(1, FT857_OTHER_TX_MODES, W(2), W(20), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_70cm(1, FT857_AM_TX_MODES, W(0.5), W(5), FT857_VFO_ALL, FT857_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT857_ALL_RX_MODES, -1, -1}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1}, {MHz(118), MHz(164), FT857_ALL_RX_MODES, -1, -1}, {MHz(420), MHz(470), FT857_ALL_RX_MODES, -1, -1}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT857_OTHER_TX_MODES, W(10), W(100), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_HF(2, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_2m(2, FT857_OTHER_TX_MODES, W(5), W(50), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_2m(2, FT857_AM_TX_MODES, W(2.5), W(25), FT857_VFO_ALL, FT857_ANTS), FRQ_RNG_70cm(2, FT857_OTHER_TX_MODES, W(2), W(20), FT857_VFO_ALL, FT857_ANTS), /* AM class */ FRQ_RNG_70cm(2, FT857_AM_TX_MODES, W(0.5), W(5), FT857_VFO_ALL, FT857_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT857_SSB_CW_RX_MODES, 10}, {FT857_SSB_CW_RX_MODES, 100}, {FT857_AM_FM_RX_MODES, 10}, {FT857_AM_FM_RX_MODES, 100}, RIG_TS_END, }, /* filter selection is not supported by CAT functions * per testing by Rich Newsom, WA4SXZ */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, // {RIG_MODE_SSB, kHz(2.2)}, // {RIG_MODE_CW, kHz(2.2)}, // {RIG_MODE_CWR, kHz(2.2)}, // {RIG_MODE_RTTY, kHz(2.2)}, // {RIG_MODE_AM, kHz(6)}, // {RIG_MODE_FM, kHz(15)}, // {RIG_MODE_PKTFM, kHz(15)}, // {RIG_MODE_FM, kHz(9)}, // {RIG_MODE_PKTFM, kHz(9)}, // {RIG_MODE_WFM, kHz(230)}, /* ?? */ RIG_FLT_END, }, .rfpower_meter_cal = FT857_PWR_CAL, .rig_init = ft857_init, .rig_cleanup = ft857_cleanup, .rig_open = ft857_open, .rig_close = ft857_close, .get_vfo = ft857_get_vfo, .set_vfo = ft857_set_vfo, .set_freq = ft857_set_freq, .get_freq = ft857_get_freq, .set_mode = ft857_set_mode, .get_mode = ft857_get_mode, .set_ptt = ft857_set_ptt, .get_ptt = ft857_get_ptt, .get_dcd = ft857_get_dcd, .set_rptr_shift = ft857_set_rptr_shift, .set_rptr_offs = ft857_set_rptr_offs, .set_split_freq_mode = ft857_set_split_freq_mode, .get_split_freq_mode = ft857_get_split_freq_mode, .set_split_vfo = ft857_set_split_vfo, .get_split_vfo = ft857_get_split_vfo, .set_rit = ft857_set_rit, .set_dcs_code = ft857_set_dcs_code, .set_ctcss_tone = ft857_set_ctcss_tone, .set_dcs_sql = ft857_set_dcs_sql, .set_ctcss_sql = ft857_set_ctcss_sql, .set_powerstat = ft817_set_powerstat, .get_level = ft857_get_level, .set_func = ft857_set_func, .vfo_op = ft857_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ---------------------------------------------------------------------- */ int ft857_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if ((STATE(rig)->priv = calloc(1, sizeof(struct ft857_priv_data))) == NULL) { return -RIG_ENOMEM; } return RIG_OK; } int ft857_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } int ft857_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft857_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s:called\n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } static int check_cache_timeout(struct timeval *tv) { struct timeval curr; long t; if (tv->tv_sec == 0 && tv->tv_usec == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache invalid\n", __func__); return 1; } gettimeofday(&curr, NULL); if ((t = timediff(&curr, tv)) < FT857_CACHE_TIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "ft857: using cache (%ld ms)\n", t); return 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "ft857: cache timed out (%ld ms)\n", t); return 1; } } static int ft857_read_eeprom(RIG *rig, unsigned short addr, unsigned char *out) { unsigned char data[YAESU_CMD_LENGTH]; hamlib_port_t *rp = RIGPORT(rig); int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); memcpy(data, (char *)ncmd[FT857_NATIVE_CAT_EEPROM_READ].nseq, YAESU_CMD_LENGTH); data[0] = addr >> 8; data[1] = addr & 0xfe; write_block(rp, data, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, 2)) < 0) { return n; } if (n != 2) { return -RIG_EIO; } *out = data[addr % 2]; return RIG_OK; } static int ft857_get_status(RIG *rig, int status) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); struct timeval *tv; unsigned char *data; int len; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (status) { case FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS: data = p->fm_status; len = YAESU_CMD_LENGTH; tv = &p->fm_status_tv; break; case FT857_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; tv = &p->rx_status_tv; break; case FT857_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; tv = &p->tx_status_tv; break; default: rig_debug(RIG_DEBUG_ERR, "%s: internal error!\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); write_block(rp, ncmd[status].nseq, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, len)) < 0) { return n; } if (n != len) { return -RIG_EIO; } if (status == FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS) { if ((n = ft857_read_eeprom(rig, 0x0078, &p->fm_status[5])) < 0) { return n; } p->fm_status[5] >>= 5; } gettimeofday(tv, NULL); return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete sequences. */ static int ft857_send_cmd(RIG *rig, int index) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (ncmd[index].ncomp == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: incomplete sequence\n", __func__); return -RIG_EINTERNAL; } write_block(RIGPORT(rig), ncmd[index].nseq, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* * The same for incomplete commands. */ static int ft857_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* ---------------------------------------------------------------------- */ int ft857_get_vfo(RIG *rig, vfo_t *vfo) { unsigned char c; static int ignore = 0; *vfo = RIG_VFO_B; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); // Some 857's cannot read so we'll just return the cached value if we've seen an error if (ignore) { *vfo = CACHE(rig)->vfo; return RIG_OK; } if (ft857_read_eeprom(rig, 0x0068, &c) < 0) /* get vfo status */ { ignore = 1; *vfo = CACHE(rig)->vfo; return RIG_OK; } if ((c & 0x1) == 0) { *vfo = RIG_VFO_A; } return RIG_OK; } int ft857_set_vfo(RIG *rig, vfo_t vfo) { vfo_t curvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); ft857_get_vfo(rig, &curvfo); // retval is always RIG_OK so ignore it if (curvfo == vfo) { return RIG_OK; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); } int ft857_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } *freq = from_bcd_be(p->fm_status, 8) * 10; return -RIG_OK; } static void get_mode(RIG *rig, const struct ft857_priv_data *priv, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (priv->fm_status[4] & 0x7f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x06: *mode = RIG_MODE_WFM; break; case 0x08: *mode = RIG_MODE_FM; break; case 0x0a: switch (priv->fm_status[5]) { case FT857_DIGI_RTTY_L: *mode = RIG_MODE_RTTY; break; case FT857_DIGI_RTTY_U: *mode = RIG_MODE_RTTYR; break; case FT857_DIGI_PSK_L: *mode = RIG_MODE_PKTLSB; break; case FT857_DIGI_PSK_U: *mode = RIG_MODE_PKTUSB; break; case FT857_DIGI_USER_L: *mode = RIG_MODE_PKTLSB; break; case FT857_DIGI_USER_U: *mode = RIG_MODE_PKTUSB; break; } break; case 0x0c: *mode = RIG_MODE_PKTFM; break; default: *mode = RIG_MODE_NONE; } if (priv->fm_status[4] & 0x80) /* narrow */ { *width = rig_passband_narrow(rig, *mode); } else { *width = RIG_PASSBAND_NORMAL; } } int ft857_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } get_mode(rig, p, mode, width); return RIG_OK; } int ft857_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retcode; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); retcode = ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); if (RIG_OK != retcode) { return retcode; } retcode = ft857_get_freq(rig, RIG_VFO_CURR, freq); if (RIG_OK == retcode) { get_mode(rig, (struct ft857_priv_data *)STATE(rig)->priv, mode, width); } ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); /* always try and return to orig VFO */ return retcode; } int ft857_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->tx_status_tv)) if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } if (p->tx_status & 0x80) { // TX status not valid when in RX unsigned char c; if ((n = ft857_read_eeprom(rig, 0x008d, &c)) < 0) /* get split status */ { return n; } *split = (c & 0x80) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } else { *split = (p->tx_status & 0x20) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; } return RIG_OK; } int ft857_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } *ptt = ((p->tx_status & 0x80) == 0); return RIG_OK; } static int ft857_get_pometer_level(RIG *rig, value_t *val, const cal_table_float_t *cal, float divider) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } /* Valid only if PTT is on */ if ((p->tx_status & 0x80) == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: bars=%d\n", __func__, p->tx_status & 0x0F); // does rig have 10 bars or 15? val->f = rig_raw2val_float(p->tx_status & 0x0F, cal) / divider; } else { val->f = 0; // invalid value return } return RIG_OK; } static int ft857_get_smeter_level(RIG *rig, value_t *val) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } n = (p->rx_status & 0x0F); // S level returned if (n >= 9) { val->i = (n - 9) * 10; } else { val->i = n * 6 - 54; } return RIG_OK; } int ft857_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); freq_t freq; rmode_t mode; pbwidth_t width; int freq_ms, mode_ms, width_ms; switch (level) { case RIG_LEVEL_STRENGTH: return ft857_get_smeter_level(rig, val); case RIG_LEVEL_RFPOWER: case RIG_LEVEL_RFPOWER_METER_WATTS: rig_get_cache(rig, vfo, &freq, &freq_ms, &mode, &mode_ms, &width, &width_ms); if (144000000.0f >= freq && 148000000.0f <= freq) { return ft857_get_pometer_level(rig, val, &rig->caps->rfpower_meter_cal, 2.0); } else if (420000000.0f >= freq && 450000000.0f <= freq) { return ft857_get_pometer_level(rig, val, &rig->caps->rfpower_meter_cal, 5.0); } return ft857_get_pometer_level(rig, val, &rig->caps->rfpower_meter_cal, 1.0); default: return -RIG_EINVAL; } return RIG_OK; } int ft857_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft857_priv_data *p = (struct ft857_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft857_get_status(rig, FT857_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } int ft857_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[YAESU_CMD_LENGTH - 1]; int i; ptt_t ptt = RIG_PTT_ON; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: requested freq = %"PRIfreq" Hz\n", freq); // cannot set freq while PTT is on for (i = 0; i < 10 && ptt == RIG_PTT_ON; ++i) { int retval = ft857_get_ptt(rig, vfo, &ptt); if (retval != RIG_OK) { return retval; } hl_usleep(100 * 1000); } /* fill in the frequency */ to_bcd_be(data, (freq + 5) / 10, 8); rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_FREQ, data); } int ft857_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: index = FT857_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: index = FT857_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_USB: index = FT857_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: index = FT857_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_RTTY: case RIG_MODE_PKTUSB: /* user has to have correct DIG mode setup on rig */ index = FT857_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_FM: index = FT857_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_WFM: index = FT857_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_CWR: index = FT857_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_PKTFM: index = FT857_NATIVE_CAT_SET_MODE_PKT; break; default: return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL) { return -RIG_EINVAL; } rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->fm_status_tv); return ft857_send_cmd(rig, index); } int ft857_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retcode; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); retcode = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retcode != RIG_OK) { return retcode; } retcode = ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); if (RIG_OK != retcode) { return retcode; } retcode = ft857_set_freq(rig, RIG_VFO_CURR, freq); if (RIG_OK == retcode) { retcode = ft857_set_mode(rig, RIG_VFO_CURR, mode, width); } ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); /* always try and return to orig VFO */ return retcode; } int ft857_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (split) { case RIG_SPLIT_ON: index = FT857_NATIVE_CAT_SPLIT_ON; break; case RIG_SPLIT_OFF: index = FT857_NATIVE_CAT_SPLIT_OFF; break; default: return -RIG_EINVAL; } n = ft857_send_cmd(rig, index); rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft857_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (ptt) { case RIG_PTT_ON: index = FT857_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: index = FT857_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } n = ft857_send_cmd(rig, index); if (ptt == RIG_PTT_OFF) { hl_usleep(200 * 1000); } // FT857 takes a bit to come out of PTT rig_force_cache_timeout(&((struct ft857_priv_data *) STATE(rig)->priv)->tx_status_tv); if (n < 0 && n != -RIG_ERJCTED) { return n; } return RIG_OK; } int ft857_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_LOCK_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_OFF); } #if 0 case RIG_FUNC_CODE: /* this doesn't exist */ if (status) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ENC_ON); } else { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } #endif default: return -RIG_EINVAL; } } int ft857_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set DCS code (%u)\n", code); if (code == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ENC_ON); } int ft857_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ENC_ON); } int ft857_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set DCS sql (%u)\n", code); if (code == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_DCS_ON); } int ft857_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_CTCSS_ON); } int ft857_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set repeter shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } int ft857_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set repeter offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_RPT_OFFSET, data); } int ft857_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "ft857: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = ft857_send_icmd(rig, FT857_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_OFF); } else { ft857_send_cmd(rig, FT857_NATIVE_CAT_CLAR_ON); }*/ return RIG_OK; } int ft857_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); switch (op) { case RIG_OP_TOGGLE: return ft857_send_cmd(rig, FT857_NATIVE_CAT_SET_VFOAB); default: return -RIG_EINVAL; } return -RIG_EINVAL; } /* ---------------------------------------------------------------------- */ hamlib-4.6.2/rigs/yaesu/ftdx10.h0000644000175000017500000001155314752216205013262 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx10.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Mikael Nousiainen 2020 * (C) Michael Black W9MDB 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX10(D/MP) using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FTDX10_H #define _FTDX10_H 1 #define FTDX10_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FTDX10_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX10_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX10_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FTDX10_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX10_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX10_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) /* 100 W class */ #define FTDX10_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FTDX10_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FTDX10_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) /* TBC */ #define FTDX10_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FTDX10_RFPOWER_METER_CAL \ { \ 5, \ { \ {27, 5.0f}, \ {94, 25.0f}, \ {147, 50.0f}, \ {176, 75.0f}, \ {205, 100.0f}, \ } \ } // Based on testing with G3VPX Ian Sumner for the FTDX101D #define FTDX10_SWR_CAL \ { \ 8, \ { \ {0, 1.0f}, \ {26, 1.2f}, \ {52, 1.5f}, \ {89, 2.0f}, \ {126, 3.0f}, \ {173, 4.0f}, \ {236, 5.0f}, \ {255, 25.0f}, \ } \ } /* * Other features (used by rig_caps) */ #define FTDX10_TX_ANTS RIG_ANT_CURR #define FTDX10_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX10_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX10_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX10_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX10_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX10_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ /* Delay between bytes sent * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FTDX10_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX10_POST_WRITE_DELAY 5 #endif /* _FTDX10_H */ hamlib-4.6.2/rigs/yaesu/pmr171.c0000644000175000017500000011102514752216205013171 00000000000000/* * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * pmr171.c - borrowed from ft817.c * (C) Michael Black W9MDB 2024 * This shared library provides an API for communicating * via serial interface to an Guohe PMR-171 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * Then, Tommi OH2BNS improved the code a lot in the framework of the * FT-857 backend. These improvements have now (August 2005) been * copied back and adopted for the FT-817 which has then been borrowed * for the PMR-171. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" //#include "pmr171.h" #include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" struct pmr171_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* Raw data from rig. Highest bit 0 = PTT */ /* tx levels */ struct timeval tx_level_tv; unsigned char swr_level; unsigned char alc_level; unsigned char mod_level; unsigned char pwr_level; /* TX power level */ /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[5]; /* 5 bytes, NOT related to YAESU_CMD_LENGTH */ /* Digi mode is not part of regular fm_status response. * So keep track of it in a separate variable. */ unsigned char dig_mode; }; static int pmr171_init(RIG *rig); static int pmr171_open(RIG *rig); static int pmr171_cleanup(RIG *rig); static int pmr171_close(RIG *rig); static int pmr171_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int pmr171_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int pmr171_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int pmr171_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int pmr171_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int pmr171_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int pmr171_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int pmr171_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int pmr171_set_powerstat(RIG *rig, powerstat_t status); #if 0 static int pmr171_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int pmr171_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int pmr171_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int pmr171_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int pmr171_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int pmr171_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int pmr171_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int pmr171_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int pmr171_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int pmr171_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int pmr171_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int pmr171_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int pmr171_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); #endif #define FT817_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PKTFM|\ RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY) #define FT817_CWN_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY) #define FT817_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT817_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_AM_TX_MODES (RIG_MODE_AM) #define FT817_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT817_ANT_FRONT (RIG_ANT_1) #define FT817_ANT_REAR (RIG_ANT_2) #define FT817_ANTS (FT817_ANT_FRONT | FT817_ANT_REAR) #define FT817_STR_CAL { 16, \ { \ { 0x00, -54 }, /* S0 */ \ { 0x01, -48 }, \ { 0x02, -42 }, \ { 0x03, -36 }, \ { 0x04, -30 }, \ { 0x05, -24 }, \ { 0x06, -18 }, \ { 0x07, -12 }, \ { 0x08, -6 }, \ { 0x09, 0 }, /* S9 */ \ { 0x0A, 10 }, /* +10 */ \ { 0x0B, 20 }, /* +20 */ \ { 0x0C, 30 }, /* +30 */ \ { 0x0D, 40 }, /* +40 */ \ { 0x0E, 50 }, /* +50 */ \ { 0x0F, 60 } /* +60 */ \ } } // Thanks to Olivier Schmitt sc.olivier@gmail.com for these tables #define FT817_PWR_CAL { 9, \ { \ { 0x00, 0 }, \ { 0x01, 10 }, \ { 0x02, 14 }, \ { 0x03, 20 }, \ { 0x04, 34 }, \ { 0x05, 50 }, \ { 0x06, 66 }, \ { 0x07, 82 }, \ { 0x08, 100 } \ } } #define FT817_ALC_CAL { 6, \ { \ { 0x00, 0 }, \ { 0x01, 20 }, \ { 0x02, 40 }, \ { 0x03, 60 }, \ { 0x04, 80 }, \ { 0x05, 100 } \ } } #define FT817_SWR_CAL { 2, \ { \ { 0, 0 }, \ { 15, 100 } \ } } // similar to FT817 but with header and CRC check struct rig_caps pmr171_caps = { RIG_MODEL(RIG_MODEL_PMR171), .model_name = "PMR-171", .mfg_name = "Guohe", .version = "20240704.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 2, .has_get_func = RIG_FUNC_NONE, // .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, // .has_get_level = // RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | // RIG_LEVEL_ALC | RIG_LEVEL_SWR, // .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* FIXME: 60 meters in US version */ FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = pmr171_init, .rig_cleanup = pmr171_cleanup, .rig_open = pmr171_open, .rig_close = pmr171_close, // .get_vfo = pmr171_get_vfo, // .set_vfo = pmr171_set_vfo, .set_freq = pmr171_set_freq, .get_freq = pmr171_get_freq, // using cache for now until we determine timing .set_mode = pmr171_set_mode, .get_mode = pmr171_get_mode, // using cache for now until we determine timing .set_ptt = pmr171_set_ptt, .get_ptt = pmr171_get_ptt, .set_split_vfo = pmr171_set_split_vfo, .get_split_vfo = pmr171_get_split_vfo, // TBD .set_powerstat = pmr171_set_powerstat, #if 0 .get_dcd = pmr171_get_dcd, .set_rptr_shift = pmr171_set_rptr_shift, .set_rptr_offs = pmr171_set_rptr_offs, .set_rit = pmr171_set_rit, .set_dcs_code = pmr171_set_dcs_code, .set_ctcss_tone = pmr171_set_ctcss_tone, .set_dcs_sql = pmr171_set_dcs_sql, .set_ctcss_sql = pmr171_set_ctcss_sql, .power2mW = pmr171_power2mW, .mW2power = pmr171_mW2power, .get_level = pmr171_get_level, .set_func = pmr171_set_func, .vfo_op = pmr171_vfo_op, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; //**************************************************** //** Function name: CRC16Check -- from the PMR-171 manual //** Input: buf The data to verify; //** len The length of the data to verify //** Output: Check value //** Function description: CRC16 cyclic redundancy check //** Note: The check mode is CRC16/CCITT-FALSE, pay attention to the variable type //*****************************************************/ #include uint16_t CRC16Check(const unsigned char *buf, int len) { uint16_t crc = 0xFFFF; // Initial value uint16_t polynomial = 0x1021; // Polynomial x^16 + x^12 + x^5 + 1 for (int i = 0; i < len; i++) { crc ^= ((uint16_t)buf[i] << 8); // XOR byte into the upper 8 bits of crc for (int j = 0; j < 8; j++) { if (crc & 0x8000) { crc = (crc << 1) ^ polynomial; } else { crc = crc << 1; } } } return crc; } #if 0 // manual's method does not compute the correct CRC // some day when I'm bored I'll debug this unsigned int CRC16Checkx(unsigned char *buf, unsigned char len) { unsigned char i, j; unsigned int uncrcReg = 0xFFFF; unsigned int uncur; for (i = 0; i < len; i++) { uncur = buf[i] << 8; printf("buf[%d]=x%04x\n", i, uncur); for (j = 0; j < 8; j++) { if ((int)(uncrcReg ^ uncur) < 0) { uncrcReg = (uncrcReg << 1) ^ 0x1021; } else { uncrcReg <<= 1; } uncur <<= 1; } } printf("CRC=%04x\n", uncrcReg); return uncrcReg; } #endif /* ---------------------------------------------------------------------- */ static int pmr171_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called, version %s\n", __func__, rig->caps->version); if ((STATE(rig)->priv = calloc(1, sizeof(struct pmr171_priv_data))) == NULL) { return -RIG_ENOMEM; } CACHE(rig)->freqMainA = 14999000; CACHE(rig)->freqMainB = 14999000; return RIG_OK; } static int pmr171_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } static int pmr171_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } static int pmr171_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ #if 0 static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } #endif static int pmr171_send_cmd1(RIG *rig, unsigned char cmd, unsigned char *reply) { hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); unsigned char buf[8] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x03, 0x00, 0x00, 0x00 }; buf[5] = cmd; unsigned int crc = CRC16Check(&buf[4], 2); buf[6] = crc >> 8; buf[7] = crc & 0xff; rig_flush(rp); write_block(rp, buf, 8); return RIG_OK; } #define GUOHE_MODE_TABLE_MAX 9 rmode_t pmr171_modes[GUOHE_MODE_TABLE_MAX] = { RIG_MODE_USB, RIG_MODE_LSB, RIG_MODE_CWR, RIG_MODE_CW, RIG_MODE_AM, RIG_MODE_FM, RIG_MODE_FMN, RIG_MODE_PKTUSB, RIG_MODE_RTTY // not functioning }; rmode_t guohe2rmode(unsigned char mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=0x%02x\n", __func__, mode); if (mode >= GUOHE_MODE_TABLE_MAX) { return (RIG_MODE_NONE); } rig_debug(RIG_DEBUG_VERBOSE, "%s: returning %s\n", __func__, rig_strrmode(mode_table[mode])); return (mode_table[mode]); } unsigned char rmode2guohe(rmode_t mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=%s\n", __func__, rig_strrmode(mode)); if (mode != RIG_MODE_NONE) { unsigned char i; for (i = 0; i < GUOHE_MODE_TABLE_MAX; i++) { if (mode_table[i] == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: returning 0x%02x\n", __func__, i); return (i); } } } return (-1); } /** * Converting to Big-endian bytes */ unsigned char *to_be(unsigned char data[], unsigned long long freq, unsigned int byte_len) { int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = byte_len - 1; i >= 0; i--) { unsigned char a = freq & 0xFF; freq >>= 8; data[i] = a; } return data; } unsigned long long from_be(const unsigned char data[], unsigned int byte_len) { int i; unsigned long long f = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); for (i = 0; i < byte_len; i++) { f = (f << 8) + data[i]; } return f; } static int pmr171_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct rig_cache *cachep = CACHE(rig); hamlib_port_t *rp = RIGPORT(rig); unsigned char reply[80]; freq_t vfoa, vfob; // probably already read VFO_A so just return cache for VFO_B for now if (vfo == RIG_VFO_B) { *freq = cachep->freqMainB; return RIG_OK; } pmr171_send_cmd1(rig, 0x0b, 0); read_block(rp, reply, 5); read_block(rp, &reply[5], reply[4]); vfoa = from_be(&reply[9], 4); vfob = from_be(&reply[13], 4); cachep->freqMainA = vfoa; cachep->freqMainB = vfob; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfoa=%.0f, vfob=%.0f\n", __func__, vfoa, vfob); // Now grab the ptt status cachep->ptt = reply[6] == 1; // And the mode cachep->modeMainA = guohe2rmode(reply[7], pmr171_modes); cachep->modeMainB = guohe2rmode(reply[8], pmr171_modes); if (vfo == RIG_VFO_B) { *freq = cachep->freqMainA; } else { *freq = cachep->freqMainB; } return RIG_OK; } static int pmr171_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct rig_cache *cachep = CACHE(rig); if (vfo == RIG_VFO_B) { *mode = cachep->modeMainA; } else { *mode = cachep->modeMainB; } *width = 2400; return RIG_OK; } static int pmr171_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { *split = CACHE(rig)->split; if (*split) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } return RIG_OK; } static int pmr171_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { //struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *ptt = CACHE(rig)->ptt; return RIG_OK; } #if 0 static int pmr171_get_tx_level(RIG *rig, value_t *val, unsigned char *tx_level, const cal_table_float_t *cal) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_level_tv)) { int n; ptt_t ptt; /* Default to not keyed */ *tx_level = 0; /* TX metering is special; it sends 1 byte if not keyed and 2 if keyed. * To handle this properly we first verify the rig is keyed. * Otherwise we experience at least a full timeout and * perhaps pointless retries + timeouts. */ n = pmr171_get_ptt(rig, 0, &ptt); if (n != RIG_OK) { return n; } if (ptt == RIG_PTT_OFF) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig not keyed\n", __func__); return -RIG_ERJCTED; //Or return OK? } n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_TX_METERING); if (n != RIG_OK) { return n; } } val->f = rig_raw2val_float(*tx_level, cal); rig_debug(RIG_DEBUG_VERBOSE, "%s: level %f\n", __func__, val->f); return RIG_OK; } /* frontend will always use RAWSTR+cal_table */ static int pmr171_get_smeter_level(RIG *rig, value_t *val) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } //n = (p->rx_status & 0x0F) - 9; //val->i = n * ((n > 0) ? 10 : 6); /* S-meter value is returned in the lower 4 bits. 0x00 = S0 (-54dB) 0x01 = S1 0x02 = S2 ... 0x09 = S9 (0dB) 0x0A = S9+10 (10dB) 0x0B = S9+20 and so on */ n = (p->rx_status & 0x0F); if (n < 0x0A) { val->i = (6 * n) - 54; } else { val->i = 10 * (n - 9); } return RIG_OK; } static int pmr171_get_raw_smeter_level(RIG *rig, value_t *val) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } val->i = p->rx_status & 0x0F; return RIG_OK; } static int pmr171_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: /* The front-end will always call for RAWSTR and use the cal_table */ return pmr171_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return pmr171_get_raw_smeter_level(rig, val); case RIG_LEVEL_RFPOWER: return pmr171_get_tx_level(rig, val, &p->pwr_level, &rig->caps->rfpower_meter_cal); case RIG_LEVEL_ALC: return pmr171_get_tx_level(rig, val, &p->alc_level, &rig->caps->alc_cal); case RIG_LEVEL_SWR: return pmr171_get_tx_level(rig, val, &p->swr_level, &rig->caps->swr_cal); default: return -RIG_EINVAL; } return RIG_OK; } static int pmr171_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct pmr171_priv_data *p = (struct pmr171_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = pmr171_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } #endif /* ---------------------------------------------------------------------- */ static int pmr171_read_ack(RIG *rig) { unsigned char dummy; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (rp->post_write_delay == 0) { if (read_block(rp, &dummy, 1) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error reading ack\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: adjusting post_write_delay to avoid ack\n", __func__); rp->post_write_delay = 10; // arbitrary choice right now of max 100 cmds/sec return RIG_OK; // let it continue without checking for ack now } rig_debug(RIG_DEBUG_TRACE, "%s: ack value=0x%x\n", __func__, dummy); } return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete 2-byte sequences. */ static int pmr171_send_cmd2(RIG *rig, unsigned char cmd, unsigned char value, int response) { unsigned char reply[256]; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); unsigned char buf[64] = { 0xa5, 0xa5, 0xa5, 0xa5, 0x04, 0x00, 0x00, 0x00, 0x00 }; buf[5] = cmd; buf[6] = value; unsigned int crc = CRC16Check(&buf[4], 3); buf[7] = crc >> 8; buf[8] = crc & 0xff; rig_flush(rp); write_block(rp, buf, 9); if (response) { read_block(rp, reply, 5); read_block(rp, &reply[5], reply[4]); } return pmr171_read_ack(rig); } /* * The same for incomplete commands. */ #if 0 static int pmr171_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return pmr171_read_ack(rig); } #endif static int pmr171_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[16] = { 0xa5, 0xa5, 0xa5, 0xa5, 11, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char reply[16]; //int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "pmr171: requested freq = %"PRIfreq" Hz\n", freq); /* fill in the frequency */ if (vfo == RIG_VFO_B) { to_be(&cmd[6], CACHE(rig)->freqMainA, 4); to_be(&cmd[10], freq, 4); } else { to_be(&cmd[6], freq, 4); to_be(&cmd[10], CACHE(rig)->freqMainB, 4); } unsigned int crc = CRC16Check(&cmd[4], 10); cmd[14] = crc >> 8; cmd[15] = crc & 0xff; rig_flush(rp); write_block(rp, cmd, 16); read_block(rp, reply, 16); dump_hex(reply, 16); return RIG_OK; } static int pmr171_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { hamlib_port_t *rp = RIGPORT(rig); unsigned char cmd[10] = { 0xa5, 0xa5, 0xa5, 0xa5, 5, 0x0a, 0x00, 0x00, 0x00, 0x00 }; unsigned char reply[10]; int crc; unsigned char i = rmode2guohe(mode, pmr171_modes); if (i != (-1)) { if (vfo == RIG_VFO_B) { cmd[6] = rmode2guohe(CACHE(rig)->modeMainA, pmr171_modes); cmd[7] = i; } else { cmd[6] = i; cmd[7] = rmode2guohe(CACHE(rig)->modeMainB, pmr171_modes); } crc = CRC16Check(&cmd[4], 4); cmd[8] = crc >> 8; cmd[9] = crc & 0xff; rig_flush(rp); write_block(rp, cmd, 10); read_block(rp, reply, 5); read_block(rp, &reply[5], reply[4]); dump_hex(reply, reply[4] + 5); /* // Grab the modes CACHE(rig)->modeMainA = guohe2rmode(reply[6], pmr171_modes); CACHE(rig)->modeMainB = guohe2rmode(reply[7], pmr171_modes); */ return RIG_OK; } rig_debug(RIG_DEBUG_ERR, "%s: invalid mode=%s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } static int pmr171_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char reply[9]; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); // According to the manual, sending 0 means PTT ON. // TODO: How to process ack messages? switch (ptt) { case RIG_PTT_ON: return pmr171_send_cmd2(rig, 0x07, 0x00, 1); case RIG_PTT_OFF: return pmr171_send_cmd2(rig, 0x07, 0x01, 1); default: return -RIG_EINVAL; } read_block(rp, reply, 9); dump_hex(reply, 9); } #if 0 static int pmr171_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_LOCK_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } else { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } default: return -RIG_EINVAL; } } static int pmr171_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; /* int n; */ rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set DCS code (%u)\n", code); if (code == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); /* FT-817 does not have the DCS_ENC_ON command, so we just set the tone here */ /* if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) */ /* return n; */ /* return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ENC_ON); */ return pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data); } static int pmr171_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set DCS sql (%u)\n", code); if (code == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } static int pmr171_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } static int pmr171_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } static int pmr171_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { /* Note: this doesn't have effect unless FT817 is in FM mode although the command is accepted in any mode. */ rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set repeter shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } static int pmr171_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set repeter offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_RPT_OFFSET, data); } static int pmr171_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "pmr171: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = pmr171_send_icmd(rig, FT817_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } else { pmr171_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } */ return RIG_OK; } #endif static int pmr171_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case RIG_POWER_OFF: return pmr171_send_cmd2(rig, 0x0c, 0x00, 0); case RIG_POWER_ON: return pmr171_send_cmd2(rig, 0x0c, 0x01, 0); case RIG_POWER_STANDBY: default: return -RIG_EINVAL; } } #if 0 static int pmr171_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (op) { int n; case RIG_OP_TOGGLE: rig_force_cache_timeout(&((struct pmr171_priv_data *) STATE(rig)->priv)->fm_status_tv); n = pmr171_send_cmd(rig, FT817_NATIVE_CAT_SET_VFOAB); hl_usleep(100 * 1000); // rig needs a little time to do this return n; default: return -RIG_EINVAL; } } #endif /* FIXME: this function silently ignores the vfo args and just turns split ON or OFF. */ static int pmr171_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (split) { case RIG_SPLIT_ON: pmr171_send_cmd2(rig, 0x07, 0x1c, 1); break; case RIG_SPLIT_OFF: pmr171_send_cmd2(rig, 0x07, 0x1c, 0); break; default: return -RIG_EINVAL; } CACHE(rig)->split = split; return RIG_OK; } #if 0 /* FIXME: currently ignores mode and freq */ /* No documentation on how to interpret it but the max number of bars on the display is 10 and I measure: 8 bars = 5W 5 bars = 2.5W 3 bars = 1W 1 bar = 0.5W */ static int pmr171_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *mwpower = (int)(power * 6000); return RIG_OK; } /* FIXME: currently ignores mode and freq */ static int pmr171_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *power = mwpower / 6000.0; return RIG_OK; } #endif /* ---------------------------------------------------------------------- */ hamlib-4.6.2/rigs/yaesu/ft890.h0000644000175000017500000000675614752216205013037 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft890.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-890 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT890_H #define _FT890_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT890_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT890_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT890_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT890_AM_RX_MODES (RIG_MODE_AM) #define FT890_FM_RX_MODES (RIG_MODE_FM) /* TX caps */ #define FT890_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT890_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT890_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) /* fix */ /* * Other features (used by rig_caps) * */ #define FT890_ANTS 0 /* Returned data length in bytes */ #define FT890_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT890_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT890_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT890_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT890_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT890_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ #define FT890_PACING_INTERVAL 5 #define FT890_PACING_DEFAULT_VALUE 0 #define FT890_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT890_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT890_DEFAULT_READ_TIMEOUT 649 * ( 5 + (FT890_PACING_INTERVAL * FT890_PACING_DEFAULT_VALUE)) /* BCD coded frequency length */ #define FT890_BCD_DIAL 8 #define FT890_BCD_RIT 3 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte * rate = 1 byte in 2.2917 msec => 649 bytes in 1487 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 28 bytes * ------------ ---------------------- * * 0 1487 msec * 1 2136 msec (backend default) * 2 2785 msec * 5 4732 msec * 255 167 sec * */ #endif /* _FT890_H */ hamlib-4.6.2/rigs/yaesu/ft1000mp.c0000644000175000017500000015611614752216205013423 00000000000000/* * ft1000.c - (C) Stephane Fillod 2002-2005 (fillods@users.sourceforge.net) * * This shared library provides an API for communicating * via serial interface to an FT-1000MP using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Right now, this FT-1000MP implementation is a big mess. * This is actually a fast copy past (from ft920.c), * just to make get_freq/set_freq and co to work for a friend of mine. * I wouldn't mind if someone could take over the maintenance * of this piece of code, and eventually rewrite it. * '02, Stephane */ #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft1000mp.h" /* * Native FT1000MP functions. More to come :-) * */ enum ft1000mp_native_cmd_e { FT1000MP_NATIVE_SPLIT_OFF = 0, FT1000MP_NATIVE_SPLIT_ON, // 1 FT1000MP_NATIVE_RECALL_MEM, // 2 FT1000MP_NATIVE_VFO_TO_MEM, // 3 FT1000MP_NATIVE_VFO_A, // 4 FT1000MP_NATIVE_VFO_B, // 5 FT1000MP_NATIVE_M_TO_VFO, // 6 FT1000MP_NATIVE_RIT_ON, // 7 FT1000MP_NATIVE_RIT_OFF, // 8 FT1000MP_NATIVE_XIT_ON, // 9 FT1000MP_NATIVE_XIT_OFF, // 10 FT1000MP_NATIVE_RXIT_SET, // 11 FT1000MP_NATIVE_FREQA_SET, // 12 FT1000MP_NATIVE_FREQB_SET, // 13 FT1000MP_NATIVE_MODE_SET_LSB, // 14 FT1000MP_NATIVE_MODE_SET_USB, // 15 FT1000MP_NATIVE_MODE_SET_CW, // 16 FT1000MP_NATIVE_MODE_SET_CWR, // 17 FT1000MP_NATIVE_MODE_SET_AM, // 18 FT1000MP_NATIVE_MODE_SET_AMS, // 19 FT1000MP_NATIVE_MODE_SET_FM, // 20 FT1000MP_NATIVE_MODE_SET_FMW, // 21 FT1000MP_NATIVE_MODE_SET_RTTY_LSB, // 22 FT1000MP_NATIVE_MODE_SET_RTTY_USB, // 23 FT1000MP_NATIVE_MODE_SET_DATA_LSB, // 24 FT1000MP_NATIVE_MODE_SET_DATA_FM, // 25 FT1000MP_NATIVE_MODE_SET_LSB_B, // 26 FT1000MP_NATIVE_MODE_SET_USB_B, // 27 FT1000MP_NATIVE_MODE_SET_CW_B, // 28 FT1000MP_NATIVE_MODE_SET_CWR_B, // 29 FT1000MP_NATIVE_MODE_SET_AM_B, // 30 FT1000MP_NATIVE_MODE_SET_AMS_B, // 31 FT1000MP_NATIVE_MODE_SET_FM_B, // 32 FT1000MP_NATIVE_MODE_SET_FMW_B, // 33 FT1000MP_NATIVE_MODE_SET_RTTY_LSB_B, // 34 FT1000MP_NATIVE_MODE_SET_RTTY_USB_B, // 35 FT1000MP_NATIVE_MODE_SET_DATA_LSB_B, // 36 FT1000MP_NATIVE_MODE_SET_DATA_FM_B, // 37 FT1000MP_NATIVE_PACING, // 38 FT1000MP_NATIVE_PTT_OFF, // 39 FT1000MP_NATIVE_PTT_ON, // 40 FT1000MP_NATIVE_VFO_UPDATE, // 41 FT1000MP_NATIVE_CURR_VFO_UPDATE, // 42 FT1000MP_NATIVE_UPDATE, // 43 FT1000MP_NATIVE_AB, // 44 FT1000MP_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; /* * API local implementation * */ static int ft1000mp_init(RIG *rig); static int ft1000mp_cleanup(RIG *rig); static int ft1000mp_open(RIG *rig); //static int ft1000mp_close(RIG *rig); static int ft1000mp_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft1000mp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft1000mp_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int ft1000mp_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); static int ft1000mp_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); static int ft1000mp_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width); static int ft1000mp_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width); static int ft1000mp_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int ft1000mp_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft1000mp_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft1000mp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft1000mp_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft1000mp_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft1000mp_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft1000mp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000mp_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000mp_set_rxit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000mp_get_rxit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft1000mp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft1000mp_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft1000mp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft1000mp_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); /* * Differences between FT1000MP: * The FT1000MP MARK-V Field appears to be identical to FT1000MP, * whereas the FT1000MP MARK-V is a FT1000MP with 200W. TBC. */ /* Private helper function prototypes */ static int ft1000mp_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft1000mp_send_priv_cmd(RIG *rig, unsigned char ci); /* * Native ft1000mp cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 0 split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* 1 split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* 2 recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* 3 memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* 4 select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* 5 select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* 6 copy memory data to vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* 7 RX clarifier on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* 8 RX clarifier off */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* 9 TX clarifier on */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* 10 TX clarifier off */ { 0, { 0x00, 0x00, 0x00, 0xFF, 0x09 } }, /* 11 set clarifier offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* 12 set VFOA freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* 13 set VFOB freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* 14 vfo A mode set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* 15 vfo A mode set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* 16 vfo A mode set CW-USB */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* 17 vfo A mode set CW-LSB */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* 18 vfo A mode set AM */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* 19 vfo A mode set AM sync */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* 20 vfo A mode set FM */ { 1, { 0x00, 0x00, 0x00, 0x07, 0x0c } }, /* 21 vfo A mode set FMW? */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* 22 vfo A mode set RTTY-LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* 23 vfo A mode set RTTY-USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* 24 vfo A mode set DATA-LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* 25 vfo A mode set DATA-FM */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x0c } }, /* 26 vfo B mode set LSB */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x0c } }, /* 27 vfo B mode set USB */ { 1, { 0x00, 0x00, 0x00, 0x82, 0x0c } }, /* 28 vfo B mode set CW-USB */ { 1, { 0x00, 0x00, 0x00, 0x83, 0x0c } }, /* 29 vfo B mode set CW-LSB */ { 1, { 0x00, 0x00, 0x00, 0x84, 0x0c } }, /* 30 vfo B mode set AM */ { 1, { 0x00, 0x00, 0x00, 0x85, 0x0c } }, /* 31 vfo B mode set AM */ { 1, { 0x00, 0x00, 0x00, 0x86, 0x0c } }, /* 32 vfo B mode set FM */ { 1, { 0x00, 0x00, 0x00, 0x87, 0x0c } }, /* 33 vfo B mode set FMN */ { 1, { 0x00, 0x00, 0x00, 0x88, 0x0c } }, /* 34 vfo B mode set DATA-LSB */ { 1, { 0x00, 0x00, 0x00, 0x89, 0x0c } }, /* 35 vfo B mode set DATA-LSB */ { 1, { 0x00, 0x00, 0x00, 0x8a, 0x0c } }, /* 36 vfo B mode set DATA-USB */ { 1, { 0x00, 0x00, 0x00, 0x8b, 0x0c } }, /* 37 vfo B mode set DATA-FM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* 38 update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0F } }, /* 39 PTT OFF */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0F } }, /* 40 PTT ON */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* 41 status update VFO A & B update */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* 42 status update operating data */ // We only ask for the 1st 3 status bytes // The MARK-V was not recognizing the 6-byte request // This should be all we need as we're only getting the VFO { 1, { 0x00, 0x00, 0x00, 0x00, 0xFA } }, /* 43 Read status flags */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* 44 A>B */ /* { 0, { 0x00, 0x00, 0x00, 0x00, 0x70 } }, */ /* 45 keyer commands */ /* { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, */ /* 46 tuner off */ /* { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, */ /* 47 tuner on */ /* { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, */ /* 48 tuner start*/ }; #define FT1000MP_ALL_RX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_AM|RIG_MODE_FM) /* * TX caps */ #define FT1000MP_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_SSB|RIG_MODE_RTTY|RIG_MODE_FM) /* 100 W class */ #define FT1000MP_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT1000MP_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL \ |RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK \ |RIG_FUNC_RIT|RIG_FUNC_XIT \ /* |RIG_FUNC_TUNER */) /* FIXME */ #define FT1000MP_LEVEL_GET (RIG_LEVEL_RAWSTR|RIG_LEVEL_ALC|RIG_LEVEL_SWR|RIG_LEVEL_RFPOWER|RIG_LEVEL_COMP| \ RIG_LEVEL_MICGAIN|RIG_LEVEL_CWPITCH) #define FT1000MP_VFOS (RIG_VFO_A|RIG_VFO_B) #define FT1000MP_ANTS 0 /* FIXME: declare antenna connectors: ANT-A, ANT-B, RX ANT */ #define FT1000MP_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) /** * 33 CTCSS sub-audible tones */ static tone_t ft1000mp_ctcss_list[] = { 670, 719, 770, 825, 885, 948, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0, }; #define FT1000MP_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .ant = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } #define FT1000MP_STR_CAL { 12, \ { \ { 0, -60 }, \ { 17, -54 }, /* S0 */ \ { 17, -48 }, \ { 34, -42 }, \ { 51, -36 }, \ { 68, -30 }, \ { 85, -24 }, \ { 102, -18 }, \ { 119, -12 }, \ { 136, -6 }, \ { 160, 0 }, /* S9 */ \ { 255, 60 } /* +60 */ \ } } /* * future - private data * */ struct ft1000mp_priv_data { unsigned char pacing; /* pacing value */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[2 * FT1000MP_STATUS_UPDATE_LENGTH]; /* returned data--max value, some are less */ }; /* * ft1000mp rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft1000mp_caps = { RIG_MODEL(RIG_MODEL_FT1000MP), .model_name = "FT-1000MP", .mfg_name = "Yaesu", .version = "20241105.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000MP_WRITE_DELAY, .post_write_delay = FT1000MP_POST_WRITE_DELAY, .timeout = 400, // was 2000 -- see https://github.com/Hamlib/Hamlib/issues/308 .retry = 6, .has_get_func = FT1000MP_FUNC_ALL, .has_set_func = FT1000MP_FUNC_ALL, .has_get_level = FT1000MP_LEVEL_GET, .has_set_level = RIG_LEVEL_BAND_SELECT, /* as strange as it could be */ .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = ft1000mp_ctcss_list, .dcs_list = NULL, .vfo_ops = FT1000MP_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = kHz(1.12), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, FT1000MP_MEM_CAP }, { 100, 108, RIG_MTYPE_EDGE }, /* P1 .. P9 */ { 109, 113, RIG_MTYPE_MEMOPAD }, /* Q1 .. Q5 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY, Hz(10)}, /* Normal */ {RIG_MODE_CW | RIG_MODE_SSB | RIG_MODE_RTTY, Hz(100)}, /* Fast */ {RIG_MODE_AM, Hz(100)}, /* Normal */ {RIG_MODE_AM, kHz(1)}, /* Fast */ {RIG_MODE_FM, Hz(100)}, /* Normal */ {RIG_MODE_FM, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-1000MP has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_CW | RIG_MODE_RTTY, Hz(250)}, {RIG_MODE_AM, kHz(5)}, /* wide */ {RIG_MODE_FM, kHz(8)}, /* FM */ RIG_FLT_END, }, .str_cal = FT1000MP_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft1000mp_init, .rig_cleanup = ft1000mp_cleanup, .rig_open = ft1000mp_open, /* port opened */ .set_freq = ft1000mp_set_freq, /* set freq */ .get_freq = ft1000mp_get_freq, /* get freq */ .set_mode = ft1000mp_set_mode, /* set mode */ .get_mode = ft1000mp_get_mode, /* get mode */ .set_vfo = ft1000mp_set_vfo, /* set vfo */ .get_vfo = ft1000mp_get_vfo, /* get vfo */ .set_split_freq = ft1000mp_set_split_freq, .get_split_freq = ft1000mp_get_split_freq, .set_split_mode = ft1000mp_set_split_mode, .get_split_mode = ft1000mp_get_split_mode, .set_split_freq_mode = ft1000mp_set_split_freq_mode, .get_split_freq_mode = ft1000mp_get_split_freq_mode, .set_split_vfo = ft1000mp_set_split_vfo, .get_split_vfo = ft1000mp_get_split_vfo, .get_rit = ft1000mp_get_rxit, .set_rit = ft1000mp_set_rit, .get_xit = ft1000mp_get_rxit, .set_xit = ft1000mp_set_xit, .get_level = ft1000mp_get_level, .set_ptt = ft1000mp_set_ptt, .set_func = ft1000mp_set_func, .get_func = ft1000mp_get_func, /* TODO: the remaining ... */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft1000mpmkv_caps = { RIG_MODEL(RIG_MODEL_FT1000MPMKV), .model_name = "MARK-V FT-1000MP", .mfg_name = "Yaesu", .version = "20241105.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000MP_WRITE_DELAY, .post_write_delay = FT1000MP_POST_WRITE_DELAY, .timeout = 400, .retry = 6, .has_get_func = FT1000MP_FUNC_ALL, .has_set_func = FT1000MP_FUNC_ALL, .has_get_level = FT1000MP_LEVEL_GET, .has_set_level = RIG_LEVEL_BAND_SELECT, /* as strange as it could be */ .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = ft1000mp_ctcss_list, .dcs_list = NULL, .vfo_ops = FT1000MP_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = kHz(1.12), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, FT1000MP_MEM_CAP }, { 100, 108, RIG_MTYPE_EDGE }, /* P1 .. P9 */ { 109, 113, RIG_MTYPE_MEMOPAD }, /* Q1 .. Q5 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(200), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(50), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(200), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(50), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(10)}, /* Normal */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(100)}, /* Fast */ {RIG_MODE_AM | RIG_MODE_SAL, Hz(100)}, /* Normal */ {RIG_MODE_AM | RIG_MODE_SAL, kHz(1)}, /* Fast */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(100)}, /* Normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-1000MP has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_AM | RIG_MODE_SAL, kHz(5)}, /* wide */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, /* FM */ RIG_FLT_END, }, .str_cal = FT1000MP_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft1000mp_init, .rig_cleanup = ft1000mp_cleanup, .rig_open = ft1000mp_open, /* port opened */ .set_freq = ft1000mp_set_freq, /* set freq */ .get_freq = ft1000mp_get_freq, /* get freq */ .set_mode = ft1000mp_set_mode, /* set mode */ .get_mode = ft1000mp_get_mode, /* get mode */ .set_vfo = ft1000mp_set_vfo, /* set vfo */ .get_vfo = ft1000mp_get_vfo, /* get vfo */ .set_split_freq = ft1000mp_set_split_freq, .get_split_freq = ft1000mp_get_split_freq, .set_split_mode = ft1000mp_set_split_mode, .get_split_mode = ft1000mp_get_split_mode, .set_split_freq_mode = ft1000mp_set_split_freq_mode, .get_split_freq_mode = ft1000mp_get_split_freq_mode, .set_split_vfo = ft1000mp_set_split_vfo, .get_split_vfo = ft1000mp_get_split_vfo, .get_rit = ft1000mp_get_rxit, .set_rit = ft1000mp_set_rit, .get_xit = ft1000mp_get_rxit, .set_xit = ft1000mp_set_xit, .get_level = ft1000mp_get_level, .set_ptt = ft1000mp_set_ptt, .set_func = ft1000mp_set_func, .get_func = ft1000mp_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS /* TODO: the remaining ... */ }; struct rig_caps ft1000mpmkvfld_caps = { RIG_MODEL(RIG_MODEL_FT1000MPMKVFLD), .model_name = "MARK-V Field FT-1000MP", .mfg_name = "Yaesu", .version = "20241105.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000MP_WRITE_DELAY, .post_write_delay = FT1000MP_POST_WRITE_DELAY, .timeout = 400, .retry = 6, .has_get_func = FT1000MP_FUNC_ALL, .has_set_func = FT1000MP_FUNC_ALL, .has_get_level = FT1000MP_LEVEL_GET, .has_set_level = RIG_LEVEL_BAND_SELECT, /* as strange as it could be */ .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = ft1000mp_ctcss_list, .dcs_list = NULL, .vfo_ops = FT1000MP_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = kHz(1.12), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 99, RIG_MTYPE_MEM, FT1000MP_MEM_CAP }, { 100, 108, RIG_MTYPE_EDGE }, /* P1 .. P9 */ { 109, 113, RIG_MTYPE_MEMOPAD }, /* Q1 .. Q5 */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(100), MHz(30), FT1000MP_ALL_RX_MODES, -1, -1, FT1000MP_VFOS, FT1000MP_ANTS }, /* General coverage + ham */ RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { FRQ_RNG_HF(1, FT1000MP_OTHER_TX_MODES, W(5), W(100), FT1000MP_VFOS, FT1000MP_ANTS), FRQ_RNG_HF(1, FT1000MP_AM_TX_MODES, W(2), W(25), FT1000MP_VFOS, FT1000MP_ANTS), /* AM class */ RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(10)}, /* Normal */ {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_PKTLSB, Hz(100)}, /* Fast */ {RIG_MODE_AM | RIG_MODE_SAL, Hz(100)}, /* Normal */ {RIG_MODE_AM | RIG_MODE_SAL, kHz(1)}, /* Fast */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(100)}, /* Normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(1)}, /* Fast */ RIG_TS_END, /* * The FT-1000MP has a Fine tuning step which increments in 1 Hz steps * for SSB_CW_RX_MODES, and 10 Hz steps for AM_RX_MODES and * FM_RX_MODES. It doesn't appear that anything finer than 10 Hz * is available through the CAT interface, however. -N0NB * */ }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_AM | RIG_MODE_SAL | RIG_MODE_PKTLSB, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_AM | RIG_MODE_SAL, kHz(5)}, /* wide */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(8)}, /* FM */ RIG_FLT_END, }, .str_cal = FT1000MP_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft1000mp_init, .rig_cleanup = ft1000mp_cleanup, .rig_open = ft1000mp_open, /* port opened */ .set_freq = ft1000mp_set_freq, /* set freq */ .get_freq = ft1000mp_get_freq, /* get freq */ .set_mode = ft1000mp_set_mode, /* set mode */ .get_mode = ft1000mp_get_mode, /* get mode */ .set_vfo = ft1000mp_set_vfo, /* set vfo */ .get_vfo = ft1000mp_get_vfo, /* get vfo */ .set_split_freq = ft1000mp_set_split_freq, .get_split_freq = ft1000mp_get_split_freq, .set_split_mode = ft1000mp_set_split_mode, .get_split_mode = ft1000mp_get_split_mode, .set_split_freq_mode = ft1000mp_set_split_freq_mode, .get_split_freq_mode = ft1000mp_get_split_freq_mode, .set_split_vfo = ft1000mp_set_split_vfo, .get_split_vfo = ft1000mp_get_split_vfo, .get_rit = ft1000mp_get_rxit, .set_rit = ft1000mp_set_rit, .get_xit = ft1000mp_get_rxit, .set_xit = ft1000mp_set_xit, .get_level = ft1000mp_get_level, .set_ptt = ft1000mp_set_ptt, .set_func = ft1000mp_set_func, .get_func = ft1000mp_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS /* TODO: the remaining ... */ }; /* * _init * */ static int ft1000mp_init(RIG *rig) { struct ft1000mp_priv_data *priv; ENTERFUNC; STATE(rig)->priv = (struct ft1000mp_priv_data *) calloc(1, sizeof(struct ft1000mp_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT1000MP_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ RETURNFUNC(RIG_OK); } /* * ft1000mp_cleanup routine * the serial port is closed by the frontend * */ static int ft1000mp_cleanup(RIG *rig) { ENTERFUNC; if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* * ft1000mp_open routine * */ static int ft1000mp_open(RIG *rig) { struct rig_state *rig_s; hamlib_port_t *rp = RIGPORT(rig); struct ft1000mp_priv_data *p; unsigned char *cmd; /* points to sequence to send */ ENTERFUNC; rig_s = STATE(rig); p = (struct ft1000mp_priv_data *)rig_s->priv; rig_debug(RIG_DEBUG_TRACE, "%s: rig_open: write_delay = %i msec \n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: rig_open: post_write_delay = %i msec \n", __func__, rp->post_write_delay); /* * Copy native cmd PACING to private cmd storage area */ memcpy(&p->p_cmd, &ncmd[FT1000MP_NATIVE_PACING].nseq, YAESU_CMD_LENGTH); p->p_cmd[3] = p->pacing; /* get pacing value, and store in private cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, p->pacing); /* send PACING cmd to rig */ cmd = p->p_cmd; write_block(rp, cmd, YAESU_CMD_LENGTH); ft1000mp_get_vfo(rig, &rig_s->current_vfo); /* TODO */ RETURNFUNC(RIG_OK); } static int ft1000mp_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft1000mp_priv_data *p; unsigned char *cmd; /* points to sequence to send */ int cmd_index = 0; ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: requested freq on %s = %"PRIfreq" Hz \n", __func__, rig_strvfo(vfo), freq); if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } // round freq to 10Hz intervals due to rig restriction freq = round(freq / 10.0) * 10.0; switch (vfo) { case RIG_VFO_A: cmd_index = FT1000MP_NATIVE_FREQA_SET; CACHE(rig)->freqMainA = freq; break; case RIG_VFO_B: cmd_index = FT1000MP_NATIVE_FREQB_SET; CACHE(rig)->freqMainB = freq; break; case RIG_VFO_MEM: // we can set VFOA when VFO MEM is selected cmd_index = FT1000MP_NATIVE_FREQA_SET; break; default: rig_debug(RIG_DEBUG_WARN, "%s: unknown VFO %0x\n", __func__, vfo); RETURNFUNC(-RIG_EINVAL); } /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&p->p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); to_bcd(p->p_cmd, freq / 10, 8); /* store bcd format in in p_cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz\n", __func__, (freq_t)from_bcd(p->p_cmd, 8) * 10); cmd = p->p_cmd; /* get native sequence */ write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); } static int ft1000mp_get_vfo_data(RIG *rig, vfo_t vfo) { int cmd_index, len, retval; ENTERFUNC; if (vfo == RIG_VFO_A || vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_VFO_UPDATE; len = 2 * FT1000MP_STATUS_UPDATE_LENGTH; } else { /* RIG_VFO_CURR or RIG_VFO_MEM */ cmd_index = FT1000MP_NATIVE_CURR_VFO_UPDATE; len = FT1000MP_STATUS_UPDATE_LENGTH; } /* * get record from rig */ retval = ft1000mp_get_update_data(rig, cmd_index, len); RETURNFUNC(retval); } /* * Return Freq for a given VFO * */ static int ft1000mp_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft1000mp_priv_data *priv; unsigned char *p; freq_t f; int retval; ENTERFUNC; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); vfo = STATE(rig)->current_vfo; } retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_FREQ]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_FREQ]; /* CURR_VFO has VFOA offset */ } /* big endian integer, kinda */ f = ((((((p[0] << 8) + p[1]) << 8) + p[2]) << 8) + p[3]) * 10 / 16; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for VFO [%x]\n", __func__, f, vfo); *freq = f; // return displayed frequency RETURNFUNC(RIG_OK); } /* * set mode : eg AM, CW etc for a given VFO * */ static int ft1000mp_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index = 0; /* index of sequence to send */ ENTERFUNC; /* frontend sets VFO for us */ rig_debug(RIG_DEBUG_TRACE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); vfo = STATE(rig)->current_vfo; } /* * translate mode from generic to ft1000mp specific */ switch (mode) { case RIG_MODE_AM: cmd_index = FT1000MP_NATIVE_MODE_SET_AM; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_AM_B; } break; case RIG_MODE_CW: cmd_index = FT1000MP_NATIVE_MODE_SET_CWR; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_CWR_B; } break; case RIG_MODE_CWR: cmd_index = FT1000MP_NATIVE_MODE_SET_CW; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_CW_B; } break; case RIG_MODE_USB: cmd_index = FT1000MP_NATIVE_MODE_SET_USB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_USB_B; } break; case RIG_MODE_LSB: cmd_index = FT1000MP_NATIVE_MODE_SET_LSB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_LSB_B; } break; case RIG_MODE_FM: cmd_index = FT1000MP_NATIVE_MODE_SET_FM; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_FM_B; } break; case RIG_MODE_RTTY: cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_LSB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_LSB_B; } break; case RIG_MODE_PKTUSB: case RIG_MODE_RTTYR: cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_USB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_RTTY_USB_B; } break; case RIG_MODE_PKTLSB: cmd_index = FT1000MP_NATIVE_MODE_SET_DATA_LSB; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_DATA_LSB_B; } break; case RIG_MODE_PKTFM: cmd_index = FT1000MP_NATIVE_MODE_SET_DATA_FM; if (vfo == RIG_VFO_B) { cmd_index = FT1000MP_NATIVE_MODE_SET_FM_B; } break; default: RETURNFUNC(-RIG_EINVAL); /* sorry, wrong MODE * */ } /* * Now set width * FIXME: so far setting passband is buggy, only 0 is accepted */ /* * phew! now send cmd to rig */ ft1000mp_send_priv_cmd(rig, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_index = %i\n", __func__, cmd_index); RETURNFUNC(RIG_OK); /* good */ } /* * get mode : eg AM, CW etc for a given VFO * */ static int ft1000mp_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft1000mp_priv_data *priv; unsigned char mymode; /* ft1000mp mode */ unsigned char mymode_ext; /* ft1000mp extra mode bit mode */ int retval; struct rig_state *rs = STATE(rig); ENTERFUNC; if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(rs->current_vfo)); vfo = rs->current_vfo; } retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } priv = (struct ft1000mp_priv_data *)rs->priv; if (vfo == RIG_VFO_B) { mymode = priv->update_data[FT1000MP_SUMO_VFO_B_MODE]; mymode_ext = priv->update_data[FT1000MP_SUMO_VFO_B_IF] & IF_MODE_MASK; } else { mymode = priv->update_data[FT1000MP_SUMO_VFO_A_MODE]; /* CURR_VFO is VFOA offset */ mymode_ext = priv->update_data[FT1000MP_SUMO_VFO_A_IF] & IF_MODE_MASK; } rig_debug(RIG_DEBUG_TRACE, "%s: mymode = %x (before)\n", __func__, mymode); mymode &= MODE_MASK; rig_debug(RIG_DEBUG_TRACE, "%s: mymode = %x (after)\n", __func__, mymode); /* * translate mode from ft1000mp to generic. * TODO: Add DATA, and Narrow modes. CW on LSB? -N0NB */ switch (mymode) { case MODE_CW: *mode = mymode_ext ? RIG_MODE_CW : RIG_MODE_CWR; break; case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_AM: *mode = mymode_ext ? RIG_MODE_SAL : RIG_MODE_AM; break; case MODE_FM: *mode = RIG_MODE_FM; break; case MODE_RTTY: *mode = mymode_ext ? RIG_MODE_RTTYR : RIG_MODE_RTTY; break; case MODE_PKT: *mode = mymode_ext ? RIG_MODE_PKTFM : RIG_MODE_PKTLSB; break; default: RETURNFUNC(-RIG_EINVAL); /* sorry, wrong mode */ break; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); /* TODO: set real IF filter selection */ *width = RIG_PASSBAND_NORMAL; RETURNFUNC(RIG_OK); } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft1000mp_set_vfo(RIG *rig, vfo_t vfo) { //unsigned char cmd_index = 0; /* index of sequence to send */ ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); /* * RIG_VFO_VFO/RIG_VFO_MEM are not available * so try to emulate them. * looks like there's no RIG_VFO_MEM, maybe setting mem# * switch to it automatically? */ if (vfo == RIG_VFO_VFO) { vfo = STATE(rig)->current_vfo; } #if 0 // seems switching VFOs like this changes the frequencies in the response switch (vfo) { case RIG_VFO_A: cmd_index = FT1000MP_NATIVE_VFO_A; STATE(rig)->current_vfo = vfo; /* update active VFO */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo == RIG_VFO_A\n", __func__); break; case RIG_VFO_B: cmd_index = FT1000MP_NATIVE_VFO_B; STATE(rig)->current_vfo = vfo; /* update active VFO */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo == RIG_VFO_B\n", __func__); break; case RIG_VFO_CURR: /* do nothing, we're already at it! */ RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Unknown default VFO %d\n", __func__, vfo); RETURNFUNC(-RIG_EINVAL); /* sorry, wrong VFO */ } /* * phew! now send cmd to rig */ ft1000mp_send_priv_cmd(rig, cmd_index); #endif // we just store the requested vfo in our internal state STATE(rig)->current_vfo = vfo; RETURNFUNC(RIG_OK); } /* * get vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft1000mp_get_vfo(RIG *rig, vfo_t *vfo) { struct ft1000mp_priv_data *p; int retval; ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ retval = ft1000mp_get_update_data(rig, FT1000MP_NATIVE_UPDATE, FT1000MP_STATUS_FLAGS_LENGTH); if (retval < 0) { RETURNFUNC(retval); } if (p->update_data[1] & 0x40) { *vfo = RIG_VFO_MEM; } else // we are emulating vfo status { *vfo = STATE(rig)->current_vfo; if (*vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: no get_vfo, defaulting to VFOA\n", __func__); *vfo = RIG_VFO_A; } } #if 0 else if (p->update_data[FT1000MP_SUMO_DISPLAYED_STATUS] & SF_VFOAB) { *vfo = STATE(rig)->current_vfo = RIG_VFO_B; } else { *vfo = STATE(rig)->current_vfo = RIG_VFO_A; } #endif rig_debug(RIG_DEBUG_TRACE, "%s: vfo status = %x %x\n", __func__, p->update_data[0], p->update_data[1]); RETURNFUNC(RIG_OK); } static int ft1000mp_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct ft1000mp_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char *cmd; ENTERFUNC; priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; switch (func) { case RIG_FUNC_RIT: if (status) { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_RIT_ON].nseq, YAESU_CMD_LENGTH); } else { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_RIT_OFF].nseq, YAESU_CMD_LENGTH); } cmd = priv->p_cmd; write_block(rp, cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); case RIG_FUNC_XIT: if (status) { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_XIT_ON].nseq, YAESU_CMD_LENGTH); } else { memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_XIT_OFF].nseq, YAESU_CMD_LENGTH); } cmd = priv->p_cmd; write_block(rp, cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_func %s", __func__, rig_strfunc(func)); } RETURNFUNC(-RIG_EINVAL); } static int ft1000mp_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; struct ft1000mp_priv_data *priv; unsigned char *p; ENTERFUNC; priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; if (!status) { RETURNFUNC(-RIG_EINVAL); } switch (func) { case RIG_FUNC_RIT: { retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_MEM]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_MEM]; /* CURR_VFO has VFOA offset */ } *status = (*p & 2) ? 1 : 0; RETURNFUNC(RIG_OK); } case RIG_FUNC_XIT: { retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_MEM]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_MEM]; /* CURR_VFO has VFOA offset */ } *status = (*p & 1) ? 1 : 0; RETURNFUNC(RIG_OK); } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_func %s", __func__, rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } /* * set_rit only support vfo = RIG_VFO_CURR */ static int ft1000mp_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { ENTERFUNC; if (rit != 0) { ft1000mp_set_func(rig, vfo, RIG_FUNC_RIT, 1); } RETURNFUNC(ft1000mp_set_rxit(rig, vfo, rit)); } static int ft1000mp_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { ENTERFUNC; RETURNFUNC(ft1000mp_set_rxit(rig, vfo, rit)); } static int ft1000mp_set_rxit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct rig_state *rs; struct ft1000mp_priv_data *priv; unsigned char *cmd; /* points to sequence to send */ int direction = 0; ENTERFUNC; rs = STATE(rig); priv = (struct ft1000mp_priv_data *)rs->priv; rig_debug(RIG_DEBUG_TRACE, "%s: requested freq = %d Hz\n", __func__, (int)rit); /* * Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[FT1000MP_NATIVE_RXIT_SET].nseq, YAESU_CMD_LENGTH); if (rit < 0) { direction = 0xff; rit = -rit; } unsigned char rit_freq[10]; // yes, it really is this nasty and complicated! to_bcd_be(rit_freq, (rit - (rit / 1000) * 1000) / 10, 2); priv->p_cmd[0] = rit_freq[0]; // 10 hz to_bcd_be(rit_freq, rit / 1000, 2); priv->p_cmd[1] = rit_freq[0]; // Khz priv->p_cmd[2] = direction; cmd = priv->p_cmd; /* get native sequence */ write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); } /* * Return RIT for a given VFO * */ static int ft1000mp_get_rxit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft1000mp_priv_data *priv; unsigned char *p; shortfreq_t f; int retval; ENTERFUNC; priv = (struct ft1000mp_priv_data *)STATE(rig)->priv; retval = ft1000mp_get_vfo_data(rig, vfo); if (retval < 0) { RETURNFUNC(retval); } if (vfo == RIG_VFO_B) { p = &priv->update_data[FT1000MP_SUMO_VFO_B_CLAR]; } else { p = &priv->update_data[FT1000MP_SUMO_VFO_A_CLAR]; /* CURR_VFO has VFOA offset */ } f = (p[0] << 8) + p[1]; if (p[0] & 0x80) { f = ~(f - 1) & 0x7fff; // two's complement f = -f; } f = f * 10 / 16; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %d Hz for VFO [%s]\n", __func__, (int)f, rig_strvfo(vfo)); *rit = f; // return displayed frequency RETURNFUNC(RIG_OK); } static int ft1000mp_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft1000mp_priv_data *priv; struct rig_state *rs; hamlib_port_t *rp = RIGPORT(rig); unsigned char lvl_data[YAESU_CMD_LENGTH]; int m; int retval; int retry = rp->retry; ENTERFUNC; rs = STATE(rig); priv = (struct ft1000mp_priv_data *)rs->priv; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_RAWSTR: if (vfo == RIG_VFO_CURR) { vfo = rs->current_vfo; } m = vfo == RIG_VFO_B ? 0x01 : 0x00; break; case RIG_LEVEL_RFPOWER: m = 0x80; break; case RIG_LEVEL_ALC: m = 0x81; break; case RIG_LEVEL_COMP: m = 0x83; break; case RIG_LEVEL_SWR: m = 0x85; break; case RIG_LEVEL_MICGAIN: /* not sure ... */ m = 0x86; break; case RIG_LEVEL_CWPITCH: m = 0xf1; break; case RIG_LEVEL_IF: /* not sure ... */ m = 0xf3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } memset(&priv->p_cmd, m, YAESU_CMD_LENGTH - 1); priv->p_cmd[4] = 0xf7; do { write_block(rp, priv->p_cmd, YAESU_CMD_LENGTH); retval = read_block(rp, lvl_data, YAESU_CMD_LENGTH); } while (retry-- && retval == -RIG_ETIMEOUT); if (retval != YAESU_CMD_LENGTH) { rig_debug(RIG_DEBUG_ERR, "%s: ack NG %d", __func__, retval); RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_RAWSTR: val->i = lvl_data[0]; break; default: if (RIG_LEVEL_IS_FLOAT(level)) { val->f = (float)lvl_data[0] / 255; } else { val->i = lvl_data[0]; } } rig_debug(RIG_DEBUG_TRACE, "%s: %d %d %f\n", __func__, lvl_data[0], val->i, val->f); RETURNFUNC(RIG_OK); } static int ft1000mp_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; /* index of sequence to send */ ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: called %d\n", __func__, ptt); cmd_index = ptt ? FT1000MP_NATIVE_PTT_ON : FT1000MP_NATIVE_PTT_OFF; ft1000mp_send_priv_cmd(rig, cmd_index); RETURNFUNC(RIG_OK); } /* * private helper function. Retrieves update data from rig. * using buffer indicated in *priv struct. * Extended to be command agnostic as 1000mp has several ways to * get data and several ways to return it. * * need to use this when doing ft1000mp_get_* stuff * * Variables: ci = command index, rl = read length of returned data * */ static int ft1000mp_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft1000mp_priv_data *p; int n; /* for read_ */ ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; // timeout retries are done in read_block now // based on rig backed retry value /* send UPDATE command to fetch data*/ ft1000mp_send_priv_cmd(rig, ci); n = read_block(RIGPORT(rig), p->update_data, rl); if (n == -RIG_ETIMEOUT) { rig_debug(RIG_DEBUG_TRACE, "%s: Timeout\n", __func__); } RETURNFUNC(n); } /* * private helper function to send a private command * sequence . Must only be complete sequences. * TODO: place variant of this in yaesu.c * */ static int ft1000mp_send_priv_cmd(RIG *rig, unsigned char ci) { ENTERFUNC; if (! ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: attempt to send incomplete sequence\n", __func__); RETURNFUNC(-RIG_EINVAL); } write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); RETURNFUNC(RIG_OK); } static int ft1000mp_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index = 0; /* index of sequence to send */ struct rig_state *rs = STATE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s called rx_vfo=%s, tx_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo)); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT1000MP_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT1000MP_NATIVE_SPLIT_ON; break; default: rig_debug(RIG_DEBUG_VERBOSE, "%s: Unknown split value = %d\n", __func__, split); RETURNFUNC(-RIG_EINVAL); /* sorry, wrong VFO */ } // manual says VFO_A=Tx and VFO_B=Rx but testing shows otherwise rs->current_vfo = RIG_VFO_A; rs->rx_vfo = RIG_VFO_B; rs->tx_vfo = RIG_VFO_B; ft1000mp_send_priv_cmd(rig, cmd_index); RETURNFUNC(RIG_OK); } /* * get split * */ static int ft1000mp_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft1000mp_priv_data *p; int retval; ENTERFUNC; p = (struct ft1000mp_priv_data *)STATE(rig)->priv; /* Get flags for split status */ retval = ft1000mp_get_update_data(rig, FT1000MP_NATIVE_UPDATE, FT1000MP_STATUS_FLAGS_LENGTH); if (retval < 0) { RETURNFUNC(retval); } if (p->update_data[0] & 0x01) { *tx_vfo = RIG_VFO_B; *split = RIG_SPLIT_ON; } else { *tx_vfo = RIG_VFO_A; *split = RIG_SPLIT_OFF; } RETURNFUNC(RIG_OK); } static int ft1000mp_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { ENTERFUNC; int retval = rig_set_split_vfo(rig, vfo, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(ft1000mp_set_freq(rig, RIG_VFO_B, tx_freq)); } static int ft1000mp_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int retval; ENTERFUNC; retval = rig_set_mode(rig, RIG_VFO_B, tx_mode, tx_width); RETURNFUNC(retval); } static int ft1000mp_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int retval; ENTERFUNC; retval = rig_get_mode(rig, RIG_VFO_B, tx_mode, tx_width); RETURNFUNC(retval); } static int ft1000mp_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width) { int retval; ENTERFUNC; retval = rig_set_mode(rig, RIG_VFO_B, mode, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_mode failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } retval = ft1000mp_set_split_freq(rig, vfo, freq); if (retval == RIG_OK) { CACHE(rig)->freqMainB = freq; CACHE(rig)->modeMainB = mode; } RETURNFUNC(retval); } static int ft1000mp_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { int retval; ENTERFUNC; retval = rig_get_mode(rig, RIG_VFO_B, mode, width); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_mode failed: %s\n", __func__, rigerror(retval)); RETURNFUNC(retval); } retval = ft1000mp_get_split_freq(rig, vfo, freq); if (retval == RIG_OK) { CACHE(rig)->freqMainB = *freq; CACHE(rig)->modeMainB = *mode; } RETURNFUNC(retval); } static int ft1000mp_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { ENTERFUNC; RETURNFUNC(ft1000mp_get_freq(rig, RIG_VFO_B, tx_freq)); } hamlib-4.6.2/rigs/yaesu/newcat.c0000644000175000017500000125555414752216205013444 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * and the Hamlib Group (hamlib-developer at lists.sourceforge.net) * * newcat.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2010 * (C) David Fannin (kk6df at arrl.net) * * This shared library provides an API for communicating * via serial interface to any newer Yaesu radio using the * "new" text CAT interface. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "iofunc.h" #include "misc.h" #include "cal.h" #include "newcat.h" #include "serial.h" /* global variables */ static const char cat_term = ';'; /* Yaesu command terminator */ // static const char cat_unknown_cmd[] = "?;"; /* Yaesu ? */ /* Internal Backup and Restore VFO Memory Channels */ #define NC_MEM_CHANNEL_NONE 2012 #define NC_MEM_CHANNEL_VFO_A 2013 #define NC_MEM_CHANNEL_VFO_B 2014 /* 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 = 570, NC_RIGID_FT991A = 670, NC_RIGID_FT2000 = 251, NC_RIGID_FT2000D = 252, NC_RIGID_FTDX1200 = 583, NC_RIGID_FTDX10 = 761, NC_RIGID_FTDX9000D = 101, NC_RIGID_FTDX9000Contest = 102, NC_RIGID_FTDX9000MP = 103, NC_RIGID_FTDX5000 = 362, NC_RIGID_FTDX3000 = 460, NC_RIGID_FTDX3000DM = 462, // an undocumented FT-DX3000DM 50W rig NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682, NC_RIGID_FT710 = 800, } nc_rigid_t; /* * The following table defines which commands are valid for any given * rig supporting the "new" CAT interface. */ typedef struct _yaesu_newcat_commands { char *command; ncboolean ft450; ncboolean ft950; ncboolean ft891; ncboolean ft991; ncboolean ft2000; ncboolean ft9000; ncboolean ft5000; ncboolean ft1200; ncboolean ft3000; ncboolean ft101d; ncboolean ftdx10; ncboolean ft101mp; ncboolean ft710; ncboolean ft9000Old; } yaesu_newcat_commands_t; /** * Yaesu FT-991 S-meter scale, default for new Yaesu rigs. * Determined by data from W6HN -- seems to be pretty linear * * SMeter, rig answer, %fullscale * S0 SM0000 0 * S2 SM0026 10 * S4 SM0051 20 * S6 SM0081 30 * S7.5 SM0105 40 * S9 SM0130 50 * +12db SM0157 60 * +25db SM0186 70 * +35db SM0203 80 * +50db SM0237 90 * +60db SM0255 100 * * 114dB range over 0-255 referenced to S0 of -54dB */ const cal_table_t yaesu_default_str_cal = { 11, { { 0, -54, }, // S0 { 26, -42, }, // S2 { 51, -30, }, // S4 { 81, -18, }, // S6 { 105, -9, }, // S7.5 { 130, 0, }, // S9 { 157, 12, }, // S9+12dB { 186, 25, }, // S9+25dB { 203, 35, }, // S9+35dB { 237, 50, }, // S9+50dB { 255, 60, }, // S9+60dB } }; /** * First cut at generic Yaesu table, need more points probably * based on testing by Adam M7OTP on FT-991 */ const cal_table_float_t yaesu_default_swr_cal = { 5, { {12, 1.0f}, {39, 1.35f}, {65, 1.5f}, {89, 2.0f}, {242, 5.0f} } }; // TODO: Provide sane defaults const cal_table_float_t yaesu_default_alc_cal = { 2, { {0, 0.0f}, {64, 1.0f} } }; const cal_table_float_t yaesu_default_comp_meter_cal = { 9, { { 0, 0.0f }, { 40, 2.5f }, { 60, 5.0f }, { 85, 7.5f }, { 135, 10.0f }, { 150, 12.5f }, { 175, 15.0f }, { 195, 17.5f }, { 220, 20.0f } } }; // TODO: Provide sane defaults const cal_table_float_t yaesu_default_rfpower_meter_cal = { 3, { {0, 0.0f}, {148, 50.0f}, {255, 100.0f}, } }; const cal_table_float_t yaesu_default_vd_meter_cal = { 3, { {0, 0.0f}, {196, 13.8f}, {255, 17.95f}, } }; const cal_table_float_t yaesu_default_id_meter_cal = { 3, { {0, 0.0f}, {100, 10.0f}, {255, 25.5f}, } }; // Easy reference to rig model -- it is set in newcat_valid_command static ncboolean is_ft450; static ncboolean is_ft710; static ncboolean is_ft891; static ncboolean is_ft897; static ncboolean is_ft897d; static ncboolean is_ft950; static ncboolean is_ft991; static ncboolean is_ft2000; static ncboolean is_ftdx9000; static ncboolean is_ftdx5000; static ncboolean is_ftdx1200; static ncboolean is_ftdx3000; static ncboolean is_ftdx3000dm; static ncboolean is_ftdx101d; static ncboolean is_ftdx101mp; static ncboolean is_ftdx10; static ncboolean is_ftdx9000Old; /* * Even thought this table does make a handy reference, it could be depreciated as it is not really needed. * All of the CAT commands used in the newcat interface are available on the FT-950, FT-2000, FT-5000, and FT-9000. * There are 5 CAT commands used in the newcat interface that are not available on the FT-450. * Thesec CAT commands are XT -TX Clarifier ON/OFF, AN - Antenna select, PL - Speech Proc Level, * PR - Speech Proc ON/OFF, and BC - Auto Notch filter ON/OFF. * The FT-450 returns -RIG_ENVAIL for these unavailable CAT commands. * * NOTE: The following table must be in alphabetical order by the * command. This is because it is searched using a binary search * to determine whether or not a command is valid for a given rig. * * The list of supported commands is obtained from the rig's operator's * or CAT programming manual. * */ static const yaesu_newcat_commands_t valid_commands[] = { /* Command FT-450 FT-950 FT-891 FT-991 FT-2000 FT-9000 FT-5000 FT-1200 FT-3000 FTDX101D FTDX10 FTDX101MP FT710 FT9000Old*/ {"AB", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AM", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"AN", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE }, {"AO", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"BA", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"BC", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"BP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"BY", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CF", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE }, {"CH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CO", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"CT", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"DA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"DN", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"DP", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"DS", TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"DT", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"ED", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"EK", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE }, {"EM", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE }, {"EN", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"EU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"EX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FK", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"FN", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"FR", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"FS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE }, {"FT", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"GT", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"ID", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"IF", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"IS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"KY", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"LK", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"LM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MA", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MB", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"MC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MK", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"ML", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"MW", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"MX", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NA", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"NB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"NR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"OI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"OS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PB", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PL", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PR", FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"PS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"QI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"QR", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"QS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RA", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RI", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RL", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RO", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE }, {"RP", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}, {"RS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"RT", TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE }, {"RU", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SC", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SH", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SQ", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SS", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, // ST command has two meanings Step or Split Status // If new rig is added that has ST ensure it means Split // Otherwise modify newcat_(set|get)_split {"ST", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"SV", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"SY", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE}, {"TS", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"TX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"UL", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"UP", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VD", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VF", FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE }, {"VG", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VM", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"VR", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, {"VS", TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE }, {"VT", FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE }, {"VV", TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, {"VX", TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, {"XT", FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE }, {"ZI", FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE }, } ; int valid_commands_count = sizeof(valid_commands) / sizeof( yaesu_newcat_commands_t); /* * configuration Tokens * */ #define TOK_FAST_SET_CMD TOKEN_BACKEND(1) const struct confparams newcat_cfg_params[] = { { TOK_FAST_SET_CMD, "fast_commands_token", "High throughput of commands", "Enabled high throughput of >200 messages/sec by not waiting for ACK/NAK of messages", "0", RIG_CONF_NUMERIC, { .n = { 0, 1, 1 } } }, { RIG_CONF_END, NULL, } }; /* NewCAT Internal Functions */ static ncboolean newcat_is_rig(RIG *rig, rig_model_t model); static int newcat_set_split(RIG *rig, split_t split, vfo_t *rx_vfo, vfo_t *tx_vfo); static int newcat_get_split(RIG *rig, split_t *split, vfo_t *tx_vfo); static int newcat_set_vfo_from_alias(RIG *rig, vfo_t *vfo); static int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width); static int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int newcat_set_narrow(RIG *rig, vfo_t vfo, ncboolean narrow); static int newcat_get_narrow(RIG *rig, vfo_t vfo, ncboolean *narrow); static int newcat_set_faststep(RIG *rig, ncboolean fast_step); static int newcat_get_faststep(RIG *rig, ncboolean *fast_step); static int newcat_get_rigid(RIG *rig); static int newcat_get_vfo_mode(RIG *rig, vfo_t vfo, vfo_t *vfo_mode); static int newcat_vfomem_toggle(RIG *rig); static int set_roofing_filter(RIG *rig, vfo_t vfo, int index); static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width); static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter); static int newcat_set_clarifier(RIG *rig, vfo_t vfo, int rx, int tx); static int newcat_get_clarifier(RIG *rig, vfo_t vfo, int *rx, int *tx); static int newcat_set_apf_frequency(RIG *rig, vfo_t vfo, int freq); static int newcat_get_apf_frequency(RIG *rig, vfo_t vfo, int *freq); static int newcat_set_apf_width(RIG *rig, vfo_t vfo, int choice); static int newcat_get_apf_width(RIG *rig, vfo_t vfo, int *choice); static int newcat_set_contour(RIG *rig, vfo_t vfo, int status); static int newcat_get_contour(RIG *rig, vfo_t vfo, int *status); static int newcat_set_contour_frequency(RIG *rig, vfo_t vfo, int freq); static int newcat_get_contour_frequency(RIG *rig, vfo_t vfo, int *freq); static int newcat_set_contour_level(RIG *rig, vfo_t vfo, int level); static int newcat_get_contour_level(RIG *rig, vfo_t vfo, int *level); static int newcat_set_contour_width(RIG *rig, vfo_t vfo, int width); static int newcat_get_contour_width(RIG *rig, vfo_t vfo, int *width); static ncboolean newcat_valid_command(RIG *rig, char const *const command); /* * The BS command needs to know what band we're on so we can restore band info * So this converts freq to band index */ static int newcat_band_index(freq_t freq) { int band = 11; // general // restrict band memory recall to ITU 1,2,3 band ranges // using < instead of <= for the moment // does anybody work LSB or RTTYR at the upper band edge? // what about band 13 -- what is it? if (freq >= MHz(420) && freq < MHz(470)) { band = 16; } else if (freq >= MHz(144) && freq < MHz(148)) { band = 15; } // band 14 is RX only // override band 15 with 14 if needed else if (freq >= MHz(118) && freq < MHz(164)) { band = 14; } else if (freq >= MHz(70) && freq < MHz(70.5)) { band = 17; } else if (freq >= MHz(50) && freq < MHz(55)) { band = 10; } else if (freq >= MHz(28) && freq < MHz(29.7)) { band = 9; } else if (freq >= MHz(24.890) && freq < MHz(24.990)) { band = 8; } else if (freq >= MHz(21) && freq < MHz(21.45)) { band = 7; } else if (freq >= MHz(18) && freq < MHz(18.168)) { band = 6; } else if (freq >= MHz(14) && freq < MHz(14.35)) { band = 5; } else if (freq >= MHz(10) && freq < MHz(10.15)) { band = 4; } else if (freq >= MHz(7) && freq < MHz(7.3)) { band = 3; } else if (freq >= MHz(5.3515) && freq < MHz(5.3665)) { band = 2; } else if (freq >= MHz(3.5) && freq < MHz(4)) { band = 1; } else if (freq >= MHz(1.8) && freq < MHz(2)) { band = 0; } else if (freq >= MHz(0.5) && freq < MHz(1.705)) { band = 12; } // MW Medium Wave rig_debug(RIG_DEBUG_TRACE, "%s: freq=%g, band=%d\n", __func__, freq, band); return (band); } /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ int newcat_init(RIG *rig) { struct newcat_priv_data *priv; ENTERFUNC; STATE(rig)->priv = (struct newcat_priv_data *) calloc(1, sizeof(struct newcat_priv_data)); if (!STATE( rig)->priv) /* whoops! memory shortage! */ { RETURNFUNC(-RIG_ENOMEM); } priv = STATE(rig)->priv; // priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ // priv->current_vfo = RIG_VFO_A; priv->rig_id = NC_RIGID_NONE; priv->current_mem = NC_MEM_CHANNEL_NONE; priv->fast_set_commands = FALSE; /* * Determine the type of rig from the model number. Note it is * possible for several model variants to exist; i.e., all the * FT-9000 variants. */ is_ft450 = newcat_is_rig(rig, RIG_MODEL_FT450); is_ft450 |= newcat_is_rig(rig, RIG_MODEL_FT450D); is_ft891 = newcat_is_rig(rig, RIG_MODEL_FT891); is_ft897 = newcat_is_rig(rig, RIG_MODEL_FT897); is_ft897d = newcat_is_rig(rig, RIG_MODEL_FT897D); is_ft950 = newcat_is_rig(rig, RIG_MODEL_FT950); is_ft991 = newcat_is_rig(rig, RIG_MODEL_FT991); is_ft2000 = newcat_is_rig(rig, RIG_MODEL_FT2000); is_ftdx9000 = newcat_is_rig(rig, RIG_MODEL_FT9000); is_ftdx9000Old = newcat_is_rig(rig, RIG_MODEL_FT9000OLD); is_ftdx5000 = newcat_is_rig(rig, RIG_MODEL_FTDX5000); is_ftdx1200 = newcat_is_rig(rig, RIG_MODEL_FTDX1200); is_ftdx3000 = newcat_is_rig(rig, RIG_MODEL_FTDX3000); is_ftdx3000dm = FALSE; // Detected dynamically is_ftdx101d = newcat_is_rig(rig, RIG_MODEL_FTDX101D); is_ftdx101mp = newcat_is_rig(rig, RIG_MODEL_FTDX101MP); is_ftdx10 = newcat_is_rig(rig, RIG_MODEL_FTDX10); is_ft710 = newcat_is_rig(rig, RIG_MODEL_FT710); RETURNFUNC(RIG_OK); } /* * rig_cleanup * * the serial port is closed by the frontend * */ int newcat_cleanup(RIG *rig) { ENTERFUNC; if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } /* * rig_open * * New CAT does not support pacing * */ int newcat_open(RIG *rig) { struct rig_state *rig_s = STATE(rig); struct newcat_priv_data *priv = rig_s->priv; hamlib_port_t *rp = RIGPORT(rig); const char *handshake[3] = {"None", "Xon/Xoff", "Hardware"}; int err; int set_only = 0; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: Rig=%s, version=%s\n", __func__, rig->caps->model_name, rig->caps->version); rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, rp->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: serial_handshake = %s \n", __func__, handshake[rig->caps->serial_handshake]); /* Ensure rig is powered on */ if (priv->poweron == 0 && rig_s->auto_power_on) { rig_set_powerstat(rig, 1); priv->poweron = 1; } priv->question_mark_response_means_rejected = 0; /* get current AI state so it can be restored */ priv->trn_state = -1; // for this sequence we will shorten the timeout so we can detect rig is powered off faster int timeout = rp->timeout; rp->timeout = 100; newcat_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ if (priv->trn_state > 0) { newcat_set_trn(rig, RIG_TRN_OFF); } /* ignore status in case it's not supported */ /* Initialize rig_id in case any subsequent commands need it */ (void)newcat_get_rigid(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: rig_id=%d\n", __func__, priv->rig_id); rp->timeout = timeout; // some rigs have a CAT TOT timeout that defaults to 10ms // so we'll increase CAT timeout to 100ms // 10ms seemed problematic on some rigs/computers if (priv->rig_id == NC_RIGID_FT2000 || priv->rig_id == NC_RIGID_FT2000D || priv->rig_id == NC_RIGID_FT891 || priv->rig_id == NC_RIGID_FT991 || priv->rig_id == NC_RIGID_FT991A || priv->rig_id == NC_RIGID_FT950 || priv->rig_id == NC_RIGID_FTDX10 || priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX3000DM) { char *cmd = "EX0291;EX029;"; // FT2000/D int retry_save; if (priv->rig_id == NC_RIGID_FT950 || rig->caps->rig_model == RIG_MODEL_FT950) { cmd = "EX0271;EX027;"; } else if (priv->rig_id == NC_RIGID_FT891 || rig->caps->rig_model == RIG_MODEL_FT891) { cmd = "EX05071;EX0507;"; } else if (priv->rig_id == NC_RIGID_FT991 || rig->caps->rig_model == RIG_MODEL_FT991) { cmd = "EX0321;EX032;"; } else if (priv->rig_id == NC_RIGID_FT991A || rig->caps->rig_model == RIG_MODEL_FT991) { cmd = "EX0321;EX032;"; } else if (priv->rig_id == NC_RIGID_FTDX3000 || rig->caps->rig_model == RIG_MODEL_FTDX3000) { cmd = "EX0391;"; set_only = 1; } else if (priv->rig_id == NC_RIGID_FTDX3000DM || rig->caps->rig_model == RIG_MODEL_FTDX3000) { cmd = "EX0391;"; set_only = 1; } else if (priv->rig_id == NC_RIGID_FTDX5000 || rig->caps->rig_model == RIG_MODEL_FTDX5000) { cmd = "EX0331;EX033"; } else if (priv->rig_id == NC_RIGID_FTDX10 || rig->caps->rig_model == RIG_MODEL_FTDX10) { cmd = "EX0301091;EX030109;"; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", cmd); retry_save = rp->retry; rp->retry = 0; if (set_only) { err = newcat_set_cmd(rig); } else { err = newcat_get_cmd(rig); } rp->retry = retry_save; if (err != RIG_OK) { // if we can an err we just ignore the failure -- Win4Yaesu was not recognizing EX032 command } } if (priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX3000DM) { rig_s->disable_yaesu_bandselect = 1; rig_debug(RIG_DEBUG_VERBOSE, "%s: disabling FTDX3000 band select\n", __func__); } #if 0 // this apparently does not work if (is_ftdx5000) { // Remember EX103 status SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX103;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); if (set_only) { err = newcat_set_cmd(rig); } else { err = newcat_get_cmd(rig); } if (err != RIG_OK) { RETURNFUNC(err); } if (priv->ret_data[6] == ';') { priv->front_rear_status = priv->ret_data[5]; } } #endif priv->band_index = -1; RETURNFUNC(RIG_OK); } /* * rig_close * */ int newcat_close(RIG *rig) { struct rig_state *rig_s = STATE(rig); struct newcat_priv_data *priv = rig_s->priv; ENTERFUNC; if (!no_restore_ai && priv->trn_state >= 0 && rig_s->comm_state && rig_s->powerstat != RIG_POWER_OFF) { /* restore AI state */ newcat_set_trn(rig, priv->trn_state); /* ignore status in case it's not supported */ } if (priv->poweron != 0 && rig_s->auto_power_off && rig_s->comm_state) { rig_set_powerstat(rig, 0); priv->poweron = 0; } #if 0 // this apparently does not work -- we can't query EX103 if (is_ftdx5000) { // Restore EX103 status SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX103%c;", priv->front_rear_status); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); newcat_set_cmd(rig); // don't care about the return } #endif RETURNFUNC(RIG_OK); } /* * rig_set_config * * Set Configuration Token for Yaesu Radios */ int newcat_set_conf(RIG *rig, hamlib_token_t token, const char *val) { int ret = RIG_OK; struct newcat_priv_data *priv; ENTERFUNC; priv = (struct newcat_priv_data *)STATE(rig)->priv; if (priv == NULL) { RETURNFUNC(-RIG_EINTERNAL); } switch (token) { char *end; long value; case TOK_FAST_SET_CMD: ; //using strtol because atoi can lead to undefined behaviour value = strtol(val, &end, 10); if (end == val) { RETURNFUNC(-RIG_EINVAL); } if ((value == 0) || (value == 1)) { priv->fast_set_commands = (int)value; } else { RETURNFUNC(-RIG_EINVAL); } break; default: ret = -RIG_EINVAL; } RETURNFUNC(ret); } /* * rig_get_config * * Get Configuration Token for Yaesu Radios */ int newcat_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { int ret = RIG_OK; struct newcat_priv_data *priv; ENTERFUNC; priv = (struct newcat_priv_data *)STATE(rig)->priv; if (priv == NULL) { RETURNFUNC(-RIG_EINTERNAL); } switch (token) { case TOK_FAST_SET_CMD: if (sizeof(val) < 2) { RETURNFUNC(-RIG_ENOMEM); } SNPRINTF(val, val_len, "%d", priv->fast_set_commands); break; default: ret = -RIG_EINVAL; } RETURNFUNC(ret); } static int freq_60m[] = { 5332000, 5348000, 5358500, 5373000, 5405000 }; /* returns 0 if no exception or 1 if rig needs special handling */ int newcat_60m_exception(RIG *rig, freq_t freq, mode_t mode) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int channel = -1; int i; vfo_t vfo_mode; if (!(freq > 5.2 && freq < 5.5)) // we're not on 60M { return 0; } if (mode != RIG_MODE_CW && mode != RIG_MODE_USB && mode != RIG_MODE_PKTUSB && mode != RIG_MODE_RTTYR) { rig_debug(RIG_DEBUG_ERR, "%s: only USB, PKTUSB, RTTYR, and CW allowed for 60M operations\n", __func__); return -RIG_EINVAL; } // some rigs need to skip freq/mode settings as 60M only operates in memory mode if (is_ft991 || is_ft897 || is_ft897d || is_ftdx5000 || is_ftdx10) { return 1; } if (!is_ftdx10 && !is_ft710 && !is_ftdx101d && !is_ftdx101mp) { return 0; } rig_debug(RIG_DEBUG_VERBOSE, "%s: 60M exception ignoring freq/mode commands\n", __func__); // If US mode we need to use memory channels SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0301%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } // 01 is the only exception so far -- others may be like UK and have full control too if (strncmp(&priv->ret_data[6], "01", 2) != 0) { return 0; } // no exception // so now we should have a rig that has fixed memory channels 501-510 in USB/CW-U mode // toggle vfo mode if we need to rig_debug(RIG_DEBUG_VERBOSE, "%s: 60M exception ignoring freq/mode commands\n", __func__); newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (vfo_mode != RIG_VFO_MEM) { err = newcat_vfomem_toggle(rig); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Error toggling VFO_MEM\n", __func__); return -err; } } // find the nearest slot below what is requested for (i = 0; i < 5; ++i) { if ((long)freq == freq_60m[i]) { channel = i; } } if ((long)freq == 5357000) { channel = 3; } // 60M channel for FT8 if (channel < 0) { rig_debug(RIG_DEBUG_ERR, "%s: 60M allowed frequencies are 5.332, 5.348, 5.3585, 5.373,5.405, got %g\n", __func__, freq / 1000); return -RIG_EINVAL; } if (mode == RIG_MODE_CW) { channel += 5; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MC%3d%c", channel + 501, cat_term); if ((err = newcat_set_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } return 1; } /* * newcat_set_freq * * Set frequency for a given VFO * RIG_TARGETABLE_VFO * Does not SET priv->current_vfo * */ int newcat_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char c; char target_vfo; int err; struct rig_caps *caps; struct rig_cache *cachep = CACHE(rig); struct rig_state *rig_s = STATE(rig); struct newcat_priv_data *priv; int special_60m = 0; vfo_t vfo_mode; ENTERFUNC; if (newcat_60m_exception(rig, freq, cachep->modeMainA)) { // we don't try to set freq on 60m for some rigs since we must be in memory mode // and we can't run split mode on 60M memory mode either if (cachep->split == RIG_SPLIT_ON) { rig_set_split_vfo(rig, RIG_VFO_A, RIG_VFO_A, RIG_SPLIT_OFF); } RETURNFUNC(RIG_OK); } // we don't set freq in this case if (!newcat_valid_command(rig, "FA")) { RETURNFUNC(-RIG_ENAVAIL); } if (!newcat_valid_command(rig, "FB")) { RETURNFUNC(-RIG_ENAVAIL); } priv = (struct newcat_priv_data *)rig_s->priv; caps = rig->caps; newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (vfo_mode == RIG_VFO_MEM) { // then we need to toggle back to VFO mode newcat_vfomem_toggle(rig); } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); // rig_debug(RIG_DEBUG_TRACE, "%s: translated vfo = %s\n", __func__, rig_strvfo(tvfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { ERRMSG(err, "newcat_set_vfo_from_alias"); RETURNFUNC(err); } /* vfo should now be modified to a valid VFO constant. */ /* DX3000/DX5000/450 can only do VFO_MEM on 60M */ /* So we will not change freq in that case */ // did have FTDX3000 as not capable of 60M set_freq but as of 2021-01-21 it works // special_60m = newcat_is_rig(rig, RIG_MODEL_FTDX3000); /* duplicate the following line to add more rigs */ // disabled to check 2019 firmware on FTDX5000 and FT450 behavior //special_60m = newcat_is_rig(rig, RIG_MODEL_FTDX5000); //special_60m |= newcat_is_rig(rig, RIG_MODEL_FT450); rig_debug(RIG_DEBUG_TRACE, "%s: special_60m=%d, 60m freq=%d, is_ftdx3000=%d,is_ftdx3000dm=%d\n", __func__, special_60m, freq >= 5300000 && freq <= 5410000, is_ftdx3000, is_ftdx3000dm); if (special_60m && (freq >= 5300000 && freq <= 5410000)) { rig_debug(RIG_DEBUG_TRACE, "%s: 60M VFO_MEM exception, no freq change done\n", __func__); RETURNFUNC(RIG_OK); /* make it look like we changed */ } if ((is_ftdx101d || is_ftdx101mp) && (freq >= 70000000 && freq <= 70499999)) { // ensure the tuner is off for 70cm -- can cause damage to the rig newcat_set_func(rig, RIG_VFO_A, RIG_FUNC_TUNER, 0); hl_usleep(100 * 1000); // give it a chance to turn off } switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: case RIG_VFO_MEM: c = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: c = 'B'; break; default: RETURNFUNC(-RIG_ENIMPL); /* Only VFO_A or VFO_B are valid */ } target_vfo = 'A' == c ? '0' : '1'; // some rigs like FTDX101D cannot change non-TX vfo freq // but they can change the TX vfo if ((is_ftdx101d || is_ftdx101mp) && cachep->ptt == RIG_PTT_ON) { rig_debug(RIG_DEBUG_TRACE, "%s: ftdx101 check vfo OK, vfo=%s, tx_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rig_s->tx_vfo)); // when in split we can change VFOB but not VFOA if (cachep->split == RIG_SPLIT_ON && target_vfo == '0') { RETURNFUNC(-RIG_ENTARGET); } // when not in split we can't change VFOA at all if (cachep->split == RIG_SPLIT_OFF && target_vfo == '0') { RETURNFUNC(-RIG_ENTARGET); } if (vfo != rig_s->tx_vfo) { RETURNFUNC(-RIG_ENTARGET); } } if (is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx1200) { // we have a few rigs that can't set freq while PTT_ON // so we'll try a few times to see if we just need to wait a bit // 3 retries should be about 400ms -- hopefully more than enough ptt_t ptt; int retry = 3; do { if (RIG_OK != (err = newcat_get_ptt(rig, vfo, &ptt))) { ERRMSG(err, "newcat_set_cmd failed"); RETURNFUNC(err); } if (ptt == RIG_PTT_ON) { rig_debug(RIG_DEBUG_WARN, "%s: ptt still on...retry#%d\n", __func__, retry); hl_usleep(100 * 1000); // 100ms pause if ptt still on } } while (err == RIG_OK && ptt == RIG_PTT_ON && retry-- > 0); if (ptt) { RETURNFUNC(-RIG_ENTARGET); } } if (RIG_MODEL_FT450 == caps->rig_model) { /* The FT450 only accepts F[A|B]nnnnnnnn; commands for the current VFO so we must use the VS[0|1]; command to check and select the correct VFO before setting the frequency */ // Plus we can't do the VFO swap if transmitting if (target_vfo == '1' && cachep->ptt == RIG_PTT_ON) { RETURNFUNC(-RIG_ENTARGET); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%c", cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { ERRMSG(err, "newcat_get_cmd"); RETURNFUNC(err); } if (priv->ret_data[2] != target_vfo) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%c%c", target_vfo, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); if (RIG_OK != (err = newcat_set_cmd(rig))) { ERRMSG(err, "newcat_set_cmd failed"); RETURNFUNC(err); } } } // W1HKJ // creation of the priv structure guarantees that the string can be NEWCAT_DATA_LEN // bytes in length. the SNPRINTF will only allow (NEWCAT_DATA_LEN - 1) chars // followed by the NULL terminator. // CAT command string for setting frequency requires that 8 digits be sent // including leading fill zeros // Call this after open to set width_frequency for later use if (priv->width_frequency == 0) { vfo_t vfo_mode; newcat_get_vfo_mode(rig, vfo, &vfo_mode); } // // Restore band memory if we can and band is changing -- we do it before we set the frequency // And only when not in split mode (note this check has been removed for testing) int changing; rig_debug(RIG_DEBUG_TRACE, "%s(%d)%s: STATE(rig)->current_vfo=%s\n", __FILE__, __LINE__, __func__, rig_strvfo(rig_s->current_vfo)); CACHE_RESET; if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { freq_t freqA; rig_get_freq(rig, RIG_VFO_A, &freqA); rig_debug(RIG_DEBUG_TRACE, "%s(%d)%s: checking VFOA for band change \n", __FILE__, __LINE__, __func__); changing = newcat_band_index(freq) != newcat_band_index(freqA); rig_debug(RIG_DEBUG_TRACE, "%s: VFO_A band changing=%d\n", __func__, changing); } else { freq_t freqB; rig_get_freq(rig, RIG_VFO_B, &freqB); rig_debug(RIG_DEBUG_TRACE, "%s(%d)%s: checking VFOB for band change \n", __FILE__, __LINE__, __func__); changing = newcat_band_index(freq) != newcat_band_index(freqB); rig_debug(RIG_DEBUG_TRACE, "%s: VFO_B band changing=%d\n", __func__, changing); } if (newcat_valid_command(rig, "BS") && changing && !rig_s->disable_yaesu_bandselect // remove the split check here -- hopefully works OK //&& !cachep->split // seems some rigs are problematic // && !(is_ftdx3000 || is_ftdx3000dm) // some rigs can't do BS command on 60M // && !(is_ftdx3000 || is_ftdx3000dm && newcat_band_index(freq) == 2) && !(is_ft2000 && newcat_band_index(freq) == 2) && !(is_ftdx1200 && newcat_band_index(freq) == 2) && !is_ft891 // 891 does not remember bandwidth so don't do this && !is_ft991 // 991 does not behave well with bandstack changes && rig->caps->get_vfo != NULL && rig->caps->set_vfo != NULL) // gotta' have get_vfo too { if (rig_s->current_vfo != vfo) { int vfo1 = 1, vfo2 = 0; if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { vfo1 = 0; vfo2 = 1; } // we need to change vfos, BS, and change back if (is_ft991 == FALSE && is_ft891 == FALSE && newcat_valid_command(rig, "VS")) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%d;BS%02d%c", vfo1, newcat_band_index(freq), cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", newcat_band_index(freq), cat_term); } if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#1=%s\n", __func__, rigerror(err)); } hl_usleep(500 * 1000); // wait for BS to do its thing and swap back if (newcat_valid_command(rig, "VS")) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS%d;", vfo2); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#3=%s\n", __func__, rigerror(err)); } } } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", newcat_band_index(freq), cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#2=%s\n", __func__, rigerror(err)); } hl_usleep(500 * 1000); // wait for BS to do its thing } #if 0 // disable for testing else { // Also need to do this for the other VFO on some Yaesu rigs // is redundant for rigs where band stack includes both vfos vfo_t vfotmp; freq_t freqtmp; err = rig_get_vfo(rig, &vfotmp); if (err != RIG_OK) { RETURNFUNC(err); } if (rig_s->vfo_list & RIG_VFO_MAIN) { err = rig_set_vfo(rig, vfotmp == RIG_VFO_MAIN ? RIG_VFO_SUB : RIG_VFO_MAIN); } else { err = rig_set_vfo(rig, vfotmp == RIG_VFO_A ? RIG_VFO_B : RIG_VFO_A); } if (err != RIG_OK) { RETURNFUNC(err); } rig_get_freq(rig, RIG_VFO_CURR, &freqtmp); if (err != RIG_OK) { RETURNFUNC(err); } // Cross band should work too // If the BS works on both VFOs then VFOB will have the band select answer // so now change needed // If the BS is by VFO then we'll need to do BS for the other VFO too if (newcat_band_index(freqtmp) != newcat_band_index(freq)) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", newcat_band_index(freq), cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected error with BS command#3=%s\n", __func__, rigerror(err)); } } // switch back to the starting vfo if (rig_s->vfo_list & RIG_VFO_MAIN) { err = rig_set_vfo(rig, vfotmp == RIG_VFO_MAIN ? RIG_VFO_MAIN : RIG_VFO_SUB); } else { err = rig_set_vfo(rig, vfotmp == RIG_VFO_A ? RIG_VFO_A : RIG_VFO_B); } if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_vfo failed: %s\n", __func__, rigerror(err)); RETURNFUNC(err); } // after band select re-read things -- may not have to change anything freq_t tmp_freqA, tmp_freqB; rmode_t tmp_mode; pbwidth_t tmp_width; rig_get_freq(rig, RIG_VFO_MAIN, &tmp_freqA); rig_get_freq(rig, RIG_VFO_SUB, &tmp_freqB); rig_get_mode(rig, RIG_VFO_MAIN, &tmp_mode, &tmp_width); rig_get_mode(rig, RIG_VFO_SUB, &tmp_mode, &tmp_width); if ((target_vfo == 0 && tmp_freqA == freq) || (target_vfo == 1 && tmp_freqB == freq)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq after band select already set to %"PRIfreq"\n", __func__, freq); RETURNFUNC(RIG_OK); // we're done then!! } } #endif // after band select re-read things -- may not have to change anything // reading both VFOs is really only needed for rigs with just one VFO stack // but we read them all to ensure we cover both types freq_t tmp_freqA = 0, tmp_freqB = 0; rmode_t tmp_mode; pbwidth_t tmp_width; // we need to update some info that BS may have caused CACHE_RESET; if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { rig_get_freq(rig, RIG_VFO_SUB, &tmp_freqA); } else { rig_get_freq(rig, RIG_VFO_MAIN, &tmp_freqB); } rig_get_mode(rig, RIG_VFO_MAIN, &tmp_mode, &tmp_width); rig_get_mode(rig, RIG_VFO_SUB, &tmp_mode, &tmp_width); if ((target_vfo == 0 && tmp_freqA == freq) || (target_vfo == 1 && tmp_freqB == freq)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: freq after band select already set to %"PRIfreq"\n", __func__, freq); RETURNFUNC(RIG_OK); // we're done then!! } // just drop through } rig_debug(RIG_DEBUG_VERBOSE, "%s: is_ft991=%d, CACHE(rig)->split=%d, vfo=%s\n", __func__, is_ft991, cachep->split, rig_strvfo(vfo)); if (priv->band_index < 0) { priv->band_index = newcat_band_index(freq); } // only use bandstack method when actually changing bands // there are multiple bandstacks so we just use the 1st one if (is_ft991 && vfo == RIG_VFO_A && priv->band_index != newcat_band_index(freq)) { if (cachep->split) { // FT991/991A bandstack does not work in split mode // so for a VFOA change we stop split, change bands, change freq, enable split SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "FT2;BS%02d;FA%09.0f;FT3;", newcat_band_index(freq), freq); } else // in non-split us BS to get bandstack info { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d;FA%09.0f;", newcat_band_index(freq), freq); } priv->band_index = newcat_band_index(freq); } else if (RIG_MODEL_FT450 == caps->rig_model) { if (c == 'B') { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VS1;F%c%0*"PRIll";VS0;", c, priv->width_frequency, (int64_t)freq); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "F%c%0*"PRIll";", c, priv->width_frequency, (int64_t)freq); } } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "F%c%0*"PRIll";", c, priv->width_frequency, (int64_t)freq); } rig_debug(RIG_DEBUG_TRACE, "%s:%d cmd_str = %s\n", __func__, __LINE__, priv->cmd_str); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC(err); } rig_debug(RIG_DEBUG_TRACE, "%s: band changing? old=%d, new=%d\n", __func__, newcat_band_index(freq), newcat_band_index(rig_s->current_freq)); if (RIG_MODEL_FT450 == caps->rig_model && priv->ret_data[2] != target_vfo) { /* revert current VFO */ rig_debug(RIG_DEBUG_TRACE, "%s:%d cmd_str = %s\n", __func__, __LINE__, priv->ret_data); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } /* * rig_get_freq * * Return Freq for a given VFO * RIG_TARGETABLE_FREQ * Does not SET priv->current_vfo * */ int newcat_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char command[3]; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; int err; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); if (!newcat_valid_command(rig, "FA")) { RETURNFUNC(-RIG_ENAVAIL); } if (!newcat_valid_command(rig, "FB")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: // what about MAIN_A/MAIN_B? c = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: // what about SUB_A/SUB_B? c = 'B'; break; case RIG_VFO_MEM: c = 'A'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported vfo=%s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); /* sorry, unsupported VFO */ } /* Build the command string */ SNPRINTF(command, sizeof(command), "F%c", c); if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); /* get freq */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } /* convert the read frequency string into freq_t and store in *freq */ sscanf(priv->ret_data + 2, "%"SCNfreq, freq); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo %s\n", __func__, *freq, rig_strvfo(vfo)); RETURNFUNC(RIG_OK); } int newcat_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct newcat_priv_data *priv; struct rig_cache *cachep = CACHE(rig); int err; rmode_t tmode; pbwidth_t twidth; split_t split_save = cachep->split; priv = (struct newcat_priv_data *)STATE(rig)->priv; ENTERFUNC; if (newcat_60m_exception(rig, cachep->freqMainA, mode)) { RETURNFUNC(RIG_OK); } // we don't set mode in this case if (!newcat_valid_command(rig, "MD")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } // if vfo is current the same don't do anything // we don't want to use cache in case the user is twiddling the rig if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { rig_get_mode(rig, vfo, &tmode, &twidth); if (mode == tmode && (twidth == width || width == RIG_PASSBAND_NOCHANGE)) { RETURNFUNC(RIG_OK); } if (mode != tmode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: mode changing from %s to %s\n", __func__, rig_strrmode(mode), rig_strrmode(tmode)); } if (width != twidth) { rig_debug(RIG_DEBUG_VERBOSE, "%s: width changing from %d to %d\n", __func__, (int)width, (int)twidth); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MD0x%c", cat_term); priv->cmd_str[3] = newcat_modechar(mode); if (priv->cmd_str[3] == '0') { RETURNFUNC(-RIG_EINVAL); } /* FT9000 RIG_TARGETABLE_MODE (mode and width) */ /* FT2000 mode only */ if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s \n", __func__, rig_strrmode(mode)); err = newcat_set_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { cachep->modeMainA = mode; } else { cachep->modeMainB = mode; } if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC(err); } if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } /* Set width after mode has been set */ err = newcat_set_rx_bandwidth(rig, vfo, mode, width); // some rigs if you set mode on VFOB it will turn off split // so if we started in split we query split and turn it back on if needed if (split_save) { split_t split; vfo_t tx_vfo; err = rig_get_split_vfo(rig, RIG_VFO_A, &split, &tx_vfo); // we'll just reset to split to what we want if we need to if (!split) { rig_debug(RIG_DEBUG_TRACE, "%s: turning split back on...buggy rig\n", __func__); err = rig_set_split_vfo(rig, RIG_VFO_A, split_save, RIG_VFO_B); } } RETURNFUNC(err); } int newcat_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; int err; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, "MD")) { RETURNFUNC(-RIG_ENAVAIL); } if (STATE(rig)->powerstat == 0) { rig_debug(RIG_DEBUG_WARN, "%s: Cannot get from rig when power is off\n", __func__); RETURNFUNC(RIG_OK); // to prevent repeats } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } /* Build the command string */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MD%c%c", main_sub_vfo, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get MODE */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } /* * The current mode value is a digit '0' ... 'C' * embedded at ret_data[3] in the read string. */ c = priv->ret_data[3]; /* default, unless set otherwise */ *width = RIG_PASSBAND_NORMAL; *mode = newcat_rmode_width(rig, vfo, c, width); if (*mode == '0') { rig_debug(RIG_DEBUG_ERR, "%s: *mode = '0'??\n", __func__); RETURNFUNC(-RIG_EPROTO); } if (RIG_PASSBAND_NORMAL == *width) { *width = rig_passband_normal(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: returning newcat_get_rx_bandwidth\n", __func__); RETURNFUNC(newcat_get_rx_bandwidth(rig, vfo, *mode, width)); } /* * newcat_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ int newcat_set_vfo(RIG *rig, vfo_t vfo) { struct newcat_priv_data *priv; struct rig_state *state; char c; int err, mem; vfo_t vfo_mode; char command[] = "VS"; state = STATE(rig); priv = (struct newcat_priv_data *)state->priv; priv->cache_start.tv_sec = 0; // invalidate the cache ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); // we can't change VFO while transmitting if (CACHE(rig)->ptt == RIG_PTT_ON) { RETURNFUNC(RIG_OK); } if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); /* passes RIG_VFO_MEM, RIG_VFO_A, RIG_VFO_B */ if (err < 0) { RETURNFUNC(err); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_B: case RIG_VFO_MAIN: case RIG_VFO_SUB: if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { c = '1'; } else { c = '0'; } err = newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (err != RIG_OK) { RETURNFUNC(err); } if (vfo_mode == RIG_VFO_MEM) { priv->current_mem = NC_MEM_CHANNEL_NONE; state->current_vfo = RIG_VFO_A; err = newcat_vfomem_toggle(rig); RETURNFUNC(err); } break; case RIG_VFO_MEM: if (priv->current_mem == NC_MEM_CHANNEL_NONE) { /* Only works correctly for VFO A */ if (state->current_vfo != RIG_VFO_A && state->current_vfo != RIG_VFO_MAIN) { RETURNFUNC(-RIG_ENTARGET); } /* get current memory channel */ err = newcat_get_mem(rig, vfo, &mem); if (err != RIG_OK) { RETURNFUNC(err); } /* turn on memory channel */ err = newcat_set_mem(rig, vfo, mem); if (err != RIG_OK) { RETURNFUNC(err); } /* Set current_mem now */ priv->current_mem = mem; } /* Set current_vfo now */ state->current_vfo = vfo; RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_ENIMPL); /* sorry, VFO not implemented */ } /* Build the command string */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, c, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); err = newcat_set_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } state->current_vfo = vfo; /* if set_vfo worked, set current_vfo */ rig_debug(RIG_DEBUG_TRACE, "%s: STATE(rig)->current_vfo = %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(RIG_OK); } // Either returns a valid RIG_VFO* or if < 0 an error code static vfo_t newcat_set_vfo_if_needed(RIG *rig, vfo_t vfo) { vfo_t oldvfo = STATE(rig)->current_vfo; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, oldvfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(oldvfo)); if (oldvfo != vfo) { int ret; ret = newcat_set_vfo(rig, vfo); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting vfo=%s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(ret); } } RETURNFUNC(oldvfo); } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ int newcat_get_vfo(RIG *rig, vfo_t *vfo) { struct rig_state *state = STATE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)state->priv; int err; vfo_t vfo_mode; char const *command = "VS"; ENTERFUNC; if (!vfo) { RETURNFUNC(-RIG_EINVAL); } /* Build the command string */ if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s;", command); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get VFO */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } /* * The current VFO value is a digit ('0' or '1' ('A' or 'B' * respectively)) embedded at ret_data[2] in the read string. */ switch (priv->ret_data[2]) { case '0': if (state->vfo_list & RIG_VFO_MAIN) { *vfo = RIG_VFO_MAIN; } else { *vfo = RIG_VFO_A; } break; case '1': if (state->vfo_list & RIG_VFO_SUB) { *vfo = RIG_VFO_SUB; } else { *vfo = RIG_VFO_B; } break; default: RETURNFUNC(-RIG_EPROTO); /* sorry, wrong current VFO */ } /* Check to see if RIG is in MEM mode */ err = newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (err != RIG_OK) { RETURNFUNC(err); } if (vfo_mode == RIG_VFO_MEM) { *vfo = RIG_VFO_MEM; } state->current_vfo = *vfo; /* set now */ rig_debug(RIG_DEBUG_TRACE, "%s: STATE(rig)->current_vfo = %s\n", __func__, rig_strvfo(state->current_vfo)); RETURNFUNC(RIG_OK); } int newcat_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err = -RIG_EPROTO; char txon[] = "TX1;"; ENTERFUNC; priv->cache_start.tv_sec = 0; // invalidate the cache if (!newcat_valid_command(rig, "TX")) { RETURNFUNC(-RIG_ENAVAIL); } switch (ptt) { case RIG_PTT_ON_MIC: /* Build the command string */ // the FTDX5000 uses menu 103 for front/rear audio in USB mode if (is_ftdx5000) { // Ensure FT5000 is back to MIC input SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1030;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); newcat_set_cmd(rig); // don't care about the return } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txon); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); break; case RIG_PTT_ON_DATA: /* Build the command string */ // the FTDX5000 uses menu 103 for front/rear audio in USB mode if (is_ftdx5000) { // Ensure FT5000 is back to MIC input SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1031;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); newcat_set_cmd(rig); // don't care about the return } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txon); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); break; case RIG_PTT_ON: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txon); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); break; case RIG_PTT_OFF: { const char txoff[] = "TX0;"; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", txoff); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); err = newcat_set_cmd(rig); // some rigs like the FT991 need time before doing anything else like set_freq // We won't mess with CW mode -- no freq change expected hopefully if (STATE(rig)->current_mode != RIG_MODE_CW && STATE(rig)->current_mode != RIG_MODE_CWR && STATE(rig)->current_mode != RIG_MODE_CWN && (is_ftdx3000 || is_ftdx3000dm) ) { // DX3000 with separate rx/tx antennas was failing frequency change // so we increased the sleep from 100ms to 300ms hl_usleep(300 * 1000); } } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(err); } int newcat_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; int err; ENTERFUNC; if (!newcat_valid_command(rig, "TX")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", "TX", cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get PTT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[2]; switch (c) { case '0': /* FT-950 "TX OFF", Original Release Firmware */ *ptt = RIG_PTT_OFF; break; case '1' : /* Just because, what the CAT Manual Shows */ case '2' : /* FT-950 Radio: Mic, Dataport, CW "TX ON" */ case '3' : /* FT-950 CAT port: Radio in "TX ON" mode [Not what the CAT Manual Shows] */ *ptt = RIG_PTT_ON; break; default: RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } int newcat_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "OS"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: c = '0'; break; case RIG_RPT_SHIFT_PLUS: c = '1'; break; case RIG_RPT_SHIFT_MINUS: c = '2'; break; default: RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c%c", command, main_sub_vfo, c, cat_term); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "OS"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo, cat_term); /* Get Rptr Shift */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[3]; switch (c) { case '0': *rptr_shift = RIG_RPT_SHIFT_NONE; break; case '1': *rptr_shift = RIG_RPT_SHIFT_PLUS; break; case '2': *rptr_shift = RIG_RPT_SHIFT_MINUS; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char command[32]; freq_t freq = 0; ENTERFUNC; err = newcat_get_freq(rig, vfo, &freq); // Need to get freq to determine band if (err < 0) { RETURNFUNC(err); } if (is_ft450) { strcpy(command, "EX050"); // Step size is 100 kHz offs /= 100000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%03li%c", command, offs, cat_term); } else if (is_ft2000) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX076"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX077"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft950) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX057"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX058"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft891) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX0904"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX0905"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft991) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX080"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX081"); } else if (freq >= 144000000 && freq <= 148000000) { strcpy(command, "EX082"); } else if (freq >= 430000000 && freq <= 450000000) { strcpy(command, "EX083"); } else { // only valid on 10m to 70cm bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ft710) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX010318"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX010319"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx1200) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX087"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX088"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX086"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX087"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx5000) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX081"); } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX082"); } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { if (freq >= 28000000 && freq <= 29700000) { strcpy(command, "EX010315"); if (is_ftdx10) { strcpy(command, "EX010317"); } } else if (freq >= 50000000 && freq <= 54000000) { strcpy(command, "EX010316"); if (is_ftdx10) { strcpy(command, "EX010318"); } } else { // only valid on 10m and 6m bands RETURNFUNC(-RIG_EINVAL); } // Step size is 1 kHz offs /= 1000; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%04li%c", command, offs, cat_term); } else { RETURNFUNC(-RIG_ENAVAIL); } RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *retoffs; freq_t freq = 0; int step = 0; ENTERFUNC; err = newcat_get_freq(rig, vfo, &freq); // Need to get freq to determine band if (err < 0) { RETURNFUNC(err); } if (is_ft450) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX050%c", cat_term); // Step size is 100 kHz step = 100000; } else if (is_ft2000) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX076%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX077%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft950) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX057%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX058%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft891) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0904%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0905%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft991) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX080%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX081%c", cat_term); } else if (freq >= 144000000 && freq <= 148000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX082%c", cat_term); } else if (freq >= 430000000 && freq <= 450000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX083%c", cat_term); } else { // only valid on 10m to 70cm bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ft710) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010318%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010319%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx1200) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX087%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX088%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx3000 || is_ftdx3000dm) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX086%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX087%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx5000) { if (freq >= 28000000 && freq <= 29700000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX081%c", cat_term); } else if (freq >= 50000000 && freq <= 54000000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX082%c", cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { if (freq >= 28000000 && freq <= 29700000) { char *cmd = "EX010315%c"; if (is_ftdx10) { cmd = "EX010317%c"; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), cmd, cat_term); } else if (freq >= 50000000 && freq <= 54000000) { char *cmd = "EX010316%c"; if (is_ftdx10) { cmd = "EX010318%c"; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), cmd, cat_term); } else { // only valid on 10m and 6m bands *offs = 0; RETURNFUNC(RIG_OK); } // Step size is 1 kHz step = 1000; } else { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_get_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retoffs = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *offs = atol(retoffs) * step; RETURNFUNC(RIG_OK); } int newcat_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { ENTERFUNC; rmode_t tmp_mode; pbwidth_t tmp_width; int err; rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, tx_mode=%s, tx_width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(tx_mode), (int)tx_width); err = newcat_get_mode(rig, RIG_VFO_B, &tmp_mode, &tmp_width); if (err < 0) { RETURNFUNC(err); } if (tmp_mode == tx_mode && (tmp_width == tx_width || tmp_width == RIG_PASSBAND_NOCHANGE)) { RETURNFUNC(RIG_OK); } err = rig_set_mode(rig, vfo, tx_mode, tx_width); if (err < 0) { RETURNFUNC(err); } if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { CACHE(rig)->modeMainA = tx_mode; } else { CACHE(rig)->modeMainB = tx_mode; } RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int err; ENTERFUNC; err = newcat_get_mode(rig, RIG_VFO_B, tx_mode, tx_width); if (err < 0) { RETURNFUNC(err); } RETURNFUNC(RIG_OK); } int newcat_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int err; ENTERFUNC; vfo_t rx_vfo = RIG_VFO_NONE; rig_debug(RIG_DEBUG_TRACE, "%s: entered, rxvfo=%s, txvfo=%s, split=%d\n", __func__, rig_strvfo(vfo), rig_strvfo(tx_vfo), split); err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (newcat_60m_exception(rig, CACHE(rig)->freqMainA, CACHE(rig)->modeMainA)) { rig_debug(RIG_DEBUG_VERBOSE, "%s: force set_split off since we're on 60M exception\n", __func__); split = RIG_SPLIT_OFF; //RETURNFUNC(RIG_OK); // fake the return code to make things happy } if (is_ft991) { // FT-991(A) doesn't have a concept of an active VFO, so VFO B needs to be the split VFO vfo = RIG_VFO_A; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_B : RIG_VFO_A; } else if (is_ftdx101d || is_ftdx101mp) { // FTDX101(D/MP) always use Sub VFO for transmit when in split mode vfo = RIG_VFO_MAIN; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_SUB : RIG_VFO_MAIN; } else if (is_ftdx10) { // FTDX10 always uses VFO B for transmit when in split mode vfo = RIG_VFO_A; tx_vfo = RIG_SPLIT_ON == split ? RIG_VFO_B : RIG_VFO_A; } else { err = newcat_get_vfo(rig, &rx_vfo); /* sync to rig current vfo */ if (err != RIG_OK) { RETURNFUNC(err); } } switch (split) { case RIG_SPLIT_OFF: err = -RIG_ENAVAIL; if (newcat_valid_command(rig, "ST")) { err = newcat_set_split(rig, split, &rx_vfo, &tx_vfo); } if (err == -RIG_ENAVAIL) { err = newcat_set_tx_vfo(rig, vfo); if (err != RIG_OK) { RETURNFUNC(err); } } if (rx_vfo != vfo && newcat_valid_command(rig, "VS")) { err = rig_set_vfo(rig, vfo); if (err != RIG_OK) { RETURNFUNC(err); } } break; case RIG_SPLIT_ON: err = -RIG_ENAVAIL; if (newcat_valid_command(rig, "ST")) { err = newcat_set_split(rig, split, &rx_vfo, &tx_vfo); } if (err == -RIG_ENAVAIL) { err = newcat_set_tx_vfo(rig, tx_vfo); if (err != RIG_OK) { RETURNFUNC(err); } } if (rx_vfo != vfo) { err = rig_set_vfo(rig, vfo); if (err != RIG_OK && err != -RIG_ENAVAIL) { RETURNFUNC(err); } } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int err; ENTERFUNC; err = newcat_set_vfo_from_alias(rig, &vfo); if (err != RIG_OK) { RETURNFUNC(err); } err = -RIG_ENAVAIL; if (newcat_valid_command(rig, "ST")) { err = newcat_get_split(rig, split, tx_vfo); } if (err == -RIG_ENAVAIL) { err = newcat_get_tx_vfo(rig, tx_vfo); if (err != RIG_OK) { RETURNFUNC(err); } rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(*tx_vfo), rig_strvfo(STATE(rig)->current_vfo)); if (*tx_vfo != STATE(rig)->current_vfo) { *split = RIG_SPLIT_ON; } else { *split = RIG_SPLIT_OFF; } } rig_debug(RIG_DEBUG_TRACE, "SPLIT = %d, vfo = %s, TX_vfo = %s\n", *split, rig_strvfo(vfo), rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } int newcat_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int oldvfo; int ret; ENTERFUNC; if (!newcat_valid_command(rig, "RT")) { RETURNFUNC(-RIG_ENAVAIL); } oldvfo = newcat_set_vfo_if_needed(rig, vfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } if (rit > rig->caps->max_rit) { rit = rig->caps->max_rit; /* + */ } else if (labs(rit) > rig->caps->max_rit) { rit = - rig->caps->max_rit; /* - */ } if (rit == 0) // don't turn it off just because it is zero { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%c", cat_term); } else if (rit < 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%c", cat_term, labs(rit), cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%c", cat_term, labs(rit), cat_term); } ret = newcat_set_cmd(rig); oldvfo = newcat_set_vfo_if_needed(rig, oldvfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } RETURNFUNC(ret); } int newcat_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *retval; int err; int offset = 0; char *cmd = "IF"; ENTERFUNC; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { // OI always returns VFOB and IF always VFOA cmd = "OI"; } if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } *rit = 0; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", cmd, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get RIT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } // e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq) // so we now check to ensure we know the length of the response switch (strlen(priv->ret_data)) { case 27: offset = 13; break; case 41: // FT-991 V2-01 seems to randomly give 13 extra bytes case 28: offset = 14; break; default: offset = 0; } if (offset == 0) { rig_debug(RIG_DEBUG_ERR, "%s: incorrect length of IF response, expected 27 or 28, got %du\n", __func__, (int)strlen(priv->ret_data)); RETURNFUNC(-RIG_EPROTO); } retval = priv->ret_data + offset; retval[5] = '\0'; // return the current offset even if turned off *rit = (shortfreq_t) atoi(retval); RETURNFUNC(RIG_OK); } int newcat_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int oldvfo; int ret; ENTERFUNC; if (!newcat_valid_command(rig, "XT")) { RETURNFUNC(-RIG_ENAVAIL); } oldvfo = newcat_set_vfo_if_needed(rig, vfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } if (xit > rig->caps->max_xit) { xit = rig->caps->max_xit; /* + */ } else if (labs(xit) > rig->caps->max_xit) { xit = - rig->caps->max_xit; /* - */ } if (xit == 0) { // don't turn it off just because the offset is zero SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%c", cat_term); } else if (xit < 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRD%04ld%c", cat_term, labs(xit), cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RC%cRU%04ld%c", cat_term, labs(xit), cat_term); } ret = newcat_set_cmd(rig); oldvfo = newcat_set_vfo_if_needed(rig, vfo); if (oldvfo < 0) { RETURNFUNC(oldvfo); } RETURNFUNC(ret); } int newcat_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *retval; int err; int offset = 0; char *cmd = "IF"; ENTERFUNC; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { // OI always returns VFOB and IF always VFOA cmd = "OI"; } if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } *xit = 0; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", cmd, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get XIT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } // e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq) // so we now check to ensure we know the length of the response switch (strlen(priv->ret_data)) { case 27: offset = 13; break; case 41: // FT-991 V2-01 seems to randomly give 13 extra bytes case 28: offset = 14; break; default: offset = 0; } if (offset == 0) { rig_debug(RIG_DEBUG_ERR, "%s: incorrect length of IF response, expected 27 or 28, got %du\n", __func__, (int)strlen(priv->ret_data)); RETURNFUNC(-RIG_EPROTO); } retval = priv->ret_data + offset; retval[5] = '\0'; // return the offset even when turned off *xit = (shortfreq_t) atoi(retval); RETURNFUNC(RIG_OK); } int newcat_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int err, i; pbwidth_t width; rmode_t mode; ncboolean ts_match; ENTERFUNC; err = newcat_get_mode(rig, vfo, &mode, &width); if (err < 0) { RETURNFUNC(err); } /* assume 2 tuning steps per mode */ for (i = 0, ts_match = FALSE; i < HAMLIB_TSLSTSIZ && rig->caps->tuning_steps[i].ts; i++) if (rig->caps->tuning_steps[i].modes & mode) { if (ts <= rig->caps->tuning_steps[i].ts) { err = newcat_set_faststep(rig, FALSE); } else { err = newcat_set_faststep(rig, TRUE); } if (err != RIG_OK) { RETURNFUNC(err); } ts_match = TRUE; break; } /* if mode */ rig_debug(RIG_DEBUG_TRACE, "ts_match = %d, i = %d, ts = %d\n", ts_match, i, (int)ts); if (ts_match) { RETURNFUNC(RIG_OK); } else { RETURNFUNC(-RIG_ENAVAIL); } } int newcat_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { pbwidth_t width; rmode_t mode; int err, i; ncboolean ts_match; ncboolean fast_step = FALSE; ENTERFUNC; err = newcat_get_mode(rig, vfo, &mode, &width); if (err < 0) { RETURNFUNC(err); } err = newcat_get_faststep(rig, &fast_step); if (err < 0) { RETURNFUNC(err); } /* assume 2 tuning steps per mode */ for (i = 0, ts_match = FALSE; i < HAMLIB_TSLSTSIZ && rig->caps->tuning_steps[i].ts; i++) if (rig->caps->tuning_steps[i].modes & mode) { if (fast_step == FALSE) { *ts = rig->caps->tuning_steps[i].ts; } else { *ts = rig->caps->tuning_steps[i + 1].ts; } ts_match = TRUE; break; } rig_debug(RIG_DEBUG_TRACE, "ts_match = %d, i = %d, i+1 = %d, *ts = %d\n", ts_match, i, i + 1, (int)*ts); if (ts_match) { RETURNFUNC(RIG_OK); } else { RETURNFUNC(-RIG_ENAVAIL); } } int newcat_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_tone(RIG *rig, vfo_t vfo, tone_t tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_tone(RIG *rig, vfo_t vfo, tone_t *tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int i; ncboolean tone_match; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, "CN")) { RETURNFUNC(-RIG_ENAVAIL); } if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } for (i = 0, tone_match = FALSE; rig->caps->ctcss_list[i] != 0; i++) if (tone == rig->caps->ctcss_list[i]) { tone_match = TRUE; break; } rig_debug(RIG_DEBUG_TRACE, "%s: tone = %u, tone_match = %d, i = %d", __func__, tone, tone_match, i); if (tone_match == FALSE && tone != 0) { RETURNFUNC(-RIG_ENAVAIL); } if (tone == 0) /* turn off ctcss */ { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT%c0%c", main_sub_vfo, cat_term); } else { if (is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN%c0%03d%cCT%c2%c", main_sub_vfo, i, cat_term, main_sub_vfo, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CN%c%02d%cCT%c2%c", main_sub_vfo, i, cat_term, main_sub_vfo, cat_term); } } RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int t; int ret_data_len; char *retlvl; char cmd[] = "CN"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c0%c", cmd, main_sub_vfo, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, cat_term); } /* Get CTCSS TONE */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; t = atoi(retlvl); /* tone index */ if (t < 0 || t > 49) { RETURNFUNC(-RIG_ENAVAIL); } *tone = rig->caps->ctcss_list[t]; RETURNFUNC(RIG_OK); } int newcat_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_tone_sql(RIG *rig, vfo_t vfo, tone_t tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_tone_sql(RIG *rig, vfo_t vfo, tone_t *tone) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int err; ENTERFUNC; err = newcat_set_ctcss_tone(rig, vfo, tone); if (err != RIG_OK) { RETURNFUNC(err); } /* Change to sql */ if (tone) { err = newcat_set_func(rig, vfo, RIG_FUNC_TSQL, TRUE); if (err != RIG_OK) { RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } int newcat_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int err; ENTERFUNC; err = newcat_get_ctcss_tone(rig, vfo, tone); RETURNFUNC(err); } int newcat_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { int rig_id; ENTERFUNC; rig_id = newcat_get_rigid(rig); switch (rig_id) { case NC_RIGID_FT450: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "case FT450 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FT950: /* 100 Watts */ *mwpower = power * 100000; /* 0..100 Linear scale */ rig_debug(RIG_DEBUG_TRACE, "case FT950 - rig_id = %d, power = %f, *mwpower = %u\n", rig_id, power, *mwpower); break; case NC_RIGID_FT2000: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "case FT2000 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FT2000D: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FT2000D - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX5000: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FTDX5000 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX9000D: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000D - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX9000Contest: /* 200 Watts */ *mwpower = power * 200000; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000Contest - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX9000MP: /* 400 Watts */ *mwpower = power * 400000; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000MP - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; case NC_RIGID_FTDX1200: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "case FTDX1200 - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); break; default: /* 100 Watts */ *mwpower = power * 100000; rig_debug(RIG_DEBUG_TRACE, "default - rig_id = %d, *mwpower = %u\n", rig_id, *mwpower); } RETURNFUNC(RIG_OK); } int newcat_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { int rig_id; ENTERFUNC; rig_id = newcat_get_rigid(rig); switch (rig_id) { case NC_RIGID_FT450: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "case FT450 - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FT950: /* 100 Watts */ *power = mwpower / 100000.0; /* 0..100 Linear scale */ rig_debug(RIG_DEBUG_TRACE, "case FT950 - rig_id = %d, mwpower = %u, *power = %f\n", rig_id, mwpower, *power); break; case NC_RIGID_FT2000: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "case FT2000 - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FT2000D: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FT2000D - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX5000: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX5000 - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX9000D: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000D - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX9000Contest: /* 200 Watts */ *power = mwpower / 200000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000Contest - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX9000MP: /* 400 Watts */ *power = mwpower / 400000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX9000MP - rig_id = %d, *power = %f\n", rig_id, *power); break; case NC_RIGID_FTDX1200: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "case FTDX1200 - rig_id = %d, *power = %f\n", rig_id, *power); break; default: /* 100 Watts */ *power = mwpower / 100000.0; rig_debug(RIG_DEBUG_TRACE, "default - rig_id = %d, *power = %f\n", rig_id, *power); } RETURNFUNC(RIG_OK); } int newcat_set_powerstat(RIG *rig, powerstat_t status) { hamlib_port_t *rp = RIGPORT(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; int i = 0; int retry_save; ENTERFUNC; #if 0 // all Yaesu rigs have PS and calling this here interferes with power on if (!newcat_valid_command(rig, "PS")) { RETURNFUNC(-RIG_ENAVAIL); } #endif switch (status) { case RIG_POWER_ON: // When powering on a Yaesu rig needs dummy bytes to wake it up, // then wait from 1 to 2 seconds and issue the power-on command again HAMLIB_TRACE; write_block(rp, (unsigned char *) "PS1;", 4); hl_usleep(1200000); write_block(rp, (unsigned char *) "PS1;", 4); // some rigs reset the serial port during power up // so we reopen the com port again HAMLIB_TRACE; //oser_close(rp); // we can add more rigs to this exception to speed them up if (!is_ft991) { rig_close(rig); hl_usleep(3000000); //PTTPORT(rig)->fd = ser_open(rp); rig_open(rig); } break; case RIG_POWER_OFF: case RIG_POWER_STANDBY: retval = write_block(rp, (unsigned char *) "PS0;", 4); priv->poweron = 0; RETURNFUNC(retval); default: RETURNFUNC(-RIG_EINVAL); } HAMLIB_TRACE; retry_save = rp->retry; rp->retry = 0; if (status == RIG_POWER_ON) // wait for wakeup only { for (i = 0; i < 8; ++i) // up to ~10 seconds including the timeouts { freq_t freq; hl_usleep(1000000); rig_flush(rp); retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval == RIG_OK) { rp->retry = retry_save; priv->poweron = 1; RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: Wait #%d for power up\n", __func__, i + 1); retval = write_block(rp, (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)); if (retval != RIG_OK) { RETURNFUNC(retval); } } } rp->retry = retry_save; if (i == 9) { rig_debug(RIG_DEBUG_TRACE, "%s: timeout waiting for powerup, try %d\n", __func__, i + 1); retval = -RIG_ETIMEOUT; } RETURNFUNC(retval); } /* * This functions returns an error if the rig is off, dah */ int newcat_get_powerstat(RIG *rig, powerstat_t *status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int result; char ps; char command[] = "PS"; ENTERFUNC; *status = RIG_POWER_OFF; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } // The first PS command has two purposes: // 1. to detect that the rig is turned on when it responds with PS1 immediately // 2. to act as dummy wake-up data for a rig that is turned off SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); // Timeout needs to be set temporarily to a low value, // so that the second command can be sent in 2 seconds, which is what Yaesu rigs expect. short retry_save; short timeout_retry_save; int timeout_save; retry_save = rp->retry; timeout_retry_save = rp->timeout_retry; timeout_save = rp->timeout; rp->retry = 0; rp->timeout_retry = 0; rp->timeout = 500; result = newcat_get_cmd(rig); rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; rp->timeout = timeout_save; // Rig may respond here already if (result == RIG_OK) { ps = priv->ret_data[2]; switch (ps) { case '1': *status = RIG_POWER_ON; priv->poweron = 1; RETURNFUNC(RIG_OK); case '0': *status = RIG_POWER_OFF; priv->poweron = 0; RETURNFUNC(RIG_OK); default: // fall through to retry command break; } } // Yeasu rigs in powered-off state require the PS command to be sent between 1 and 2 seconds after dummy data hl_usleep(1100000); // Discard any unsolicited data rig_flush(rp); result = newcat_get_cmd(rig); if (result != RIG_OK) { RETURNFUNC(result); } ps = priv->ret_data[2]; switch (ps) { case '1': *status = RIG_POWER_ON; break; case '0': *status = RIG_POWER_OFF; break; default: RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } int newcat_reset(RIG *rig, reset_t reset) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } /* If we ever want to support ANT3 better on the FTDX101D Maybe make ANT_4/5/6/7? Since firmware version 201906 EX0301030 => RX 3 - TX 3 => MONITOR [3] EX0301031 => RX 3 - TX 1 => MONITOR [R/T1] EX0301032 => RX 3 - TX 2 => MONITOR [R/T2] EX0301033 => RX-ANT => MONITOR [RANT] */ int newcat_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char which_ant; char command[] = "AN"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if ((rig->caps->targetable_vfo & RIG_TARGETABLE_ANT)) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (ant) { case RIG_ANT_1: which_ant = '1'; break; case RIG_ANT_2: which_ant = '2'; break; case RIG_ANT_3: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(-RIG_EINVAL); } if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { RETURNFUNC(-RIG_EINVAL); } which_ant = '3'; break; case RIG_ANT_4: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(-RIG_EINVAL); } if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { RETURNFUNC(-RIG_EINVAL); } which_ant = '4'; break; case RIG_ANT_5: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(-RIG_EINVAL); } if (newcat_is_rig(rig, RIG_MODEL_FTDX1200)) { RETURNFUNC(-RIG_EINVAL); } /* RX only, on FT-2000/FT-5000/FT-9000 */ which_ant = '5'; break; default: RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c%c", command, main_sub_vfo, which_ant, cat_term); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "AN"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_ANT) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo, cat_term); /* Get ANT */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[3]; switch (c) { case '1': *ant_curr = RIG_ANT_1; break; case '2' : *ant_curr = RIG_ANT_2; break; case '3' : *ant_curr = RIG_ANT_3; break; case '4' : *ant_curr = RIG_ANT_4; break; case '5' : *ant_curr = RIG_ANT_5; break; default: RETURNFUNC(-RIG_EPROTO); } *ant_tx = * ant_rx = *ant_curr; RETURNFUNC(RIG_OK); } static int band2rig(hamlib_band_t band) { int retval = 0; switch (band) { case RIG_BAND_160M: retval = 0; break; case RIG_BAND_80M: retval = 1; break; case RIG_BAND_60M: retval = 2; break; case RIG_BAND_40M: retval = 3; break; case RIG_BAND_30M: retval = 4; break; case RIG_BAND_20M: retval = 5; break; case RIG_BAND_17M: retval = 6; break; case RIG_BAND_15M: retval = 7; break; case RIG_BAND_12M: retval = 8; break; case RIG_BAND_10M: retval = 9; break; case RIG_BAND_6M: retval = 10; break; case RIG_BAND_GEN: retval = 11; break; case RIG_BAND_MW: retval = 12; break; case RIG_BAND_AIR: retval = 14; break; case RIG_BAND_144MHZ: retval = 15; break; case RIG_BAND_430MHZ: retval = 16; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown band index=%d\n", __func__, band); retval = -RIG_EINVAL; break; } return retval; } int newcat_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct rig_state *state = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int i; int fpf; char main_sub_vfo = '0'; char *format; gran_t *level_info; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } err = check_level_param(rig, level, val, &level_info); if (err != RIG_OK) { RETURNFUNC(err); } switch (level) { case RIG_LEVEL_RFPOWER: if (!newcat_valid_command(rig, "PC")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx3000dm) /* No separate rig->caps for this rig :-( */ { fpf = (int)((val.f * 50.0f) + 0.5f); } else { fpf = (int)((val.f / level_info->step.f) + 0.5f); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PC%03d%c", fpf, cat_term); break; case RIG_LEVEL_AF: if (!newcat_valid_command(rig, "AG")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AG%c%03d%c", main_sub_vfo, fpf, cat_term); break; case RIG_LEVEL_AGC: if (!newcat_valid_command(rig, "GT")) { RETURNFUNC(-RIG_ENAVAIL); } switch (val.i) { case RIG_AGC_OFF: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT00;"); break; case RIG_AGC_FAST: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT01;"); break; case RIG_AGC_MEDIUM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT02;"); break; case RIG_AGC_SLOW: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT03;"); break; case RIG_AGC_AUTO: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT04;"); break; default: RETURNFUNC(-RIG_EINVAL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_IF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "IS")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } rig_debug(RIG_DEBUG_TRACE, "%s: LEVEL_IF val.i=%d\n", __func__, val.i); if (abs(val.i) > rig->caps->max_ifshift) { if (val.i > 0) { val.i = rig->caps->max_ifshift; } else { val.i = rig->caps->max_ifshift * -1; } } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS%c0%+.4d%c", main_sub_vfo, val.i, cat_term); } else if (is_ftdx10 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS00%+.4d%c", val.i, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS0%d%+.4d%c", val.i == 0 ? 0 : 1, val.i, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS%c%+.4d%c", main_sub_vfo, val.i, cat_term); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in AM/FM modes if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_AM || mode & RIG_MODE_FM || mode & RIG_MODE_AMN || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_CWPITCH: { int kp; if (!newcat_valid_command(rig, "KP")) { RETURNFUNC(-RIG_ENAVAIL); } // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps kp = (val.i - level_info->min.i + (level_info->step.i / 2)) / level_info->step.i; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KP%02d%c", kp, cat_term); break; } case RIG_LEVEL_KEYSPD: if (!newcat_valid_command(rig, "KS")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KS%03d%c", val.i, cat_term); break; case RIG_LEVEL_MICGAIN: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "MG")) { RETURNFUNC(-RIG_ENAVAIL); } rmode_t exclude = RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR; if ((STATE(rig)->tx_vfo == RIG_VFO_A && (cachep->modeMainA & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_B && (cachep->modeMainB & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_C && (cachep->modeMainC & exclude))) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig cannot set MG in CW/RTTY modes\n", __func__); RETURNFUNC(RIG_OK); } if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MG%03d%c", fpf, cat_term); // Some Yaesu rigs reject this command in RTTY modes if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_RTTY || mode & RIG_MODE_RTTYR) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_METER: if (!newcat_valid_command(rig, "MS")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) // new format for the command with VFO selection { format = "MS0%d;"; if (vfo == RIG_VFO_SUB) { format = "MS1%d;"; } } else if (is_ftdx10) { format = "MS%d0;"; } else { format = "MS%d;"; } rig_debug(RIG_DEBUG_TRACE, "%s: format=%s\n", __func__, format); switch (val.i) { case RIG_METER_ALC: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 1); break; case RIG_METER_PO: if (newcat_is_rig(rig, RIG_MODEL_FT950)) { RETURNFUNC(RIG_OK); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 2); } break; case RIG_METER_SWR: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 3); break; case RIG_METER_COMP: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 0); break; case RIG_METER_IC: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 4); break; case RIG_METER_VDD: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), format, 5); break; rig_debug(RIG_DEBUG_ERR, "%s: unknown val.i=%d\n", __func__, val.i); default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_PREAMP: if (!newcat_valid_command(rig, "PA")) { RETURNFUNC(-RIG_ENAVAIL); } if (val.i == 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PA00%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; } priv->cmd_str[0] = '\0'; for (i = 0; state->preamp[i] != RIG_DBLST_END; i++) { if (state->preamp[i] == val.i) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PA0%d%c", i + 1, cat_term); break; } } if (strlen(priv->cmd_str) == 0) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_ATT: if (!newcat_valid_command(rig, "RA")) { RETURNFUNC(-RIG_ENAVAIL); } if (val.i == 0) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RA00%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; } priv->cmd_str[0] = '\0'; for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++) { if (state->attenuator[i] == val.i) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RA0%d%c", i + 1, cat_term); break; } } if (strlen(priv->cmd_str) == 0) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_RF: if (!newcat_valid_command(rig, "RG")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%03d%c", main_sub_vfo, fpf, cat_term); break; case RIG_LEVEL_NR: if (!newcat_valid_command(rig, "RL")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5); if (newcat_is_rig(rig, RIG_MODEL_FT450)) { if (fpf < 1) { fpf = 1; } if (fpf > 11) { fpf = 11; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RL0%02d%c", fpf, cat_term); } else { if (is_ft991) { if (fpf > 15) { fpf = 15; } if (fpf < 1) { fpf = 1; } } else { if (fpf > 15) { fpf = 10; } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RL0%02d%c", fpf, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } } break; case RIG_LEVEL_COMP: if (!newcat_valid_command(rig, "PL")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PL%03d%c", fpf, cat_term); break; case RIG_LEVEL_BKINDL: { int millis; value_t keyspd; if (!newcat_valid_command(rig, "SD")) { RETURNFUNC(-RIG_ENAVAIL); } // Convert 10/ths of dots to milliseconds using the current key speed err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd); if (err != RIG_OK) { RETURNFUNC(err); } millis = dot10ths_to_millis(val.i, keyspd.i); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { if (millis <= 30) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD00;"); } else if (millis <= 50) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD01;"); } else if (millis <= 100) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD02;"); } else if (millis <= 150) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD03;"); } else if (millis <= 200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD04;"); } else if (millis <= 250) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD05;"); } else if (millis > 2900) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD33;"); } else { // This covers 300-2900 06-32 SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%02d;", 6 + ((millis - 300) / 100)); } } else if (is_ftdx5000) { if (millis < 20) { millis = 20; } if (millis > 5000) { millis = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } else if (is_ft950 || is_ft450 || is_ft891 || is_ft991 || is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm) { if (millis < 30) { millis = 30; } if (millis > 3000) { millis = 3000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } else if (is_ft2000 || is_ftdx9000) { if (millis < 0) { millis = 0; } if (millis > 5000) { millis = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } else // default { if (millis < 1) { millis = 1; } if (millis > 5000) { millis = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%04d%c", millis, cat_term); } break; } case RIG_LEVEL_SQL: if (!newcat_valid_command(rig, "SQ")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%03d%c", main_sub_vfo, fpf, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_VOXDELAY: if (!newcat_valid_command(rig, "VD")) { RETURNFUNC(-RIG_ENAVAIL); } /* VOX delay, api int (tenth of seconds), ms for rig */ val.i = val.i * 100; rig_debug(RIG_DEBUG_TRACE, "%s: vali=%d\n", __func__, val.i); if (is_ft950 || is_ft450 || is_ftdx1200) { if (val.i < 100) /* min is 30ms but spec is 100ms Unit Intervals */ { val.i = 30; } if (val.i > 3000) { val.i = 3000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term); } else if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) // new lookup table argument { rig_debug(RIG_DEBUG_TRACE, "%s: ft101 #1 val.i=%d\n", __func__, val.i); if (val.i == 0) { ; } else if (val.i <= 100) { val.i = 2; } else if (val.i <= 200) { val.i = 4; } else if (val.i > 3000) { val.i = 33; } else { val.i = (val.i - 300) / 100 + 6; } rig_debug(RIG_DEBUG_TRACE, "%s: ftdx101/ftdx10 #1 val.i=%d\n", __func__, val.i); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%02d%c", val.i, cat_term); } else if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { if (val.i < 0) { val.i = 0; } if (val.i > 5000) { val.i = 5000; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%04d%c", val.i, cat_term); } break; case RIG_LEVEL_VOXGAIN: if (!newcat_valid_command(rig, "VG")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VG%03d%c", fpf, cat_term); break; case RIG_LEVEL_ANTIVOX: fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AV%03d%c", fpf, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX176%03d%c", fpf, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX183%03d%c", fpf, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX145%03d%c", fpf, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%03d%c", fpf, cat_term); } else if (is_ft950) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX117%03d%c", fpf, cat_term); } else if (is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX042%03d%c", fpf, cat_term); } else { RETURNFUNC(-RIG_EINVAL); } break; case RIG_LEVEL_NOTCHF: if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } val.i = val.i / 10; if (is_ftdx9000) { if (val.i < 0) { val.i = 0; } } else { if (val.i < 1) { val.i = 1; } } if (is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { if (val.i > 320) { val.i = 320; } } if (is_ft950 || is_ftdx9000) { if (val.i > 300) { val.i = 300; } } else { if (val.i > 400) { val.i = 400; } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP01%03d%c", val.i, cat_term); if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP%03d%c", val.i, cat_term); } else if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_MONITOR_GAIN: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } fpf = (int)((val.f / level_info->step.f) + 0.5f); if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML%03d%c", fpf, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML1%03d%c", fpf, cat_term); } break; case RIG_LEVEL_BAND_SELECT: if (newcat_valid_command(rig, "BS")) { int band = band2rig((hamlib_band_t)val.i); if (band < 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", band, cat_term); priv->band_index = band; } break; case RIG_LEVEL_NB: if (!newcat_valid_command(rig, "NL")) { RETURNFUNC(-RIG_ENAVAIL); } // Do not scale the value, level maximum value is set to 10 fpf = val.f; if (fpf < 0) { fpf = 0; } if (fpf > 10) { fpf = 10; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NL00%02d%c", fpf, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710 && !is_ftdx101mp) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_USB_AF: if (is_ftdx101d || is_ftdx101mp) { rmode_t curmode = STATE(rig)->current_vfo == RIG_VFO_A ? cachep->modeMainA : cachep->modeMainB; float valf = val.f / level_info->step.f; switch (curmode) { case RIG_MODE_USB: case RIG_MODE_LSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010113%03.0f%c", valf, cat_term); break; case RIG_MODE_AM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010214%03.0f%c", valf, cat_term); break; case RIG_MODE_FM: case RIG_MODE_FMN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010313%03.0f%c", valf, cat_term); break; case RIG_MODE_PKTFM: // is this the right place for this? case RIG_MODE_PKTFMN: // is this the right place for this? case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010415%03.0f%c", valf, cat_term); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown how to set USB_AF for mode=%s\n", __func__, rig_strrmode(curmode)); RETURNFUNC(-RIG_EINVAL); } } break; default: RETURNFUNC(-RIG_EINVAL); } err = newcat_set_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; RETURNFUNC(err); } int newcat_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct rig_state *state = STATE(rig); struct rig_cache *cachep = CACHE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *retlvl; int retlvl_len; char main_sub_vfo = '0'; int i; gran_t *level_info; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } level_info = &rig->caps->level_gran[rig_setting2idx(level)]; switch (level) { case RIG_LEVEL_RFPOWER: if (!newcat_valid_command(rig, "PC")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PC%c", cat_term); break; case RIG_LEVEL_PREAMP: if (!newcat_valid_command(rig, "PA")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PA0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_AF: if (!newcat_valid_command(rig, "AG")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AG%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_AGC: if (!newcat_valid_command(rig, "GT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "GT%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_IF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "IS")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "IS%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in AM/FM modes if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_AM || mode & RIG_MODE_FM || mode & RIG_MODE_AMN || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_CWPITCH: if (!newcat_valid_command(rig, "KP")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KP%c", cat_term); break; case RIG_LEVEL_KEYSPD: if (!newcat_valid_command(rig, "KS")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KS%c", cat_term); break; case RIG_LEVEL_MICGAIN: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "MG")) { RETURNFUNC(-RIG_ENAVAIL); } rmode_t exclude = RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_RTTY | RIG_MODE_RTTYR; if ((STATE(rig)->tx_vfo == RIG_VFO_A && (cachep->modeMainA & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_B && (cachep->modeMainB & exclude)) || (STATE(rig)->tx_vfo == RIG_VFO_C && (cachep->modeMainC & exclude))) { rig_debug(RIG_DEBUG_VERBOSE, "%s: rig cannot read MG in CW/RTTY modes\n", __func__); RETURNFUNC(RIG_OK); } if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { newcat_get_mode(rig, vfo, &mode, &width); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MG%c", cat_term); // Some Yaesu rigs reject this command in RTTY modes if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_RTTY || mode & RIG_MODE_RTTYR) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_LEVEL_METER: if (!newcat_valid_command(rig, "MS")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MS%c", cat_term); break; case RIG_LEVEL_ATT: if (!newcat_valid_command(rig, "RA")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RA0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_RF: if (!newcat_valid_command(rig, "RG")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RG%c%c", main_sub_vfo, cat_term); break; case RIG_LEVEL_COMP: if (!newcat_valid_command(rig, "PL")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PL%c", cat_term); break; case RIG_LEVEL_NR: if (!newcat_valid_command(rig, "RL")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RL0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_BKINDL: if (!newcat_valid_command(rig, "SD")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SD%c", cat_term); break; case RIG_LEVEL_SQL: if (!newcat_valid_command(rig, "SQ")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SQ%c%c", main_sub_vfo, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_VOXDELAY: /* VOX delay, arg int (tenth of seconds) */ if (!newcat_valid_command(rig, "VD")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VD%c", cat_term); break; case RIG_LEVEL_VOXGAIN: if (!newcat_valid_command(rig, "VG")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VG%c", cat_term); break; case RIG_LEVEL_NB: if (!newcat_valid_command(rig, "NL")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NL0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ftdx10 && !is_ft710 && !is_ftdx101mp) { priv->cmd_str[2] = main_sub_vfo; } break; /* * Read only levels */ case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RAWSTR: if (!newcat_valid_command(rig, "SM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx10) { main_sub_vfo = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SM%c%c", main_sub_vfo, cat_term); break; case RIG_LEVEL_SWR: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM09%c", cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx5000) { // The 3000 has to use the meter read for SWR when the tuner is on // We'll assume the 5000 is the same way for now // Also need to ensure SWR is selected for the meter int tuner; value_t meter; newcat_get_func(rig, RIG_VFO_A, RIG_FUNC_TUNER, &tuner); newcat_get_level(rig, RIG_VFO_A, RIG_LEVEL_METER, &meter); if (tuner && meter.i != RIG_METER_SWR) { RETURNFUNC(-RIG_ENAVAIL); // if meter not SWR can't read SWR } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM%c%c", (tuner && meter.i == RIG_METER_SWR) ? '2' : '6', cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM6%c", cat_term); } break; case RIG_LEVEL_ALC: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM07%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM4%c", cat_term); } break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM08%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM5%c", cat_term); } break; case RIG_LEVEL_COMP_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM06%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM3%c", cat_term); } break; case RIG_LEVEL_VD_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM11%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM8%c", cat_term); } break; case RIG_LEVEL_ID_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM10%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM7%c", cat_term); } break; case RIG_LEVEL_ANTIVOX: if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AV%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX176%c", cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX183%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX147%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1619%c", cat_term); } else if (is_ft950) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX117%c", cat_term); } else if (is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX042%c", cat_term); } else { RETURNFUNC(-RIG_ENAVAIL); } break; case RIG_LEVEL_NOTCHF: if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP01%c", cat_term); if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP%c", cat_term); } else if (rig->caps->targetable_vfo & RIG_TARGETABLE_LEVEL && !is_ft2000 && !is_ftdx10 && !is_ft710) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_LEVEL_MONITOR_GAIN: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML1%c", cat_term); } break; case RIG_LEVEL_TEMP_METER: if (!newcat_valid_command(rig, "RM")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx9000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM14%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RM9%c", cat_term); } break; case RIG_LEVEL_USB_AF_INPUT: if (is_ftdx101d || is_ftdx101mp) { rmode_t curmode = STATE(rig)->current_vfo == RIG_VFO_A ? cachep->modeMainA : cachep->modeMainB; switch (curmode) { case RIG_MODE_LSB: case RIG_MODE_USB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010113%c", cat_term); break; case RIG_MODE_AM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010214%c", cat_term); break; case RIG_MODE_FM: case RIG_MODE_FMN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010313%c", cat_term); break; case RIG_MODE_PKTFM: case RIG_MODE_PKTFMN: case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010415%c", cat_term); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown how to get USB_AF_INPUT for mode=%s\n", __func__, rig_strrmode(curmode)); RETURNFUNC(-RIG_EINVAL); } } else { RETURNFUNC(-RIG_ENIMPL); } break; case RIG_LEVEL_USB_AF: if (is_ftdx101d || is_ftdx101mp) { rmode_t curmode = STATE(rig)->current_vfo == RIG_VFO_A ? cachep->modeMainA : cachep->modeMainB; switch (curmode) { case RIG_MODE_LSB: case RIG_MODE_USB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010109%c", cat_term); break; case RIG_MODE_AM: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010209%c", cat_term); break; case RIG_MODE_FM: case RIG_MODE_FMN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010309%c", cat_term); break; case RIG_MODE_PKTFM: case RIG_MODE_PKTFMN: case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010411%c", cat_term); break; case RIG_MODE_RTTY: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX010511%c", cat_term); break; // we have PSK level too but no means to have this mode yet default: rig_debug(RIG_DEBUG_ERR, "%s: unknown how to get USB_AF for mode=%s\n", __func__, rig_strrmode(curmode)); RETURNFUNC(-RIG_EINVAL); } } else { RETURNFUNC(-RIG_ENIMPL); } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown level=%08llx\n", __func__, (long long unsigned int)level); RETURNFUNC(-RIG_EINVAL); } err = newcat_get_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retlvl = priv->ret_data + strlen(priv->cmd_str) - 1; retlvl_len = strlen(retlvl); rig_debug(RIG_DEBUG_TRACE, "%s: retlvl='%s'\n", __func__, retlvl); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; switch (level) { case RIG_LEVEL_SWR: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->swr_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_swr_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->swr_cal); } break; case RIG_LEVEL_ALC: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->alc_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_alc_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->alc_cal); } break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: rig_debug(RIG_DEBUG_VERBOSE, "%s: RFPOWER_METER retlvl=%s\n", __func__, retlvl); if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate rig_debug(RIG_DEBUG_VERBOSE, "%s: retlvl of %s getting truncated\n", __func__, retlvl); retlvl[3] = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s: retlvl truncated to %s\n", __func__, retlvl); } if (rig->caps->rfpower_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_rfpower_meter_cal) / (level == RIG_LEVEL_RFPOWER_METER_WATTS ? 1.0 : 100.0); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->rfpower_meter_cal) / (level == RIG_LEVEL_RFPOWER_METER_WATTS ? 1.0 : 100.0); if (priv->rig_id == NC_RIGID_FT2000) { // we reuse the FT2000D table for the FT2000 so need to divide by 2 // hopefully this works well otherwise we need a separate table val->f /= 2; } } rig_debug(RIG_DEBUG_VERBOSE, "%s: RFPOWER_METER=%s, converted to %f\n", __func__, retlvl, val->f); if (level == RIG_LEVEL_RFPOWER_METER && val->f > 1.0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: val->f(%f) clipped at 1.0\n", __func__, val->f); val->f = 1.0; } break; case RIG_LEVEL_COMP_METER: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->comp_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_comp_meter_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->comp_meter_cal); } break; case RIG_LEVEL_VD_METER: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->vd_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_vd_meter_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->vd_meter_cal); } break; case RIG_LEVEL_ID_METER: if (retlvl_len > 3) { // Some rigs like FTDX101 have 6-byte return so we just truncate retlvl[3] = 0; } if (rig->caps->id_meter_cal.size == 0) { val->f = rig_raw2val_float(atoi(retlvl), &yaesu_default_id_meter_cal); } else { val->f = rig_raw2val_float(atoi(retlvl), &rig->caps->id_meter_cal); } break; case RIG_LEVEL_AF: case RIG_LEVEL_RF: case RIG_LEVEL_NR: case RIG_LEVEL_SQL: case RIG_LEVEL_COMP: case RIG_LEVEL_ANTIVOX: case RIG_LEVEL_MICGAIN: case RIG_LEVEL_VOXGAIN: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_MONITOR_GAIN: val->f = (float)atoi(retlvl) * level_info->step.f; break; case RIG_LEVEL_BKINDL: { int raw_value = atoi(retlvl); int millis; value_t keyspd; if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { switch (raw_value) { case 0: millis = 30; break; case 1: millis = 50; break; case 2: millis = 100; break; case 3: millis = 150; break; case 4: millis = 200; break; case 5: millis = 250; break; case 6: millis = 300; break; default: millis = (raw_value - 6) * 100 + 300; } } else { // The rest of Yaesu rigs indicate break-in delay directly as milliseconds millis = raw_value; } // Convert milliseconds to 10/ths of dots using the current key speed err = newcat_get_level(rig, vfo, RIG_LEVEL_KEYSPD, &keyspd); if (err != RIG_OK) { RETURNFUNC(err); } val->i = millis_to_dot10ths(millis, keyspd.i); break; } case RIG_LEVEL_STRENGTH: if (rig->caps->str_cal.size > 0) { val->i = round(rig_raw2val(atoi(retlvl), &rig->caps->str_cal)); break; } if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ft891 || is_ft991 || is_ftdx101d || is_ftdx101mp || is_ftdx10) { val->i = round(rig_raw2val(atoi(retlvl), &yaesu_default_str_cal)); } else { // Some Yaesu rigs return straight S-meter answers // Return dbS9 -- does >S9 mean 10dB increments? If not, add to rig driver if (val->i > 0) { val->i = (atoi(retlvl) - 9) * 10; } else { val->i = (atoi(retlvl) - 9) * 6; } } break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_KEYSPD: if (rig->caps->rig_model == RIG_MODEL_TS570D || rig->caps->rig_model == RIG_MODEL_TS570S) { // TS570 uses 010-~060 scale according to manual val->i = atoi(retlvl) / 2 + 10; } else { val->i = atoi(retlvl); } break; case RIG_LEVEL_IF: // IS00+0400 rig_debug(RIG_DEBUG_TRACE, "%s: ret_data=%s(%d), retlvl=%s\n", __func__, priv->ret_data, (int)strlen(priv->ret_data), retlvl); if (strlen(priv->ret_data) == 9) { int n = sscanf(priv->ret_data, "IS%*c0%d\n", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse level from %s\n", __func__, priv->ret_data); } } else { val->i = atoi(retlvl); } break; case RIG_LEVEL_VOXDELAY: val->i = atoi(retlvl); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { switch (val->i) { case 0: val->i = 0; break; // 30ms=0 we only do tenths case 1: val->i = 0; break; // 50ms=0 case 2: val->i = 1; break; // 100ms=1 case 3: val->i = 1; break; // 150ms=1 case 4: val->i = 2; break; // 200ms=2 case 5: val->i = 2; break; // 250ms=2 default: val->i = (val->i - 6) + 3; break; } } else { /* VOX delay, arg int (tenth of seconds), rig in ms */ val->i /= 10; // Convert from ms to tenths } break; case RIG_LEVEL_PREAMP: { int preamp; if (retlvl[0] < '0' || retlvl[0] > '9') { RETURNFUNC(-RIG_EPROTO); } preamp = retlvl[0] - '0'; val->i = 0; if (preamp > 0) { for (i = 0; state->preamp[i] != RIG_DBLST_END; i++) { if (i == preamp - 1) { val->i = state->preamp[i]; break; } } } break; } case RIG_LEVEL_ATT: { int att; if (retlvl[0] < '0' || retlvl[0] > '9') { RETURNFUNC(-RIG_EPROTO); } att = retlvl[0] - '0'; val->i = 0; if (att > 0) { for (i = 0; state->attenuator[i] != RIG_DBLST_END; i++) { if (i == att - 1) { val->i = state->attenuator[i]; break; } } } break; } case RIG_LEVEL_AGC: switch (retlvl[0]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_FAST; break; case '2': val->i = RIG_AGC_MEDIUM; break; case '3': val->i = RIG_AGC_SLOW; break; case '4': case '5': case '6': val->i = RIG_AGC_AUTO; break; default: RETURNFUNC(-RIG_EPROTO); } break; case RIG_LEVEL_CWPITCH: // Most Yaesu rigs seem to use range of 0-75 to represent pitch of 300..1050 Hz in 10 Hz steps val->i = (atoi(retlvl) * level_info->step.i) + level_info->min.i; break; case RIG_LEVEL_METER: switch (retlvl[0]) { case '0': val->i = RIG_METER_COMP; break; case '1': val->i = RIG_METER_ALC; break; case '2': val->i = RIG_METER_PO; break; case '3': val->i = RIG_METER_SWR; break; case '4': val->i = RIG_METER_IC; break; /* ID CURRENT */ case '5': val->i = RIG_METER_VDD; break; /* Final Amp Voltage */ default: RETURNFUNC(-RIG_EPROTO); } break; case RIG_LEVEL_NOTCHF: val->i = atoi(retlvl) * 10; break; case RIG_LEVEL_NB: // Do not scale the value, level maximum value is set to 10 val->f = (float) atoi(retlvl); break; case RIG_LEVEL_TEMP_METER: // return value in centigrade -- first 3 digits i = 0; sscanf(retlvl, "%3d", &i); val->f = i / 255. * 100.; rig_debug(RIG_DEBUG_VERBOSE, "%s: retlvl=%s, i=%d, val=%g\n", __func__, retlvl, i, val->f); break; case RIG_LEVEL_USB_AF: case RIG_LEVEL_USB_AF_INPUT: i = 0; sscanf(retlvl, "%3d", &i); val->f = i * level_info->step.f; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char main_sub_vfo = '0'; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (func) { case RIG_FUNC_ANF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "BC")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BC0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC && !is_ft2000 && !is_ftdx10) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_MN: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP00%03d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC && !is_ft2000 && !is_ftdx10) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_FBKIN: if (!newcat_valid_command(rig, "BI")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BI%d%c", status ? 1 : 0, cat_term); break; case RIG_FUNC_TONE: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 2 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_TSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_CSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%d%c", status ? 3 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_LOCK: if (!newcat_valid_command(rig, "LK")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { // These rigs can lock Main/Sub VFO dials individually SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 7 : 4, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "LK%d%c", status ? 1 : 0, cat_term); } break; case RIG_FUNC_MON: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML0%03d%c", status ? 1 : 0, cat_term); break; case RIG_FUNC_NB: if (!newcat_valid_command(rig, "NB")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NB0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_NB2: if (!newcat_valid_command(rig, "NB")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NB0%d%c", status ? 2 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_NR: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "NR")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NR0%d%c", status ? 1 : 0, cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_COMP: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "PR")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } if (is_ft891 || is_ft991 || is_ft710 || is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx101d || is_ftdx101mp) { // There seems to be an error in the manuals for some of these rigs stating that values should be 1 = OFF and 2 = ON, but they are 0 = OFF and 1 = ON instead SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR0%d%c", status ? 1 : 0, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR%d%c", status ? 1 : 0, cat_term); } // Some Yaesu rigs reject this command in AM/FM/RTTY modes if (is_ft991 || is_ft710 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_AM || mode & RIG_MODE_FM || mode & RIG_MODE_AMN || mode & RIG_MODE_FMN || mode & RIG_MODE_RTTY || mode & RIG_MODE_RTTYR) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_VOX: if (!newcat_valid_command(rig, "VX")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VX%d%c", status ? 1 : 0, cat_term); break; case RIG_FUNC_TUNER: if (!newcat_valid_command(rig, "AC")) { RETURNFUNC(-RIG_ENAVAIL); } priv->question_mark_response_means_rejected = 1; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC00%d%c", status == 0 ? 0 : status, cat_term); break; case RIG_FUNC_RIT: if (is_ft710) { RETURNFUNC(newcat_set_clarifier(rig, vfo, status, -1)); } else { if (!newcat_valid_command(rig, "RT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RT%d%c", status ? 1 : 0, cat_term); } break; case RIG_FUNC_XIT: if (is_ft710) { RETURNFUNC(newcat_set_clarifier(rig, vfo, -1, status)); } else { if (!newcat_valid_command(rig, "XT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "XT%d%c", status ? 1 : 0, cat_term); } break; case RIG_FUNC_APF: if (!newcat_valid_command(rig, "CO")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c2%04d%c", main_sub_vfo, status ? 1 : 0, cat_term); } else if (is_ftdx10 || is_ft710 || is_ft991 || is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%04d%c", status ? 1 : 0, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%02d%c", main_sub_vfo, status ? 2 : 0, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%02d%c", status ? 2 : 0, cat_term); } else { RETURNFUNC(-RIG_ENIMPL); } priv->question_mark_response_means_rejected = 1; break; case RIG_FUNC_SYNC: if (!newcat_valid_command(rig, "SY")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SY%d%c", status ? 1 : 0, cat_term); break; default: RETURNFUNC(-RIG_EINVAL); } err = newcat_set_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; RETURNFUNC(err); } int newcat_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; int last_char_index; char *retfunc; char main_sub_vfo = '0'; ENTERFUNC; if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (func) { case RIG_FUNC_ANF: { pbwidth_t width; rmode_t mode = 0; if (!newcat_valid_command(rig, "BC")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { err = newcat_get_mode(rig, vfo, &mode, &width); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: get_mode: %s\n", __func__, rigerror(err)); } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BC0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } // Some Yaesu rigs reject this command in FM mode if (is_ft991 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { if (mode & RIG_MODE_FM || mode & RIG_MODE_FMN) { priv->question_mark_response_means_rejected = 1; } } break; } case RIG_FUNC_MN: if (!newcat_valid_command(rig, "BP")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BP00%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_FBKIN: if (!newcat_valid_command(rig, "BI")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BI%c", cat_term); break; case RIG_FUNC_TONE: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_TSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_CSQL: if (!newcat_valid_command(rig, "CT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CT0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_TONE) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_LOCK: if (!newcat_valid_command(rig, "LK")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "LK%c", cat_term); break; case RIG_FUNC_MON: if (!newcat_valid_command(rig, "ML")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ML0%c", cat_term); break; case RIG_FUNC_NB: case RIG_FUNC_NB2: if (!newcat_valid_command(rig, "NB")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NB0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_NR: if (!newcat_valid_command(rig, "NR")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NR0%c", cat_term); if (rig->caps->targetable_vfo & RIG_TARGETABLE_FUNC) { priv->cmd_str[2] = main_sub_vfo; } break; case RIG_FUNC_COMP: if (!newcat_valid_command(rig, "PR")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ft891 || is_ft991 || is_ft710 || is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR0%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PR%c", cat_term); } break; case RIG_FUNC_VOX: if (!newcat_valid_command(rig, "VX")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VX%c", cat_term); break; case RIG_FUNC_TUNER: if (!newcat_valid_command(rig, "AC")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC%c", cat_term); break; case RIG_FUNC_RIT: if (is_ft710) { RETURNFUNC(newcat_get_clarifier(rig, vfo, status, NULL)); } else { if (!newcat_valid_command(rig, "RT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RT%c", cat_term); } break; case RIG_FUNC_XIT: if (is_ft710) { RETURNFUNC(newcat_get_clarifier(rig, vfo, NULL, status)); } else { if (!newcat_valid_command(rig, "XT")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "XT%c", cat_term); } break; case RIG_FUNC_APF: if (!newcat_valid_command(rig, "CO")) { RETURNFUNC(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c2%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft710 || is_ft991 || is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%c", main_sub_vfo, cat_term); } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%c", cat_term); } else { RETURNFUNC(-RIG_ENIMPL); } break; case RIG_FUNC_SYNC: if (!newcat_valid_command(rig, "SY")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SY%c", cat_term); break; default: RETURNFUNC(-RIG_EINVAL); } err = newcat_get_cmd(rig); // Clear flag after executing command priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ retfunc = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; last_char_index = strlen(retfunc) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: retfunc='%s'\n", __func__, retfunc); switch (func) { case RIG_FUNC_MN: *status = (retfunc[2] == '0') ? 0 : 1; break; case RIG_FUNC_COMP: *status = (retfunc[0] == '0') ? 0 : 1; break; case RIG_FUNC_MON: // The number of digits varies by rig, but the last digit indicates the status always *status = (retfunc[last_char_index] == '0') ? 0 : 1; break; case RIG_FUNC_LOCK: if (is_ftdx1200 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx101d || is_ftdx101mp) { // These rigs can lock Main/Sub VFO dials individually *status = (retfunc[0] == '0' || retfunc[0] == '4') ? 0 : 1; } else { *status = (retfunc[0] == '0') ? 0 : 1; } break; case RIG_FUNC_ANF: case RIG_FUNC_FBKIN: case RIG_FUNC_NR: case RIG_FUNC_VOX: *status = (retfunc[0] == '0') ? 0 : 1; break; case RIG_FUNC_NB: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_NB2: *status = (retfunc[0] == '2') ? 1 : 0; break; case RIG_FUNC_TONE: *status = (retfunc[0] == '2') ? 1 : 0; break; case RIG_FUNC_TSQL: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_CSQL: *status = (retfunc[0] == '3') ? 1 : 0; break; case RIG_FUNC_TUNER: *status = (retfunc[2] == '1') ? 1 : 0; break; case RIG_FUNC_RIT: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_XIT: *status = (retfunc[0] == '1') ? 1 : 0; break; case RIG_FUNC_APF: if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { *status = (retfunc[last_char_index] == '1') ? 1 : 0; } else if (is_ftdx5000) { *status = (retfunc[last_char_index] == '2') ? 1 : 0; } else if (is_ftdx3000 || is_ftdx3000dm || is_ftdx1200 || is_ft2000) { *status = (retfunc[last_char_index] == '2') ? 1 : 0; } else { RETURNFUNC(-RIG_ENIMPL); } break; case RIG_FUNC_SYNC: *status = (retfunc[0] == '1') ? 1 : 0; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_parm(RIG *rig, setting_t parm, value_t val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; int rigband = 0; int band = 0; ENTERFUNC; switch (parm) { case RIG_PARM_BANDSELECT: if (!newcat_valid_command(rig, "BS")) { RETURNFUNC(-RIG_ENAVAIL); } // we should have a string for the desired band rigband = rig_get_band_rig(rig, 0.0, val.s); //rigband = band2rig(rigband); switch (rigband) { case RIG_BAND_160M: band = 0; break; case RIG_BAND_80M: band = 1; break; case RIG_BAND_40M: band = 3; break; case RIG_BAND_30M: band = 4; break; case RIG_BAND_20M: band = 5; break; case RIG_BAND_17M: band = 6; break; case RIG_BAND_15M: band = 7; break; case RIG_BAND_12M: band = 8; break; case RIG_BAND_10M: band = 9; break; case RIG_BAND_6M: band = 10; break; case RIG_BAND_144MHZ: band = 15; break; case RIG_BAND_430MHZ: band = 16; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown band %s=%d\n", __func__, val.s, rigband); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BS%02d%c", band, cat_term); retval = newcat_set_cmd(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } priv->band_index = band; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_ENIMPL); } int newcat_get_parm(RIG *rig, setting_t parm, value_t *val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; switch (parm) { case RIG_PARM_BANDSELECT: if (!newcat_valid_command(rig, "BS")) { RETURNFUNC(-RIG_ENAVAIL); } freq_t freq; retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval != RIG_OK) { RETURNFUNC(retval); } hamlib_band_t band = rig_get_band(rig, freq, 0); val->cs = rig_get_band_str(rig, band, 0); priv->band_index = band; RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_ENAVAIL); } static int newcat_set_maxpower(RIG *rig, vfo_t vfo, hamlib_token_t token, float val) { return -RIG_ENIMPL; } static int newcat_get_maxpower(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; int code = 0; int offset = 0; val->i = 0; if (newcat_is_rig(rig, RIG_MODEL_FT991)) { offset = 5; switch (token) { case TOK_MAXPOWER_HF: code = 137; break; case TOK_MAXPOWER_6M: code = 138; break; case TOK_MAXPOWER_VHF: code = 139; break; case TOK_MAXPOWER_UHF: code = 140; break; default: return -RIG_EINVAL; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX%03d%c", code, cat_term); } else if (newcat_is_rig(rig, RIG_MODEL_FTDX101MP) || newcat_is_rig(rig, RIG_MODEL_FTDX101D)) { offset = 6; switch (token) { case TOK_MAXPOWER_HF: code = 1; break; case TOK_MAXPOWER_6M: code = 2; break; case TOK_MAXPOWER_4M: code = 3; break; case TOK_MAXPOWER_AM: code = 4; break; default: return -RIG_EINVAL; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX0304%02d%c", code, cat_term); } retval = newcat_get_cmd(rig); if (retval == RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: offset=%d, scanning '%s'\n", __func__, offset, &priv->ret_data[offset]); sscanf(&priv->ret_data[offset], "%d", &val->i); } return retval; } int newcat_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; ENTERFUNC; switch (token) { case TOK_ROOFING_FILTER: RETURNFUNC(set_roofing_filter(rig, vfo, val.i)); case TOK_KEYER: if (!newcat_valid_command(rig, "KR")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KR%d%c", val.i ? 1 : 0, cat_term); RETURNFUNC(newcat_set_cmd(rig)); case TOK_APF_FREQ: RETURNFUNC(newcat_set_apf_frequency(rig, vfo, val.f)); case TOK_APF_WIDTH: RETURNFUNC(newcat_set_apf_width(rig, vfo, val.i)); case TOK_CONTOUR: RETURNFUNC(newcat_set_contour(rig, vfo, val.i)); case TOK_CONTOUR_FREQ: RETURNFUNC(newcat_set_contour_frequency(rig, vfo, val.f)); case TOK_CONTOUR_LEVEL: RETURNFUNC(newcat_set_contour_level(rig, vfo, val.f)); case TOK_CONTOUR_WIDTH: RETURNFUNC(newcat_set_contour_width(rig, vfo, val.f)); case TOK_MAXPOWER_HF: case TOK_MAXPOWER_6M: case TOK_MAXPOWER_VHF: case TOK_MAXPOWER_UHF: RETURNFUNC(newcat_set_maxpower(rig, vfo, token, val.f)); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token)); RETURNFUNC(-RIG_EINVAL); } } int newcat_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *result; int retval; int value; ENTERFUNC; switch (token) { case TOK_ROOFING_FILTER: { struct newcat_roofing_filter *roofing_filter; retval = get_roofing_filter(rig, vfo, &roofing_filter); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = roofing_filter->index; break; } case TOK_KEYER: if (!newcat_valid_command(rig, "KR")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KR%c", cat_term); retval = newcat_get_cmd(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } /* skip command */ result = priv->ret_data + strlen(priv->cmd_str) - 1; /* chop term */ priv->ret_data[strlen(priv->ret_data) - 1] = '\0'; val->i = result[0] == '0' ? 0 : 1; break; case TOK_APF_FREQ: retval = newcat_get_apf_frequency(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_APF_WIDTH: retval = newcat_get_apf_width(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = value; break; case TOK_CONTOUR: retval = newcat_get_contour(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = value; break; case TOK_CONTOUR_WIDTH: retval = newcat_get_contour_width(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_CONTOUR_FREQ: retval = newcat_get_contour_frequency(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_CONTOUR_LEVEL: retval = newcat_get_contour_level(rig, vfo, &value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->f = value; break; case TOK_MAXPOWER_HF: case TOK_MAXPOWER_6M: case TOK_MAXPOWER_VHF: case TOK_MAXPOWER_UHF: RETURNFUNC(newcat_get_maxpower(rig, vfo, token, val)); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %s\n", __func__, rig_strlevel(token)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_send_morse(RIG *rig, vfo_t vfo, const char *msg) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int rc; ENTERFUNC; char chan = '1'; if (newcat_is_rig(rig, RIG_MODEL_FT450) && strlen(msg) == 1 && msg[0] > '4') { // 450 manual says 1/2/3 playback needs P1=6/7/8 rig_debug(RIG_DEBUG_ERR, "%s: only messages 1-3 accepted\n", __func__); RETURNFUNC(-RIG_EINVAL); } else { // 5-chan playback 6-A: FT-1200, FT-2000, FT-3000, FTDX-5000, FT-891, FT-9000, FT-950, FT-991, FTDX-101MP/D, FTDX10 // 5-chan but 1-5 playback: FT-710 if (strlen(msg) == 1 && (msg[0] < '1' || msg[0] > '5')) { rig_debug(RIG_DEBUG_ERR, "%s: only messages 1-5 accepted\n", __func__); RETURNFUNC(-RIG_EINVAL); } if (!newcat_is_rig(rig, RIG_MODEL_FT710)) { chan += 5; // 6,7,8 needed for playback } } char *msg2 = strdup(msg); // copy so we can modify it if needed if (strlen(msg2) == 1) { switch (*msg2) { // do all Yaeus rigs play back with chan+5? case '1': msg2[0] = '6'; break; case '2': msg2[0] = '7'; break; case '3': msg2[0] = '8'; break; case '4': msg2[0] = '9'; break; case '5': msg2[0] = 'A'; break; case '6': // we'll let these pass case '7': case '8': case '9': case 'A': case 'a': break; default: RETURNFUNC(-RIG_EINVAL); } } else { if (strlen(msg2) > 50) { msg2[51] = 0; // truncate if too long rig_debug(RIG_DEBUG_ERR, "%s: msg length of %d truncated to 50\n", __func__, (int)strlen(msg)); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KM1%s;", msg2); rc = newcat_set_cmd(rig); if (rc != RIG_OK) { free(msg2); RETURNFUNC(-RIG_EINVAL); } chan = '6'; // the channel we use to key msg 1 } free(msg2); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "KY%c%c", chan, cat_term); rc = newcat_set_cmd(rig); RETURNFUNC(rc); } int newcat_set_bank(RIG *rig, vfo_t vfo, int bank) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_mem(RIG *rig, vfo_t vfo, int ch) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err, i; ncboolean restore_vfo; chan_t *chan_list; channel_t valid_chan; channel_cap_t *mem_caps = NULL; ENTERFUNC; if (!newcat_valid_command(rig, "MC")) { RETURNFUNC(-RIG_ENAVAIL); } chan_list = rig->caps->chan_list; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (ch >= chan_list[i].startc && ch <= chan_list[i].endc) { mem_caps = &chan_list[i].mem_caps; break; } } /* Test for valid usable channel, skip if empty */ memset(&valid_chan, 0, sizeof(channel_t)); valid_chan.channel_num = ch; err = newcat_get_channel(rig, vfo, &valid_chan, 1); if (err < 0) { RETURNFUNC(err); } if (valid_chan.freq <= 1.0) { mem_caps = NULL; } rig_debug(RIG_DEBUG_TRACE, "%s: valChan Freq = %f\n", __func__, valid_chan.freq); /* Out of Range, or empty */ if (!mem_caps) { RETURNFUNC(-RIG_EINVAL); } /* set to usable vfo if needed */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } /* Restore to VFO mode or leave in Memory Mode */ switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: /* Jump back from memory channel */ restore_vfo = TRUE; break; case RIG_VFO_MEM: /* Jump from channel to channel in memory mode */ restore_vfo = FALSE; break; case RIG_VFO_B: case RIG_VFO_SUB: default: /* Only works with VFO A */ RETURNFUNC(-RIG_ENTARGET); } /* Set Memory Channel Number ************** */ rig_debug(RIG_DEBUG_TRACE, "channel_num = %d, vfo = %s\n", ch, rig_strvfo(vfo)); SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MC%03d%c", ch, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } /* Restore VFO even if setting to blank memory channel */ if (restore_vfo) { err = newcat_vfomem_toggle(rig); if (err != RIG_OK) { RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } int newcat_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; ENTERFUNC; if (!newcat_valid_command(rig, "MC")) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MC%c", cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get Memory Channel Number */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } *ch = atoi(priv->ret_data + 2); RETURNFUNC(RIG_OK); } int newcat_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char main_sub_vfo = '0'; ENTERFUNC; /* Set Main or SUB vfo */ err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } switch (op) { case RIG_OP_TUNE: if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC003%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AC002%c", cat_term); } break; case RIG_OP_CPY: if (newcat_is_rig(rig, RIG_MODEL_FT450)) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "VV%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AB%c", cat_term); } break; case RIG_OP_XCHG: case RIG_OP_TOGGLE: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SV%c", cat_term); break; case RIG_OP_UP: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "UP%c", cat_term); break; case RIG_OP_DOWN: SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DN%c", cat_term); break; case RIG_OP_BAND_UP: if (main_sub_vfo == 1) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BU1%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BU0%c", cat_term); } break; case RIG_OP_BAND_DOWN: if (main_sub_vfo == 1) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BD1%c", cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "BD0%c", cat_term); } break; case RIG_OP_FROM_VFO: /* VFOA ! */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AM%c", cat_term); break; case RIG_OP_TO_VFO: /* VFOA ! */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MA%c", cat_term); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(newcat_set_cmd(rig)); } int newcat_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retval; ENTERFUNC; if (scan != RIG_SCAN_VFO) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SC%d%c", scan == RIG_SCAN_STOP ? 0 : ch, cat_term); if (RIG_OK != (retval = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, retval); RETURNFUNC(retval); } RETURNFUNC(retval); } int newcat_set_trn(RIG *rig, int trn) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; ENTERFUNC; if (!newcat_valid_command(rig, "AI")) { RETURNFUNC(-RIG_ENAVAIL); } if (trn == RIG_TRN_OFF) { c = '0'; } else { c = '1'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "AI%c%c", c, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_trn(RIG *rig, int *trn) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "AI"; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); /* Get Auto Information */ if (RIG_OK != newcat_get_cmd(rig)) { // if we failed to get AI we turn it off and try again SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s0%c", command, cat_term); hl_usleep(500 * 1000); // is 500ms enough for the rig to stop sending info? newcat_set_cmd(rig); // don't care about any errors here SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); err = newcat_get_cmd(rig); RETURNFUNC(err); } c = priv->ret_data[2]; if (c == '0') { *trn = RIG_TRN_OFF; } else { *trn = RIG_TRN_RIG; } RETURNFUNC(RIG_OK); } int newcat_decode_event(RIG *rig) { ENTERFUNC; RETURNFUNC(-RIG_ENAVAIL); } int newcat_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { struct rig_state *state = STATE(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)state->priv; int err, i; int rxit; char c_rit, c_xit, c_mode, c_vfo, c_tone, c_rptr_shift; tone_t tone; ncboolean restore_vfo; chan_t *chan_list; channel_cap_t *mem_caps = NULL; ENTERFUNC; if (!newcat_valid_command(rig, "MW")) { RETURNFUNC(-RIG_ENAVAIL); } chan_list = rig->caps->chan_list; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (chan->channel_num >= chan_list[i].startc && chan->channel_num <= chan_list[i].endc && // writable memory types... NOT 60-METERS or READ-ONLY channels (chan_list[i].type == RIG_MTYPE_MEM || chan_list[i].type == RIG_MTYPE_EDGE)) { mem_caps = &chan_list[i].mem_caps; break; } } /* Out of Range */ if (!mem_caps) { RETURNFUNC(-RIG_ENAVAIL); } /* Set Restore to VFO or leave in memory mode */ switch (state->current_vfo) { case RIG_VFO_A: case RIG_VFO_B: /* Jump back from memory channel */ restore_vfo = TRUE; break; case RIG_VFO_MEM: /* Jump from channel to channel in memory mode */ restore_vfo = FALSE; break; case RIG_VFO_SUB: default: /* Only works with VFO Main */ RETURNFUNC(-RIG_ENTARGET); } /* Write Memory Channel ************************* */ /* Clarifier TX, RX */ if (chan->rit) { rxit = chan->rit; c_rit = '1'; c_xit = '0'; } else if (chan->xit) { rxit = chan->xit; c_rit = '0'; c_xit = '1'; } else { rxit = 0; c_rit = '0'; c_xit = '0'; } /* MODE */ c_mode = newcat_modechar(chan->mode); /* VFO Fixed */ c_vfo = '0'; /* CTCSS Tone / Sql */ if (chan->ctcss_tone) { c_tone = '2'; tone = chan->ctcss_tone; } else if (chan->ctcss_sql) { c_tone = '1'; tone = chan->ctcss_sql; } else { c_tone = '0'; tone = 0; } for (i = 0; rig->caps->ctcss_list[i] != 0; i++) if (tone == rig->caps->ctcss_list[i]) { tone = i; if (tone > 49) { tone = 0; } break; } /* Repeater Shift */ switch (chan->rptr_shift) { case RIG_RPT_SHIFT_NONE: c_rptr_shift = '0'; break; case RIG_RPT_SHIFT_PLUS: c_rptr_shift = '1'; break; case RIG_RPT_SHIFT_MINUS: c_rptr_shift = '2'; break; default: c_rptr_shift = '0'; } if (priv->width_frequency == 9) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MW%03d%09d%+.4d%c%c%c%c%c%02u%c%c", chan->channel_num, (int)chan->freq, rxit, c_rit, c_xit, c_mode, c_vfo, c_tone, tone, c_rptr_shift, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MW%03d%08d%+.4d%c%c%c%c%c%02u%c%c", chan->channel_num, (int)chan->freq, rxit, c_rit, c_xit, c_mode, c_vfo, c_tone, tone, c_rptr_shift, cat_term); } rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Set Memory Channel */ priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); priv->question_mark_response_means_rejected = 0; if (err != RIG_OK) { RETURNFUNC(err); } /* Restore VFO ********************************** */ if (restore_vfo) { err = newcat_vfomem_toggle(rig); RETURNFUNC(err); } RETURNFUNC(RIG_OK); } int newcat_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char *retval; char c, c2; int err, i; chan_t *chan_list; channel_cap_t *mem_caps = NULL; ENTERFUNC; if (!newcat_valid_command(rig, "MR")) { RETURNFUNC(-RIG_ENAVAIL); } chan_list = rig->caps->chan_list; for (i = 0; i < HAMLIB_CHANLSTSIZ && !RIG_IS_CHAN_END(chan_list[i]); i++) { if (chan->channel_num >= chan_list[i].startc && chan->channel_num <= chan_list[i].endc) { mem_caps = &chan_list[i].mem_caps; break; } } /* Out of Range */ if (!mem_caps) { RETURNFUNC(-RIG_ENAVAIL); } rig_debug(RIG_DEBUG_TRACE, "sizeof(channel_t) = %d\n", (int)sizeof(channel_t)); rig_debug(RIG_DEBUG_TRACE, "sizeof(priv->cmd_str) = %d\n", (int)sizeof(priv->cmd_str)); if (is_ftdx101d || is_ftdx101mp || is_ft991 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MT%03d%c", chan->channel_num, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "MR%03d%c", chan->channel_num, cat_term); } rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get Memory Channel */ priv->question_mark_response_means_rejected = 1; err = newcat_get_cmd(rig); priv->question_mark_response_means_rejected = 0; if (RIG_OK != err) { if (-RIG_ERJCTED == err) { /* Invalid channel, has not been set up, make sure freq is 0 to indicate empty channel */ chan->freq = 0.; RETURNFUNC(RIG_OK); } RETURNFUNC(err); } int offset = 0; if (priv->width_frequency == 9) { offset = 1; } /* ret_data string to channel_t struct :: this will destroy ret_data */ /* rptr_shift P10 ************************ */ retval = priv->ret_data + 25 + offset; switch (*retval) { case '0': chan->rptr_shift = RIG_RPT_SHIFT_NONE; break; case '1': chan->rptr_shift = RIG_RPT_SHIFT_PLUS; break; case '2': chan->rptr_shift = RIG_RPT_SHIFT_MINUS; break; default: chan->rptr_shift = RIG_RPT_SHIFT_NONE; } *retval = '\0'; /* CTCSS Encoding P8 ********************* */ retval = priv->ret_data + 22 + offset; c = *retval; /* CTCSS Tone P9 ************************* */ chan->ctcss_tone = 0; chan->ctcss_sql = 0; retval = priv->ret_data + 23 + offset; i = atoi(retval); if (c == '1') { chan->ctcss_sql = rig->caps->ctcss_list[i]; } else if (c == '2') { chan->ctcss_tone = rig->caps->ctcss_list[i]; } /* vfo, mem, P7 ************************** */ retval = priv->ret_data + 21 + offset; if (*retval == '1') { chan->vfo = RIG_VFO_MEM; } else { chan->vfo = RIG_VFO_CURR; } /* MODE P6 ******************************* */ chan->width = 0; retval = priv->ret_data + 20 + offset; chan->mode = newcat_rmode(*retval); if (chan->mode == RIG_MODE_NONE) { rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%c\n", __func__, *retval); chan->mode = RIG_MODE_LSB; } /* Clarifier TX P5 *********************** */ retval = priv->ret_data + 19 + offset; c2 = *retval; /* Clarifier RX P4 *********************** */ retval = priv->ret_data + 18 + offset; c = *retval; *retval = '\0'; /* Clarifier Offset P3 ******************* */ chan->rit = 0; chan->xit = 0; retval = priv->ret_data + 13 + offset; if (c == '1') { chan->rit = atoi(retval); } else if (c2 == '1') { chan->xit = atoi(retval); } *retval = '\0'; /* Frequency P2 ************************** */ retval = priv->ret_data + 5; chan->freq = atof(retval); chan->tag[0] = '?'; // assume nothing if (priv->ret_data[28] != ';') // must have TAG data? { // get the TAG data sscanf(&priv->ret_data[28], "%31s", chan->tag); char *p = strchr(chan->tag, ';'); if (p) { *p = 0; } } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); RETURNFUNC(-RIG_ENIMPL); } RETURNFUNC(RIG_OK); } const char *newcat_get_info(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; static char idbuf[129]; /* extra large static string array */ /* Build the command string */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "ID;"); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Get Identification Channel */ if (RIG_OK != newcat_get_cmd(rig)) { return (NULL); } priv->ret_data[6] = '\0'; SNPRINTF(idbuf, sizeof(idbuf), "%s", priv->ret_data); return (idbuf); } /* * newcat_valid_command * * Determine whether or not the command is valid for the specified * rig. This function should be called before sending the command * to the rig to make it easier to differentiate invalid and illegal * commands (for a rig). */ ncboolean newcat_valid_command(RIG *rig, char const *const command) { struct rig_caps *caps; int search_high; int search_low; rig_debug(RIG_DEBUG_TRACE, "%s %s\n", __func__, command); caps = rig->caps; if (!caps) { rig_debug(RIG_DEBUG_ERR, "%s: Rig capabilities not valid\n", __func__); RETURNFUNC2(FALSE); } if (!is_ft450 && !is_ft950 && !is_ft891 && !is_ft991 && !is_ft2000 && !is_ftdx5000 && !is_ftdx9000 && !is_ftdx1200 && !is_ftdx3000 && !is_ftdx101d && !is_ftdx101mp && !is_ftdx10 && !is_ft710) { rig_debug(RIG_DEBUG_ERR, "%s: '%s' is unknown\n", __func__, caps->model_name); RETURNFUNC2(FALSE); } /* * Make sure the command is known, and then check to make sure * is it valid for the rig. */ search_low = 0; search_high = valid_commands_count; while (search_low <= search_high) { int search_test; int search_index; search_index = (search_low + search_high) / 2; search_test = strcmp(valid_commands[search_index].command, command); if (search_test > 0) { search_high = search_index - 1; } else if (search_test < 0) { search_low = search_index + 1; } else { /* * The command is valid. Now make sure it is supported by the rig. */ if (is_ft450 && valid_commands[search_index].ft450) { RETURNFUNC2(TRUE); } else if (is_ft891 && valid_commands[search_index].ft891) { RETURNFUNC2(TRUE); } else if (is_ft950 && valid_commands[search_index].ft950) { RETURNFUNC2(TRUE); } else if (is_ft991 && valid_commands[search_index].ft991) { RETURNFUNC2(TRUE); } else if (is_ft2000 && valid_commands[search_index].ft2000) { RETURNFUNC2(TRUE); } else if (is_ftdx5000 && valid_commands[search_index].ft5000) { RETURNFUNC2(TRUE); } else if (is_ftdx9000 && valid_commands[search_index].ft9000) { RETURNFUNC2(TRUE); } else if (is_ftdx1200 && valid_commands[search_index].ft1200) { RETURNFUNC2(TRUE); } else if (is_ftdx3000 && valid_commands[search_index].ft3000) { RETURNFUNC2(TRUE); } else if (is_ftdx3000dm && valid_commands[search_index].ft3000) { RETURNFUNC2(TRUE); } else if (is_ftdx101d && valid_commands[search_index].ft101d) { RETURNFUNC2(TRUE); } else if (is_ftdx101mp && valid_commands[search_index].ft101mp) { RETURNFUNC2(TRUE); } else if (is_ftdx10 && valid_commands[search_index].ftdx10) { RETURNFUNC2(TRUE); } else if (is_ft710 && valid_commands[search_index].ft710) { RETURNFUNC2(TRUE); } else { rig_debug(RIG_DEBUG_TRACE, "%s: '%s' command '%s' not supported\n", __func__, caps->model_name, command); RETURNFUNC2(FALSE); } } } rig_debug(RIG_DEBUG_TRACE, "%s: '%s' command '%s' not valid\n", __func__, caps->model_name, command); RETURNFUNC2(FALSE); } ncboolean newcat_is_rig(RIG *rig, rig_model_t model) { ncboolean is_rig; //a bit too verbose so disable this unless needed //rig_debug(RIG_DEBUG_TRACE, "%s(%d):%s called\n", __FILE__, __LINE__, __func__); is_rig = (model == rig->caps->rig_model) ? TRUE : FALSE; return (is_rig); // RETURN is too verbose here } int newcat_set_tx_vfo(RIG *rig, vfo_t tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char *command = "FT"; int result; char p1; ENTERFUNC; if (!newcat_valid_command(rig, "FT")) { RETURNFUNC(-RIG_ENAVAIL); } result = newcat_set_vfo_from_alias(rig, &tx_vfo); if (result < 0) { RETURNFUNC(result); } switch (tx_vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: p1 = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: p1 = '1'; break; case RIG_VFO_MEM: /* VFO A */ if (priv->current_mem == NC_MEM_CHANNEL_NONE) { RETURNFUNC(RIG_OK); } else /* Memory Channel mode */ { p1 = '0'; } break; default: RETURNFUNC(-RIG_EINVAL); } // NOTE: FT-450 only has toggle command so not sure how to definitively set the TX VFO (VS; doesn't seem to help either) if (is_ft950 || is_ft2000 || is_ftdx3000 || is_ftdx3000dm || is_ftdx5000 || is_ftdx1200 || is_ft991 || is_ftdx10 || is_ftdx101d || is_ftdx101mp) { // These rigs use numbers 2 and 3 to denote A/B or Main/Sub VFOs - 0 and 1 are for toggling TX function p1 = p1 + 2; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, p1, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s, vfo=%s\n", priv->cmd_str, rig_strvfo(tx_vfo)); result = newcat_set_cmd(rig); if (result != RIG_OK) { RETURNFUNC(result); } STATE(rig)->tx_vfo = tx_vfo; RETURNFUNC(result); } int newcat_get_tx_vfo(RIG *rig, vfo_t *tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char const *command = "FT"; vfo_t vfo_mode; int result; char c; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); if (RIG_OK != (result = newcat_get_cmd(rig))) { RETURNFUNC(result); } c = priv->ret_data[2]; switch (c) { case '0': if (STATE(rig)->vfo_list & RIG_VFO_MAIN) { *tx_vfo = RIG_VFO_MAIN; } else { *tx_vfo = RIG_VFO_A; } break; case '1' : if (STATE(rig)->vfo_list & RIG_VFO_SUB) { *tx_vfo = RIG_VFO_SUB; } else { *tx_vfo = RIG_VFO_B; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown tx_vfo=%c from index 2 of %s\n", __func__, c, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } /* Check to see if RIG is in MEM mode */ result = newcat_get_vfo_mode(rig, RIG_VFO_A, &vfo_mode); if (result != RIG_OK) { RETURNFUNC(result); } if (vfo_mode == RIG_VFO_MEM && *tx_vfo == RIG_VFO_A) { *tx_vfo = RIG_VFO_MEM; } rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = %s\n", __func__, rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } static int newcat_set_split(RIG *rig, split_t split, vfo_t *rx_vfo, vfo_t *tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char *command = "ST"; char p1; int result; ENTERFUNC; if (!newcat_valid_command(rig, "ST") || is_ft450 || priv->split_st_command_missing) { RETURNFUNC(-RIG_ENAVAIL); } result = newcat_set_vfo_from_alias(rig, tx_vfo); if (result < 0) { RETURNFUNC(result); } switch (split) { case RIG_SPLIT_OFF: p1 = '0'; break; case RIG_SPLIT_ON: p1 = '1'; break; default: RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, p1, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s, vfo=%s\n", priv->cmd_str, rig_strvfo(*tx_vfo)); result = newcat_set_cmd(rig); if (result != RIG_OK) { priv->split_st_command_missing = 1; RETURNFUNC(result); } switch (split) { case RIG_SPLIT_OFF: *rx_vfo = STATE(rig)->current_vfo; *tx_vfo = STATE(rig)->current_vfo; break; case RIG_SPLIT_ON: // These rigs have fixed RX and TX VFOs when using the ST split command if (is_ftdx101d || is_ftdx101mp) { *rx_vfo = RIG_VFO_MAIN; *tx_vfo = RIG_VFO_SUB; } else if (is_ftdx10) { *rx_vfo = RIG_VFO_A; *tx_vfo = RIG_VFO_B; } else { *rx_vfo = STATE(rig)->current_vfo; result = newcat_get_tx_vfo(rig, tx_vfo); if (result != RIG_OK) { RETURNFUNC(result); } } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(result); } static int newcat_get_split(RIG *rig, split_t *split, vfo_t *tx_vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *) STATE(rig)->priv; char const *command = "ST"; int result; char c; ENTERFUNC; if (!newcat_valid_command(rig, "ST") || is_ft450 || priv->split_st_command_missing) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); result = newcat_get_cmd(rig); if (result != RIG_OK) { priv->split_st_command_missing = 1; RETURNFUNC(result); } c = priv->ret_data[2]; switch (c) { case '0': *split = RIG_SPLIT_OFF; result = newcat_get_tx_vfo(rig, tx_vfo); if (result != RIG_OK) { RETURNFUNC(result); } break; case '1' : *split = RIG_SPLIT_ON; // These rigs have fixed RX and TX VFOs when using the ST split command if (is_ftdx101d || is_ftdx101mp) { *tx_vfo = RIG_VFO_SUB; } else if (is_ftdx10) { *tx_vfo = RIG_VFO_B; } else { result = newcat_get_tx_vfo(rig, tx_vfo); if (result != RIG_OK) { RETURNFUNC(result); } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown split=%c from index 2 of %s\n", __func__, c, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = %s\n", __func__, rig_strvfo(*tx_vfo)); RETURNFUNC(RIG_OK); } int newcat_set_vfo_from_alias(RIG *rig, vfo_t *vfo) { ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: alias vfo = %s\n", __func__, rig_strvfo(*vfo)); if (*vfo == RIG_VFO_NONE) { int rc = rig_get_vfo(rig, vfo); if (rc != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_get_vfo failed: %s\n", __func__, rig_strvfo(*vfo)); RETURNFUNC(rc); } rig_debug(RIG_DEBUG_TRACE, "%s: vfo==None so get vfo=%s\n", __func__, rig_strvfo(*vfo)); } switch (*vfo) { case RIG_VFO_A: case RIG_VFO_B: case RIG_VFO_MEM: /* passes through */ break; case RIG_VFO_CURR: /* RIG_VFO_RX == RIG_VFO_CURR */ case RIG_VFO_VFO: *vfo = STATE(rig)->current_vfo; break; case RIG_VFO_TX: /* set to another vfo for split or uplink */ if (STATE(rig)->vfo_list & RIG_VFO_MAIN) { *vfo = (STATE(rig)->current_vfo == RIG_VFO_SUB) ? RIG_VFO_MAIN : RIG_VFO_SUB; } else { *vfo = (STATE(rig)->current_vfo == RIG_VFO_B) ? RIG_VFO_A : RIG_VFO_B; } break; case RIG_VFO_MAIN: *vfo = RIG_VFO_MAIN; break; case RIG_VFO_SUB: *vfo = RIG_VFO_SUB; break; default: rig_debug(RIG_DEBUG_TRACE, "Unrecognized. vfo= %s\n", rig_strvfo(*vfo)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int newcat_set_narrow(RIG *rig, vfo_t vfo, ncboolean narrow) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, "NA")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (narrow == TRUE) { c = '1'; } else { c = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NA%c%c%c", main_sub_vfo, c, cat_term); rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_narrow(RIG *rig, vfo_t vfo, ncboolean *narrow) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "NA"; char main_sub_vfo = '0'; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", command, main_sub_vfo, cat_term); /* Get NAR */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[3]; if (c == '1') { *narrow = TRUE; } else { *narrow = FALSE; } RETURNFUNC(RIG_OK); } // returns 1 if in narrow mode 0 if not, < 0 if error // if vfo != RIG_VFO_NONE then will use NA0 or NA1 depending on vfo Main or Sub static int get_narrow(RIG *rig, vfo_t vfo) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int narrow = 0; int err; ENTERFUNC; // find out if we're in narrow or wide mode SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "NA%c%c", vfo == RIG_VFO_SUB ? '1' : '0', cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } if (sscanf(priv->ret_data, "NA%*1d%3d", &narrow) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(narrow); } int newcat_set_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int w = 0; char main_sub_vfo = '0'; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s vfo=%s, mode=%s, width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (!newcat_valid_command(rig, "SH")) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_SUB == vfo) ? '1' : '0'; } // NOTE: RIG_PASSBAND_NORMAL (0) should select the default filter width (SH00) if (is_ft950) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 100) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 300) { w = 5; } else if (width <= 400) { w = 6; } else if (width <= 500) { w = 7; } else if (width <= 800) { w = 8; } else if (width <= 1200) { w = 9; } else if (width <= 1400) { w = 10; } else if (width <= 1700) { w = 11; } else if (width <= 2000) { w = 12; } else { w = 13; } // 2400 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2250) { w = 12; } else if (width <= 2400) { w = 13; } else if (width <= 2450) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else { w = 20; } // 3000 Hz break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: RETURNFUNC(RIG_OK); } } // end is_ft950 */ else if (is_ft891) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else if (width <= 2400) { w = 16; } else { w = 17; } // 3000 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else { w = 21; } // 3000 Hz break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) } // end is_ft891 else if (is_ft991) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else if (width <= 2400) { w = 16; } else { w = 17; } // 3000 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else { w = 21; } // 3200 Hz break; case RIG_MODE_AM: // Only 1 passband each for AM or AMN if (width == RIG_PASSBAND_NORMAL || width == 9000) { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_AMN: if (width == RIG_PASSBAND_NORMAL || width == 6000) { err = newcat_set_narrow(rig, vfo, TRUE); } RETURNFUNC(err); case RIG_MODE_FM: // Only 1 passband each for FM or FMN if (width == RIG_PASSBAND_NORMAL || width == 16000) { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: if (width == RIG_PASSBAND_NORMAL || width == 9000) { err = newcat_set_narrow(rig, vfo, TRUE); } RETURNFUNC(err); case RIG_MODE_C4FM: if (width == RIG_PASSBAND_NORMAL || width == 16000) { err = newcat_set_narrow(rig, vfo, TRUE); } else if (width == 9000) { err = newcat_set_narrow(rig, vfo, FALSE); } else { RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(err); case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) } // end is_ft991 else if (is_ftdx1200 || is_ftdx3000) { // FTDX 1200 and FTDX 3000 have the same set of filter choices switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else { w = 16; } // 2400 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else if (width <= 3200) { w = 21; } else if (width <= 3400) { w = 22; } else if (width <= 3600) { w = 23; } else if (width <= 3800) { w = 24; } else { w = 25; } // 4000 Hz break; case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); } } // end is_ftdx1200 and is_ftdx3000 else if (is_ftdx5000) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 500 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 800) { w = 11; } else if (width <= 1200) { w = 12; } else if (width <= 1400) { w = 13; } else if (width <= 1700) { w = 14; } else if (width <= 2000) { w = 15; } else { w = 16; } // 2400 Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode must be chosen correctly before filter width err = newcat_set_narrow(rig, vfo, width <= 1800 ? TRUE : FALSE); if (err != RIG_OK) { RETURNFUNC(err); } if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 200) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1350) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2250) { w = 12; } else if (width <= 2400) { w = 13; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else if (width <= 3200) { w = 21; } else if (width <= 3400) { w = 22; } else if (width <= 3600) { w = 23; } else if (width <= 3800) { w = 24; } else { w = 25; } // 4000 Hz break; case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); } } // end is_ftdx5000 else if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft710) { switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 50) { w = 1; } else if (width <= 100) { w = 2; } else if (width <= 150) { w = 3; } else if (width <= 200) { w = 4; } else if (width <= 250) { w = 5; } else if (width <= 300) { w = 6; } else if (width <= 350) { w = 7; } else if (width <= 400) { w = 8; } else if (width <= 450) { w = 9; } else if (width <= 500) { w = 10; } else if (width <= 600) { w = 11; } else if (width <= 800) { w = 12; } else if (width <= 1200) { w = 13; } else if (width <= 1400) { w = 14; } else if (width <= 1700) { w = 15; } else if (width <= 2000) { w = 16; } else if (width <= 2400) { w = 17; } else if (width <= 3000) { w = 18; } else if (width <= 3200) { w = 19; } else if (width <= 3500) { w = 20; } else { w = 21; } // 4000Hz break; case RIG_MODE_LSB: case RIG_MODE_USB: if (width == RIG_PASSBAND_NORMAL) { w = 0; } else if (width <= 300) { w = 1; } else if (width <= 400) { w = 2; } else if (width <= 600) { w = 3; } else if (width <= 850) { w = 4; } else if (width <= 1100) { w = 5; } else if (width <= 1200) { w = 6; } else if (width <= 1500) { w = 7; } else if (width <= 1650) { w = 8; } else if (width <= 1800) { w = 9; } else if (width <= 1950) { w = 10; } else if (width <= 2100) { w = 11; } else if (width <= 2200) { w = 12; } else if (width <= 2300) { w = 13; } else if (width <= 2400) { w = 14; } else if (width <= 2500) { w = 15; } else if (width <= 2600) { w = 16; } else if (width <= 2700) { w = 17; } else if (width <= 2800) { w = 18; } else if (width <= 2900) { w = 19; } else if (width <= 3000) { w = 20; } else if (width <= 3200) { w = 21; } else if (width <= 3500) { w = 22; } else { w = 23; } // 4000Hz break; case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: // Set roofing filter and narrow mode break; default: RETURNFUNC(-RIG_EINVAL); } // end switch(mode) if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_AMN: case RIG_MODE_FMN: RETURNFUNC(RIG_OK); } } // end is_ftdx101 else if (is_ft2000) { // We need details on the widths here, manuals lack information. switch (mode) { case RIG_MODE_CW: case RIG_MODE_CWR: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); // CW bandwidth is 2400 Hz at value 16 if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 200) { w = 4; } else if (width <= 500) { w = 6; } else if (width <= 2400) { w = 16; } else { w = 31; } // No effect? break; case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); // Packet SSB bandwidth is 2400 Hz at value 31 if (width == RIG_PASSBAND_NORMAL) { w = 31; } else if (width <= 200) { w = 8; } else if (width <= 500) { w = 16; } else { w = 31; } // 2400 break; case RIG_MODE_RTTY: case RIG_MODE_RTTYR: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 300) { w = 8; } else if (width <= 500) { w = 16; } else { w = 31; } // 2400 break; case RIG_MODE_LSB: case RIG_MODE_USB: // Narrow mode overrides DSP filter width on FT-2000 newcat_set_narrow(rig, vfo, FALSE); if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 1800) { w = 8; } else if (width <= 2400) { w = 16; } else if (width <= 3000) { w = 25; } else { w = 31; } // 4000 break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_AMN: case RIG_MODE_FMN: RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_EINVAL); } if ((err = set_roofing_filter_for_width(rig, vfo, width)) != RIG_OK) { RETURNFUNC(err); } switch (mode) { case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_FM: case RIG_MODE_PKTFM: case RIG_MODE_FMN: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); } } else { // FT-450, FTDX 9000 // We need details on the widths here, manuals lack information. switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 500) { w = 6; } else if (width <= 1800) { w = 16; } else { w = 24; } break; case RIG_MODE_LSB: case RIG_MODE_USB: if (width == RIG_PASSBAND_NORMAL) { w = 16; } else if (width <= 1800) { w = 8; } else if (width <= 2400) { w = 16; } else { w = 25; } // 3000 break; case RIG_MODE_AM: case RIG_MODE_FM: case RIG_MODE_PKTFM: if (width > 0 && width < rig_passband_normal(rig, mode)) { err = newcat_set_narrow(rig, vfo, TRUE); } else { err = newcat_set_narrow(rig, vfo, FALSE); } RETURNFUNC(err); case RIG_MODE_FMN: RETURNFUNC(RIG_OK); default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end else */ if (is_ftdx101d || is_ftdx101mp || is_ft891) { // some rigs now require the bandwidth be turned "on" int on = is_ft891; SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH%c%d%02d;", main_sub_vfo, on, w); } else if (is_ft2000 || is_ftdx3000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH0%02d;", w); } else if (is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH00%02d;", w); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "SH%c%02d;", main_sub_vfo, w); } rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); /* Set RX Bandwidth */ RETURNFUNC(newcat_set_cmd(rig)); } static int set_roofing_filter(RIG *rig, vfo_t vfo, int index) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; struct newcat_roofing_filter *roofing_filters; char main_sub_vfo = '0'; char roofing_filter_choice = 0; int err; int i; ENTERFUNC; if (priv_caps == NULL) { RETURNFUNC(-RIG_ENAVAIL); } roofing_filters = priv_caps->roofing_filters; if (rig->caps->targetable_vfo & RIG_TARGETABLE_ROOFING) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (!newcat_valid_command(rig, "RF")) { RETURNFUNC(-RIG_ENAVAIL); } for (i = 0; roofing_filters[i].index >= 0; i++) { const struct newcat_roofing_filter *current_filter = &roofing_filters[i]; char set_value = current_filter->set_value; if (set_value == 0) { continue; } roofing_filter_choice = set_value; if (current_filter->index == index) { break; } } if (roofing_filter_choice == 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c%c", main_sub_vfo, roofing_filter_choice, cat_term); priv->question_mark_response_means_rejected = 1; err = newcat_set_cmd(rig); priv->question_mark_response_means_rejected = 0; if (RIG_OK != err) { RETURNFUNC(err); } RETURNFUNC(RIG_OK); } static int set_roofing_filter_for_width(RIG *rig, vfo_t vfo, int width) { struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; int index = 0; int i; ENTERFUNC; if (priv_caps == NULL) { RETURNFUNC(-RIG_ENAVAIL); } for (i = 0; i < priv_caps->roofing_filter_count; i++) { const struct newcat_roofing_filter *current_filter = &priv_caps->roofing_filters[i]; char set_value = current_filter->set_value; // Skip get-only values and optional filters if (set_value == 0 || current_filter->optional) { continue; } // The last filter is always the narrowest if (current_filter->width < width) { break; } index = current_filter->index; } RETURNFUNC(set_roofing_filter(rig, vfo, index)); } static int get_roofing_filter(RIG *rig, vfo_t vfo, struct newcat_roofing_filter **roofing_filter) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; struct newcat_priv_caps *priv_caps = (struct newcat_priv_caps *)rig->caps->priv; struct newcat_roofing_filter *roofing_filters; char roofing_filter_choice; char main_sub_vfo = '0'; char rf_vfo = 'X'; int err; int n; int i; ENTERFUNC; if (priv_caps == NULL) { RETURNFUNC(-RIG_ENAVAIL); } roofing_filters = priv_caps->roofing_filters; if (rig->caps->targetable_vfo & RIG_TARGETABLE_ROOFING) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "RF%c%c", main_sub_vfo, cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } n = sscanf(priv->ret_data, "RF%c%c", &rf_vfo, &roofing_filter_choice); if (n != 2) { rig_debug(RIG_DEBUG_ERR, "%s: error parsing '%s' for vfo and roofing filter, got %d parsed\n", __func__, priv->ret_data, n); RETURNFUNC(-RIG_EPROTO); } for (i = 0; i < priv_caps->roofing_filter_count; i++) { struct newcat_roofing_filter *current_filter = &roofing_filters[i]; if (current_filter->get_value == roofing_filter_choice) { *roofing_filter = current_filter; RETURNFUNC(RIG_OK); } } rig_debug(RIG_DEBUG_ERR, "%s: Expected a valid roofing filter but got %c from '%s'\n", __func__, roofing_filter_choice, priv->ret_data); RETURNFUNC(RIG_EPROTO); } int newcat_get_rx_bandwidth(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t *width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int w; int sh_command_valid = 1; int narrow = 0; char cmd[] = "SH"; char main_sub_vfo = '0'; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s vfo=%s, mode=%s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode)); if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } err = newcat_set_vfo_from_alias(rig, &vfo); if (err < 0) { RETURNFUNC(err); } if (is_ft950 || is_ftdx5000 || is_ftdx3000) { // Some Yaesu rigs cannot query SH in modes such as AM/FM switch (mode) { case RIG_MODE_FM: case RIG_MODE_FMN: case RIG_MODE_PKTFM: case RIG_MODE_AM: case RIG_MODE_AMN: case RIG_MODE_PKTAM: sh_command_valid = 0; break; } } if (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } if (sh_command_valid) { if (is_ft2000 || is_ftdx10 || is_ftdx3000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s0%c", cmd, cat_term); } else { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c%c", cmd, main_sub_vfo, cat_term); } err = newcat_get_cmd(rig); if (err != RIG_OK) { RETURNFUNC(err); } w = 0; // use default in case of error if (strlen(priv->ret_data) == 7) { int on; // do we need to pay attention to the Main/Sub here? int n = sscanf(priv->ret_data, "SH%*1d%1d%3d", &on, &w); if (n != 2) { err = -RIG_EPROTO; } #if 0 // this may apply to another Yaesu rig if (n == 2) { if (!on) { w = 0; } } else { err = -RIG_EPROTO; } #endif } else if (strlen(priv->ret_data) == 6) { int n = sscanf(priv->ret_data, "SH%3d", &w); if (n != 1) { err = -RIG_EPROTO; } } else { err = -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: w=%d\n", __func__, w); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse width from '%s'\n", __func__, priv->ret_data); RETURNFUNC(-RIG_EPROTO); } } else { // Some Yaesu rigs cannot query filter width using SH command in modes such as AM/FM w = 0; } if (is_ft950) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: *width = narrow ? 300 : 500; break; case 3: *width = 100; break; case 4: *width = 200; break; case 5: *width = 300; break; case 6: *width = 400; break; case 7: *width = 5000; break; case 8: *width = 800; break; case 9: *width = 1200; break; case 10: *width = 1400; break; case 11: *width = 1700; break; case 12: *width = 2000; break; case 13: *width = 2400; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1800 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2250; break; case 13: *width = 2400; break; case 14: *width = 2450; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ft950 */ else if (is_ft891) { if ((narrow = get_narrow(rig, vfo)) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error narrow < 0, narrow=%d\n", __func__, narrow); RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { *width = narrow ? 500 : 2400; } else { *width = narrow ? 300 : 500; } break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; case 17: *width = 3000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown w=%d\n", __func__, w); RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2200; break; case 13: *width = 2300; break; case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; case RIG_MODE_FM: case RIG_MODE_PKTFM: *width = 16000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown mode=%s\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ft891 */ else if (is_ft991) { // some modes are fixed and can't be queried with "NA0" if (mode != RIG_MODE_C4FM && mode != RIG_MODE_PKTFM && mode != RIG_MODE_PKTFMN && (narrow = get_narrow(rig, vfo)) < 0) { RETURNFUNC(-RIG_EPROTO); } narrow = 0; switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { *width = narrow ? 500 : 2400; } else { *width = narrow ? 300 : 500; } break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; case 17: *width = 3000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2200; break; case 13: *width = 2300; break; case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; case RIG_MODE_FM: case RIG_MODE_C4FM: case RIG_MODE_PKTFM: *width = 16000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ft991 */ else if (is_ftdx1200 || is_ftdx3000) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: *width = narrow ? 500 : 2400; break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2250; break; case 13: *width = 2400; break; case 14: *width = 2450; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; case 22: *width = 3400; break; case 23: *width = 3600; break; case 24: *width = 3800; break; case 25: *width = 4000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ftdx1200 or is_ftdx3000 */ else if (is_ftdx5000) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: *width = narrow ? 500 : 2400; break; case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 800; break; case 12: *width = 1200; break; case 13: *width = 1400; break; case 14: *width = 1700; break; case 15: *width = 2000; break; case 16: *width = 2400; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: *width = narrow ? 1500 : 2400; break; case 1: *width = 200; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1350; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2250; break; case 13: *width = 2400; break; // 14 is not defined for FTDX 5000, but leaving here for completeness case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; case 22: *width = 3400; break; case 23: *width = 3600; break; case 24: *width = 3800; break; case 25: *width = 4000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ } /* end if is_ftdx5000 */ else if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { rig_debug(RIG_DEBUG_TRACE, "%s: is_ftdx101 w=%d, mode=%s\n", __func__, w, rig_strrmode(mode)); if (w == 0) // then we need to know the roofing filter { struct newcat_roofing_filter *roofing_filter; err = get_roofing_filter(rig, vfo, &roofing_filter); if (err == RIG_OK) { *width = roofing_filter->width; } } switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: switch (w) { case 0: break; /* use roofing filter width */ case 1: *width = 50; break; case 2: *width = 100; break; case 3: *width = 150; break; case 4: *width = 200; break; case 5: *width = 250; break; case 6: *width = 300; break; case 7: *width = 350; break; case 8: *width = 400; break; case 9: *width = 450; break; case 10: *width = 500; break; case 11: *width = 600; break; case 12: *width = 800; break; case 13: *width = 1200; break; case 14: *width = 1400; break; case 15: *width = 1700; break; case 16: *width = 2000; break; case 17: *width = 2400; break; case 18: *width = 3000; break; case 19: *width = 3200; break; case 20: *width = 3500; break; case 21: *width = 4000; break; default: RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_LSB: case RIG_MODE_USB: switch (w) { case 0: break; /* use roofing filter width */ case 1: *width = 300; break; case 2: *width = 400; break; case 3: *width = 600; break; case 4: *width = 850; break; case 5: *width = 1100; break; case 6: *width = 1200; break; case 7: *width = 1500; break; case 8: *width = 1650; break; case 9: *width = 1800; break; case 10: *width = 1950; break; case 11: *width = 2100; break; case 12: *width = 2200; break; case 13: *width = 2300; break; case 14: *width = 2400; break; case 15: *width = 2500; break; case 16: *width = 2600; break; case 17: *width = 2700; break; case 18: *width = 2800; break; case 19: *width = 2900; break; case 20: *width = 3000; break; case 21: *width = 3200; break; case 22: *width = 3500; break; case 23: *width = 4000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown width=%d\n", __func__, w); RETURNFUNC(-RIG_EINVAL); } break; case RIG_MODE_AM: case RIG_MODE_FMN: case RIG_MODE_PKTFMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; case RIG_MODE_FM: case RIG_MODE_PKTFM: *width = 16000; break; default: rig_debug(RIG_DEBUG_TRACE, "%s: bad mode\n", __func__); RETURNFUNC(-RIG_EINVAL); } /* end switch(mode) */ rig_debug(RIG_DEBUG_TRACE, "%s: end if FTDX101D\n", __func__); } /* end if is_ftdx101 */ else if (is_ft2000) { if ((narrow = get_narrow(rig, RIG_VFO_MAIN)) < 0) { RETURNFUNC(-RIG_EPROTO); } switch (mode) { case RIG_MODE_CW: case RIG_MODE_CWR: if (w <= 4) { *width = 200; } else if (w <= 6) { *width = 500; } else if (w <= 16) { *width = 2400; } else { *width = 3000; } break; case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: if (w <= 8) { *width = 200; } else if (w <= 16) { *width = 500; } else { *width = 2400; } break; case RIG_MODE_RTTY: case RIG_MODE_RTTYR: if (w <= 8) { *width = 300; } else if (w <= 16) { *width = 500; } else { *width = 2400; } break; case RIG_MODE_LSB: case RIG_MODE_USB: if (w <= 8) { *width = 1800; } else if (w <= 16) { *width = 2400; } else if (w <= 25) { *width = 3000; } else { *width = 4000; } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch (mode) */ } /* end if is_ft2000 */ else { /* FT450, FT9000 */ switch (mode) { case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: case RIG_MODE_CW: case RIG_MODE_CWR: case RIG_MODE_LSB: case RIG_MODE_USB: if (w < 16) { *width = rig_passband_narrow(rig, mode); } else if (w > 16) { *width = rig_passband_wide(rig, mode); } else { *width = rig_passband_normal(rig, mode); } break; case RIG_MODE_AM: *width = narrow ? 6000 : 9000; break; case RIG_MODE_PKTFM: case RIG_MODE_FM: *width = narrow ? 9000 : 16000; break; case RIG_MODE_FMN: *width = 9000; break; case RIG_MODE_AMN: *width = 6000; break; default: RETURNFUNC(-RIG_EINVAL); } /* end switch (mode) */ } /* end else */ rig_debug(RIG_DEBUG_TRACE, "%s: RETURNFUNC(RIG_OK)\n", __func__); RETURNFUNC(RIG_OK); } int newcat_set_faststep(RIG *rig, ncboolean fast_step) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char c; ENTERFUNC; if (!newcat_valid_command(rig, "FS")) { RETURNFUNC(-RIG_ENAVAIL); } if (fast_step == TRUE) { c = '1'; } else { c = '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "FS%c%c", c, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } int newcat_get_faststep(RIG *rig, ncboolean *fast_step) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; char c; char command[] = "FS"; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); /* Get Fast Step */ if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } c = priv->ret_data[2]; if (c == '1') { *fast_step = TRUE; } else { *fast_step = FALSE; } RETURNFUNC(RIG_OK); } int newcat_get_rigid(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; const char *s = NULL; ENTERFUNC; /* if first valid get */ if (priv->rig_id == NC_RIGID_NONE) { s = newcat_get_info(rig); if (s != NULL) { s += 2; /* ID0310, jump past ID */ priv->rig_id = atoi(s); is_ftdx3000dm = priv->rig_id == NC_RIGID_FTDX3000DM; } rig_debug(RIG_DEBUG_TRACE, "rig_id = %d, idstr = %s\n", priv->rig_id, s == NULL ? "NULL" : s); } else { rig_debug(RIG_DEBUG_TRACE, "rig_id = %d\n", priv->rig_id); } RETURNFUNC(priv->rig_id); } /* * input: RIG *, vfo_t * * output: VFO mode: RIG_VFO_VFO for VFO A or B * RIG_VFO_MEM for VFO MEM * return: RIG_OK or error */ int newcat_get_vfo_mode(RIG *rig, vfo_t vfo, vfo_t *vfo_mode) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int offset = 0; char *cmd = "IF"; ENTERFUNC; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { // OI always returns VFOB and IF always VFOA cmd = "OI"; } if (!newcat_valid_command(rig, cmd)) { RETURNFUNC(-RIG_ENAVAIL); } /* Get VFO Information ****************** */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", cmd, cat_term); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } if (STATE(rig)->powerstat == 0) { rig_debug(RIG_DEBUG_WARN, "%s: Cannot get from rig when power is off\n", __func__); RETURNFUNC(RIG_OK); // to prevent repeats } /* vfo, mem, P7 ************************** */ // e.g. FT450 has 27 byte IF response, FT991 has 28 byte if response (one more byte for P2 VFO A Freq) // so we now check to ensure we know the length of the response switch (strlen(priv->ret_data)) { case 27: offset = 21; priv->width_frequency = 8; break; case 41: // FT-991 V2-01 seems to randomly give 13 extra bytes case 28: offset = 22; priv->width_frequency = 9; break; default: rig_debug(RIG_DEBUG_ERR, "%s: incorrect length of IF response, expected 27 or 28, got %d\n", __func__, (int)strlen(priv->ret_data)); RETURNFUNC(-RIG_EPROTO); } rig_debug(RIG_DEBUG_TRACE, "%s: offset=%d, width_frequency=%d\n", __func__, offset, priv->width_frequency); switch (priv->ret_data[offset]) { case '0': *vfo_mode = RIG_VFO_VFO; break; case '1': /* Memory */ case '2': /* Memory Tune */ case '3': /* Quick Memory Bank */ case '4': /* Quick Memory Bank Tune */ default: *vfo_mode = RIG_VFO_MEM; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo mode = %s\n", __func__, rig_strvfo(*vfo_mode)); RETURNFUNC(err); } /* * Writes data and waits for response * input: complete CAT command string including termination in cmd_str * output: complete CAT command answer string in ret_data * return: RIG_OK or error */ int newcat_vfomem_toggle(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char command[] = "VM"; ENTERFUNC; if (!newcat_valid_command(rig, command)) { RETURNFUNC(-RIG_ENAVAIL); } /* copy set command */ SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s%c", command, cat_term); rig_debug(RIG_DEBUG_TRACE, "%s: cmd_str = %s\n", __func__, priv->cmd_str); RETURNFUNC(newcat_set_cmd(rig)); } /* * Writes a null terminated command string from priv->cmd_str to the * CAT port and returns a response from the rig in priv->ret_data * which is also null terminated. * * Honors the 'retry' capabilities field by resending the command up * to 'retry' times until a valid response is received. In the special * cases of receiving a valid response to a different command or the * "?;" busy please wait response; the command is not resent but up to * 'retry' retries to receive a valid response are made. */ int newcat_get_cmd(RIG *rig) { struct rig_state *state = STATE(rig); hamlib_port_t *rp = RIGPORT(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retry_count = 0; int rc = -RIG_EPROTO; int is_read_cmd = 0; int is_power_status_cmd = strncmp(priv->cmd_str, "PS", 2) == 0; ENTERFUNC; priv->ret_data[0] = 0; // ensure zero-length ret_data by default if (state->powerstat == 0 && !is_power_status_cmd) { rig_debug(RIG_DEBUG_WARN, "%s: Cannot get from rig when power is off\n", __func__); RETURNFUNC(RIG_OK); // to prevent repeats } // try to cache rapid repeats of the IF command // this is for WSJT-X/JTDX sequence of v/f/m/t // should allow rapid repeat of any call using the IF; cmd // Any call that changes something in the IF response should invalidate the cache if (strcmp(priv->cmd_str, "IF;") == 0 && priv->cache_start.tv_sec != 0) { int cache_age_ms; cache_age_ms = elapsed_ms(&priv->cache_start, 0); if (cache_age_ms < 500) // 500ms cache time { rig_debug(RIG_DEBUG_TRACE, "%s: cache hit, age=%dms\n", __func__, cache_age_ms); strcpy(priv->ret_data, priv->last_if_response); RETURNFUNC(RIG_OK); } // we drop through and do the real IF command } // any command that is read only should not expire cache is_read_cmd = strcmp(priv->cmd_str, "AG0;") == 0 || strcmp(priv->cmd_str, "AG1;") == 0 || strcmp(priv->cmd_str, "AN0;") == 0 || strcmp(priv->cmd_str, "AN1;") == 0 || strcmp(priv->cmd_str, "BP00;") == 0 || strcmp(priv->cmd_str, "BP01;") == 0 || strcmp(priv->cmd_str, "BP10;") == 0 || strcmp(priv->cmd_str, "BP11;") == 0 || strcmp(priv->cmd_str, "CN00;") == 0 || strcmp(priv->cmd_str, "CN10;") == 0 || strcmp(priv->cmd_str, "CO00;") == 0 || strcmp(priv->cmd_str, "CO01;") == 0 || strcmp(priv->cmd_str, "CO02;") == 0 || strcmp(priv->cmd_str, "CO03;") == 0 || strcmp(priv->cmd_str, "CO10;") == 0 || strcmp(priv->cmd_str, "CO11;") == 0 || strcmp(priv->cmd_str, "CO12;") == 0 || strcmp(priv->cmd_str, "CO13;") == 0 || strcmp(priv->cmd_str, "IS0;") == 0 || strcmp(priv->cmd_str, "IS1;") == 0 || strcmp(priv->cmd_str, "MD0;") == 0 || strcmp(priv->cmd_str, "MD1;") == 0 || strcmp(priv->cmd_str, "NA0;") == 0 || strcmp(priv->cmd_str, "NA1;") == 0 || strcmp(priv->cmd_str, "NB0;") == 0 || strcmp(priv->cmd_str, "NB1;") == 0 || strcmp(priv->cmd_str, "NL0;") == 0 || strcmp(priv->cmd_str, "NL1;") == 0 || strcmp(priv->cmd_str, "NR0;") == 0 || strcmp(priv->cmd_str, "NR1;") == 0 || strcmp(priv->cmd_str, "OI;") == 0 || strcmp(priv->cmd_str, "OS0;") == 0 || strcmp(priv->cmd_str, "OS1;") == 0 || strcmp(priv->cmd_str, "PA0;") == 0 || strcmp(priv->cmd_str, "PA1;") == 0 || strcmp(priv->cmd_str, "RA0;") == 0 || strcmp(priv->cmd_str, "RA1;") == 0 || strcmp(priv->cmd_str, "RF0;") == 0 || strcmp(priv->cmd_str, "RF1;") == 0 || strcmp(priv->cmd_str, "RL0;") == 0 || strcmp(priv->cmd_str, "RL1;") == 0 || strncmp(priv->cmd_str, "RM", 2) == 0 || strcmp(priv->cmd_str, "SM0;") == 0 || strcmp(priv->cmd_str, "SM1;") == 0 || strcmp(priv->cmd_str, "SQ0;") == 0 || strcmp(priv->cmd_str, "SQ1;") == 0 || strcmp(priv->cmd_str, "VT0;") == 0 || strcmp(priv->cmd_str, "VT1;") == 0; if (priv->cmd_str[2] != ';' && !is_read_cmd) { // then we must be setting something so we'll invalidate the cache rig_debug(RIG_DEBUG_TRACE, "%s: cache invalidated\n", __func__); priv->cache_start.tv_sec = 0; } while (rc != RIG_OK && retry_count++ <= rp->retry) { rig_flush(rp); /* discard any unsolicited data */ if (rc != -RIG_BUSBUSY) { /* send the command */ rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); rc = write_block(rp, (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)); if (rc != RIG_OK) { RETURNFUNC(rc); } } /* read the reply */ if ((rc = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1)) <= 0) { // if we get a timeout from PS probably means power is off if (rc == -RIG_ETIMEOUT && is_power_status_cmd) { rig_debug(RIG_DEBUG_WARN, "%s: rig power is off?\n", __func__); RETURNFUNC(rc); } continue; /* usually a timeout - retry */ } rig_debug(RIG_DEBUG_TRACE, "%s: read count = %d, ret_data = %s\n", __func__, rc, priv->ret_data); rc = RIG_OK; /* received something */ /* Check that command termination is correct - alternative is response is longer than the buffer */ if (cat_term != priv->ret_data[strlen(priv->ret_data) - 1]) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, priv->ret_data); rc = -RIG_EPROTO; /* retry */ /* we could decrement retry_count here but there is a danger of infinite looping so we just use up a retry for safety's sake */ continue; } /* check for error codes */ if (2 == strlen(priv->ret_data)) { /* The following error responses are documented for Kenwood but not for Yaesu, but at least one of them is known to occur in that the FT-450 certainly responds to "IF;" occasionally with "?;". The others are harmless even of they do not occur as they are unambiguous. */ switch (priv->ret_data[0]) { case 'N': /* Command recognized by rig but invalid data entered. */ rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ENAVAIL); case 'O': // Too many characters sent without a carriage return rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EPROTO; break; /* retry */ case 'E': /* Communication error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EIO; break; /* retry */ case '?': /* The ? response is ambiguous and undocumented by Yaesu, but for get commands it seems to * indicate that the rig rejected the command because the state of the rig is not valid for the command * or that the command parameter is invalid. Retrying the command does not fix the issue, * as the error is caused by the an invalid combination of rig state. * * For example, the following cases have been observed: * - MR and MC commands are rejected when referring to an _empty_ memory channel even * if the channel number is in a valid range * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are * supported only in SSB/CW/RTTY modes * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode * * There are many more cases like these and they vary by rig model. * * So far, "rig busy" type situations with the ? response have not been observed for get commands. * Followup 20201213 FTDX3000 FB; command returning ?; so do NOT abort * see https://github.com/Hamlib/Hamlib/issues/464 */ if (priv->question_mark_response_means_rejected) { rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig (get): '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ERJCTED); } rig_debug(RIG_DEBUG_WARN, "%s: Rig busy - retrying %d of %d: '%s'\n", __func__, retry_count, rp->retry, priv->cmd_str); // DX3000 was taking 1.6 seconds in certain command sequences hl_usleep(600 * 1000); // 600ms wait should cover most cases hopefully rc = -RIG_ERJCTED; /* retry */ break; } continue; } /* verify that reply was to the command we sent */ if ((priv->ret_data[0] != priv->cmd_str[0] || priv->ret_data[1] != priv->cmd_str[1])) { /* * TODO: When RIG_TRN is enabled, we can pass the string * to the decoder for callback. That way we don't ignore * any commands. */ rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %.2s for command %.2s\n", __func__, priv->ret_data, priv->cmd_str); // we were using BUSBUSY but microham devices need retries // this should be OK under all other circumstances too //rc = -RIG_BUSBUSY; /* retry read only */ rc = -RIG_EPROTO; } } // update the cache if (strncmp(priv->cmd_str, "IF;", 3) == 0) { elapsed_ms(&priv->cache_start, 1); strcpy(priv->last_if_response, priv->ret_data); } RETURNFUNC(rc); } /* * This tries to set and read to validate the set command actually worked * returns RIG_OK if set, -RIG_EIMPL if not implemented yet, or -RIG_EPROTO if unsuccessful */ int newcat_set_cmd_validate(RIG *rig) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char valcmd[16]; int retries = 8; int retry = 0; int sleepms = 50; int rc = -RIG_EPROTO; ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: priv->cmd_str=%s\n", __func__, priv->cmd_str); // For FA and FB rig.c now tries to verify the set_freq actually works // For example the FT-2000 can't do a FA set followed by an immediate read // We were using "ID" to verify the command but rig.c now does // a verification of frequency and retries if it doesn't match if ((strncmp(priv->cmd_str, "FA", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "FA;"); if (priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX5000 || priv->rig_id == NC_RIGID_FTDX3000DM) { strcpy(valcmd, ""); } } else if ((strncmp(priv->cmd_str, "FB", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "FB;"); if (priv->rig_id == NC_RIGID_FTDX3000 || priv->rig_id == NC_RIGID_FTDX5000 || priv->rig_id == NC_RIGID_FTDX3000DM) { strcpy(valcmd, ""); } } else if ((strncmp(priv->cmd_str, "MD", 2) == 0) && (strlen(priv->cmd_str) > 3)) { #if 0 strcpy(valcmd, priv->cmd_str); // pull the needed part of the cmd valcmd[3] = ';'; valcmd[4] = 0; #endif // Win4Yaesu was not responding fast enough to validate the MD cmd strcpy(valcmd, ""); } else if ((strncmp(priv->cmd_str, "TX", 2) == 0) && (strlen(priv->cmd_str) > 3)) { if (priv->cmd_str[2] == '1' && rig->caps->rig_model == RIG_MODEL_FT950) // FT950 didn't like TX; after TX1; { valcmd[0] = 0; } else { strcpy(valcmd, "TX;"); } } else if ((strncmp(priv->cmd_str, "FT", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "FT;"); } else if ((strncmp(priv->cmd_str, "AI", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "AI;"); } else if ((strncmp(priv->cmd_str, "VS", 2) == 0) && (strlen(priv->cmd_str) > 3)) { strcpy(valcmd, "VS;"); // Some models treat the 2nd VS as a mute request if (is_ftdx3000 || is_ftdx9000) { strcpy(valcmd, ""); } } else if (strncmp(priv->cmd_str, "SV", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BA", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "AB", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BS", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "MS", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "SH", 2) == 0) { // could validate with SH but different formats need to be handled strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "RF", 2) == 0) { // could validate with RF but different formats need to be handled strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BU", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "BD", 2) == 0) { strcpy(valcmd, ""); // nothing to validate } else if (strncmp(priv->cmd_str, "EX", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "ST;", 3) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "ST", 2) == 0) { strcpy(valcmd, "ST;"); } else if (strncmp(priv->cmd_str, "KM", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "KY", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "PC", 2) == 0) { strcpy(valcmd, "PC;"); } else if (strncmp(priv->cmd_str, "AC", 2) == 0) { strcpy(valcmd, ""); } else if (strncmp(priv->cmd_str, "SY", 2) == 0) { strcpy(valcmd, "SY;"); } else { rig_debug(RIG_DEBUG_TRACE, "%s: %s not implemented\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ENIMPL); } while (rc != RIG_OK && retry++ < retries) { int bytes; hamlib_port_t *rp = RIGPORT(rig); char cmd[256]; // big enough repeat: rig_flush(rp); /* discard any unsolicited data */ SNPRINTF(cmd, sizeof(cmd), "%s", priv->cmd_str); rc = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (rc != RIG_OK) { RETURNFUNC(-RIG_EIO); } if (strlen(valcmd) == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(cmd, sizeof(cmd), "%s", valcmd); // some rigs like FT-450/Signalink need a little time before we can ask for TX status again if (strncmp(valcmd, "TX", 2) == 0) { hl_usleep(50 * 1000); } rc = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (rc != RIG_OK) { RETURNFUNC(-RIG_EIO); } bytes = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1); // we're expecting a response so we'll repeat if needed if (bytes == 0) { goto repeat; } // FA and FB success is now verified in rig.c with a followup query // so no validation is needed if (strncmp(priv->cmd_str, "FA", 2) == 0 || strncmp(priv->cmd_str, "FB", 2) == 0) { RETURNFUNC(RIG_OK); } if (strncmp(priv->cmd_str, "PC", 2) == 0 && priv->ret_data[0] == '?') { rig_debug(RIG_DEBUG_ERR, "%s: Power level error, check if exceeding max power setting\n", __func__); RETURNFUNC(RIG_OK); } if (strncmp(priv->cmd_str, "FT", 2) == 0 && strncmp(priv->ret_data, "FT", 2) == 0) { // FT command does not echo what's sent so we just check the basic command RETURNFUNC(RIG_OK); } 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); } if (bytes > 0) { // for the BS command we can only run it once // so we'll assume it worked // maybe Yaesu will make this command more intelligent if (strstr(priv->cmd_str, "BS")) { RETURNFUNC(RIG_OK); } // if the first two chars match we are validated if (strncmp(priv->cmd_str, "VS", 2) == 0 && strncmp(priv->cmd_str, priv->ret_data, 2) == 0) { RETURNFUNC(RIG_OK); } else if (strcmp(priv->cmd_str, priv->ret_data) == 0) { RETURNFUNC(RIG_OK); } else if (priv->cmd_str[0] == ';' && priv->ret_data[0] == '?') { hl_usleep(50 * 1000); RETURNFUNC(RIG_OK); } else { rc = -RIG_EPROTO; } } rig_debug(RIG_DEBUG_WARN, "%s: cmd validation failed, '%s'!='%s', try#%d\n", __func__, priv->cmd_str, priv->ret_data, retry); hl_usleep(sleepms * 1000); } RETURNFUNC(-RIG_EPROTO); } /* * Writes a null terminated command string from priv->cmd_str to the * CAT port that is not expected to have a response. * * Honors the 'retry' capabilities field by resending the command up * to 'retry' times until a valid response is received. In the special * cases of receiving a valid response to a different command or the * "?;" busy please wait response; the command is not resent but up to * 'retry' retries to receive a valid response are made. */ int newcat_set_cmd(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int retry_count = 0; int rc = -RIG_EPROTO; ENTERFUNC; /* pick a basic quick query command for verification */ char const *const verify_cmd = RIG_MODEL_FT9000 == rig->caps->rig_model ? "AI;" : "ID;"; while (rc != RIG_OK && retry_count++ <= rp->retry) { rig_flush(rp); /* discard any unsolicited data */ /* send the command */ rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", priv->cmd_str); rc = newcat_set_cmd_validate(rig); if (rc == RIG_OK) { // if we were able to set and and validate we're done rig_debug(RIG_DEBUG_TRACE, "%s: cmd_validate OK\n", __func__); RETURNFUNC(RIG_OK); } else if (rc == -RIG_EPROTO) { rig_debug(RIG_DEBUG_TRACE, "%s: set_cmd_validate failed\n", __func__); RETURNFUNC(rc); } rig_debug(RIG_DEBUG_TRACE, "%s: newcat_set_cmd_validate not implemented...continuing\n", __func__); if (RIG_OK != (rc = write_block(rp, (unsigned char *) priv->cmd_str, strlen(priv->cmd_str)))) { RETURNFUNC(rc); } /* skip validation if high throughput is needed */ if (priv->fast_set_commands == TRUE) { RETURNFUNC(RIG_OK); } // freq set and ptt are now verified in rig.c // ST command is not validated -- caused problems on FTDX101D if (strncmp(priv->cmd_str, "FA", 2) == 0 || strncmp(priv->cmd_str, "FB", 2) == 0 || strncmp(priv->cmd_str, "TX", 2) == 0 || strncmp(priv->cmd_str, "MD", 2) == 0 // Win4Yaesu not responding fast enough on MD change || strncmp(priv->cmd_str, "ST", 2) == 0) { RETURNFUNC(RIG_OK); } if (strncmp(priv->cmd_str, "BS", 2) == 0) { // the BS command needs time to do its thing hl_usleep(500 * 1000); priv->cache_start.tv_sec = 0; // invalidate the cache } /* send the verification command */ rig_debug(RIG_DEBUG_TRACE, "cmd_str = %s\n", verify_cmd); if (RIG_OK != (rc = write_block(rp, (unsigned char *) verify_cmd, strlen(verify_cmd)))) { RETURNFUNC(rc); } /* read the reply */ if ((rc = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1)) <= 0) { continue; /* usually a timeout - retry */ } rig_debug(RIG_DEBUG_TRACE, "%s(%d): read count = %d, ret_data = %s\n", __func__, __LINE__, rc, priv->ret_data); rc = RIG_OK; /* received something */ /* check for error codes */ if (2 == strlen(priv->ret_data)) { /* The following error responses are documented for Kenwood but not for Yaesu, but at least one of them is known to occur in that the FT-450 certainly responds to "IF;" occasionally with "?;". The others are harmless even of they do not occur as they are unambiguous. */ switch (priv->ret_data[0]) { case 'N': /* Command recognized by rig but invalid data entered. */ rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ENAVAIL); case 'O': // Too many characters sent without a carriage return rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EPROTO; break; /* retry */ case 'E': /* Communication error */ rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, priv->cmd_str); rc = -RIG_EIO; break; /* retry */ case '?': /* The ? response is ambiguous and undocumented by Yaesu. For set commands it seems to indicate: * 1) either that the rig is busy and the command needs to be retried * 2) or that the rig rejected the command because the state of the rig is not valid for the command * or that the command parameter is invalid. Retrying the command does not fix the issue * in this case, as the error is caused by the an invalid combination of rig state. * The latter case is consistent with behaviour of get commands. * * For example, the following cases have been observed: * - MR and MC commands are rejected when referring to an _empty_ memory channel even * if the channel number is in a valid range * - BC (ANF) and RL (NR) commands fail in AM/FM modes, because they are * supported only in SSB/CW/RTTY modes * - MG (MICGAIN) command fails in RTTY mode, as it's a digital mode * * There are many more cases like these and they vary by rig model. */ if (priv->question_mark_response_means_rejected) { rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig (set): '%s'\n", __func__, priv->cmd_str); RETURNFUNC(-RIG_ERJCTED); } /* Rig busy wait please */ rig_debug(RIG_DEBUG_WARN, "%s: Rig busy - retrying: '%s'\n", __func__, priv->cmd_str); /* read/flush the verify command reply which should still be there */ if ((rc = read_string(rp, (unsigned char *) priv->ret_data, sizeof(priv->ret_data), &cat_term, sizeof(cat_term), 0, 1)) > 0) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): read count = %d, ret_data = %s\n", __func__, __LINE__, rc, priv->ret_data); rc = -RIG_BUSBUSY; /* retry */ } break; } } if (RIG_OK == rc) { /* Check that response prefix and response termination is correct - alternative is response is longer that the buffer */ if (strncmp(verify_cmd, priv->ret_data, strlen(verify_cmd) - 1) || (cat_term != priv->ret_data[strlen(priv->ret_data) - 1])) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected verify command response '%s'\n", __func__, priv->ret_data); rc = -RIG_BUSBUSY; continue; /* retry */ } } } RETURNFUNC(rc); } struct { rmode_t mode; char modechar; ncboolean chk_width; } static const newcat_mode_conv[] = { { RIG_MODE_LSB, '1', FALSE }, { RIG_MODE_USB, '2', FALSE }, { RIG_MODE_CW, '3', FALSE }, { RIG_MODE_FM, '4', TRUE}, { RIG_MODE_AM, '5', TRUE}, { RIG_MODE_RTTY, '6', FALSE }, { RIG_MODE_CWR, '7', FALSE }, { RIG_MODE_PKTLSB, '8', FALSE }, { RIG_MODE_RTTYR, '9', FALSE }, { RIG_MODE_PKTFM, 'A', TRUE}, { RIG_MODE_FMN, 'B', TRUE}, { RIG_MODE_PKTUSB, 'C', FALSE }, { RIG_MODE_AMN, 'D', TRUE}, { RIG_MODE_C4FM, 'E', TRUE}, { RIG_MODE_PKTFMN, 'F', TRUE} }; rmode_t newcat_rmode(char mode) { int i; for (i = 0; i < sizeof(newcat_mode_conv) / sizeof(newcat_mode_conv[0]); i++) { if (newcat_mode_conv[i].modechar == mode) { rig_debug(RIG_DEBUG_TRACE, "%s: %s for %c\n", __func__, rig_strrmode(newcat_mode_conv[i].mode), mode); return (newcat_mode_conv[i].mode); } } return (RIG_MODE_NONE); } char newcat_modechar(rmode_t rmode) { int i; for (i = 0; i < sizeof(newcat_mode_conv) / sizeof(newcat_mode_conv[0]); i++) { if (newcat_mode_conv[i].mode == rmode) { rig_debug(RIG_DEBUG_TRACE, "%s: return %c for %s\n", __func__, newcat_mode_conv[i].modechar, rig_strrmode(rmode)); return (newcat_mode_conv[i].modechar); } } return ('0'); } rmode_t newcat_rmode_width(RIG *rig, vfo_t vfo, char mode, pbwidth_t *width) { ncboolean narrow; int i; ENTERFUNC2; *width = RIG_PASSBAND_NORMAL; for (i = 0; i < sizeof(newcat_mode_conv) / sizeof(newcat_mode_conv[0]); i++) { if (newcat_mode_conv[i].modechar == mode) { if (newcat_mode_conv[i].chk_width == TRUE) { // crude fix because 991 hangs on NA0; command while in C4FM if (newcat_is_rig(rig, RIG_MODEL_FT991)) { if (mode == 'E') { *width = 16000; } else if (mode == 'F') { *width = 9000; } rig_debug(RIG_DEBUG_TRACE, "991A & C4FM Skip newcat_get_narrow in %s\n", __func__); } else { if (newcat_get_narrow(rig, vfo, &narrow) != RIG_OK) { RETURNFUNC2(newcat_mode_conv[i].mode); } if (narrow == TRUE) { *width = rig_passband_narrow(rig, mode); } else { *width = rig_passband_normal(rig, mode); } } } // don't use RETURNFUNC here as that macros expects an int for the return code RETURNFUNC2(newcat_mode_conv[i].mode); } } rig_debug(RIG_DEBUG_VERBOSE, "%s fell out the bottom %c %s\n", __func__, mode, rig_strrmode(mode)); RETURNFUNC2('0'); } int newcat_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { char *p1 = "0"; // newer rigs have 2 bytes where is fixed at zero e.g. FT991 struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "PB")) { RETURNFUNC2(-RIG_ENAVAIL); } // we don't do any channel checking -- varies by rig -- could do it but not critical SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "PB%s%d%c", p1, ch, cat_term); RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_set_clarifier(RIG *rig, vfo_t vfo, int rx, int tx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } // Negative value keeps the current state for RIT/XIT if (rx < 0 || tx < 0) { int current_rx, current_tx, result; result = newcat_get_clarifier(rig, vfo, ¤t_rx, ¤t_tx); if (result == RIG_OK) { if (rx < 0) { rx = current_rx; } if (tx < 0) { tx = current_tx; } } else { if (rx < 0) { rx = 0; } if (tx < 0) { tx = 0; } } } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c00%d%d000%c", main_sub_vfo, rx ? 1 : 0, tx ? 1 : 0, cat_term); RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_clarifier(RIG *rig, vfo_t vfo, int *rx, int *tx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c00%c", main_sub_vfo, cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; if (rx != NULL) { *rx = (ret_data[0] == '1') ? 1 : 0; } if (tx != NULL) { *tx = (ret_data[1] == '1') ? 1 : 0; } RETURNFUNC2(RIG_OK); } int newcat_set_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c01%+05d%c", main_sub_vfo, (int) freq, cat_term); RETURNFUNC2(newcat_set_cmd(rig)); } int newcat_get_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t *freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = '0'; int err; int ret_data_len; char *ret_data; int freq_result; int result; if (!newcat_valid_command(rig, "CF")) { RETURNFUNC2(-RIG_ENAVAIL); } if (rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) { main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CF%c01%c", main_sub_vfo, cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; result = sscanf(ret_data, "%05d", &freq_result); if (result != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error parsing clarifier frequency: %s\n", __func__, ret_data); RETURNFUNC2(-RIG_EPROTO); } *freq = (shortfreq_t) freq_result; RETURNFUNC2(RIG_OK); } static int newcat_set_apf_frequency(RIG *rig, vfo_t vfo, int freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } // Range seems to be -250..250 Hz in 10 Hz steps if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c3%04d%c", main_sub_vfo, (freq + 250) / 10, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO03%04d%c", (freq + 250) / 10, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%02d%c", (freq + 250) / 10, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_apf_frequency(RIG *rig, vfo_t vfo, int *freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c3%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO03%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO02%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; int raw_value = atoi(ret_data); // Range seems to be -250..250 Hz in 10 Hz steps *freq = raw_value * 10 - 250; RETURNFUNC2(RIG_OK); } static int newcat_set_apf_width(RIG *rig, vfo_t vfo, int choice) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030201%d%c", choice, cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030204%d%c", choice, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX111%d%c", choice, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1201%d%c", choice, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%d%c", choice, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX107%d%c", choice, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_apf_width(RIG *rig, vfo_t vfo, int *choice) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030201%c", cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030204%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX111%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1201%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX107%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *choice = atoi(ret_data); RETURNFUNC2(RIG_OK); } static int newcat_set_contour(RIG *rig, vfo_t vfo, int status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%04d%c", main_sub_vfo, status ? 1 : 0, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%04d%c", status ? 1 : 0, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%02d%c", main_sub_vfo, status ? 1 : 0, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%02d%c", status ? 1 : 0, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour(RIG *rig, vfo_t vfo, int *status) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; int err; int ret_data_len; char *ret_data; int last_char_index; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c0%c", main_sub_vfo, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO00%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; last_char_index = strlen(ret_data) - 1; *status = (ret_data[last_char_index] == '1') ? 1 : 0; RETURNFUNC2(RIG_OK); } static int newcat_set_contour_frequency(RIG *rig, vfo_t vfo, int freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { // Range is 10..3200 Hz SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%04d%c", main_sub_vfo, freq, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { // Range is 10..3200 Hz SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%04d%c", freq, cat_term); } else if (is_ftdx5000) { // Range is 100..4000 Hz in 100 Hz steps SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%01d%c", main_sub_vfo, freq / 100, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { // Range is 100..4000 Hz in 100 Hz steps SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%02d%c", freq / 100, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour_frequency(RIG *rig, vfo_t vfo, int *freq) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; char main_sub_vfo = (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo) ? '1' : '0'; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "CO")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%c", main_sub_vfo, cat_term); } else if (is_ftdx10 || is_ft991 || is_ft891 || is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO%c1%c", main_sub_vfo, cat_term); } else if (is_ftdx3000 || is_ftdx1200 || is_ft2000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "CO01%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; int raw_value = atoi(ret_data); if (is_ftdx101d || is_ftdx101mp || is_ftdx10 || is_ft991 || is_ft891) { *freq = raw_value; } else if (is_ftdx5000 || is_ftdx3000 || is_ftdx1200 || is_ft2000) { *freq = raw_value * 100; } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(RIG_OK); } static int newcat_set_contour_level(RIG *rig, vfo_t vfo, int level) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030202%+03d%c", level, cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030205%+03d%c", level, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%+03d%c", level, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1202%+03d%c", level, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%+03d%c", level, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX108%+03d%c", level, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour_level(RIG *rig, vfo_t vfo, int *level) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030202%c", cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030205%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX112%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1202%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX108%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *level = atoi(ret_data); RETURNFUNC2(RIG_OK); } static int newcat_set_contour_width(RIG *rig, vfo_t vfo, int width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030203%02d%c", width, cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030206%02d%c", width, cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%02d%c", width, cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1203%02d%c", width, cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX114%02d%c", width, cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX109%02d%c", width, cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } RETURNFUNC2(newcat_set_cmd(rig)); } static int newcat_get_contour_width(RIG *rig, vfo_t vfo, int *width) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; int ret_data_len; char *ret_data; if (!newcat_valid_command(rig, "EX")) { RETURNFUNC2(-RIG_ENAVAIL); } if (is_ftdx101d || is_ftdx101mp || is_ftdx10) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030203%c", cat_term); } else if (is_ft710) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX030206%c", cat_term); } else if (is_ft991) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX113%c", cat_term); } else if (is_ft891) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX1203%c", cat_term); } else if (is_ftdx5000) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX114%c", cat_term); } else if (is_ftdx3000 || is_ftdx1200) { SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "EX109%c", cat_term); } else { RETURNFUNC2(-RIG_ENIMPL); } if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } ret_data_len = strlen(priv->ret_data); /* skip command */ ret_data = priv->ret_data + strlen(priv->cmd_str) - 1; rig_debug(RIG_DEBUG_TRACE, "%s: ret_data='%s'\n", __func__, ret_data); /* chop term */ priv->ret_data[ret_data_len - 1] = '\0'; *width = atoi(ret_data); RETURNFUNC2(RIG_OK); } int newcat_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { int retval = RIG_OK; int err; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "DT")) { RETURNFUNC2(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT0%04d%02d%02d%c", year, month, day, cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC2(err); } if (hour < 0) { RETURNFUNC2(RIG_OK); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT1%02d%02d%02d%c", hour, min, sec, cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC2(err); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT2%c%04d%c", utc_offset >= 0 ? '+' : '-', utc_offset, cat_term); if (RIG_OK != (err = newcat_set_cmd(rig))) { rig_debug(RIG_DEBUG_VERBOSE, "%s:%d command err = %d\n", __func__, __LINE__, err); RETURNFUNC2(err); } RETURNFUNC2(retval); } int newcat_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int retval = RIG_OK; int err; int n; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; if (!newcat_valid_command(rig, "DT")) { RETURNFUNC2(-RIG_ENAVAIL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT0%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } n = sscanf(priv->ret_data, "DT0%04d%02d%02d", year, month, day); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: DT0 unable to parse '%s'\n", __func__, priv->ret_data); RETURNFUNC2(-RIG_EPROTO); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT1%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } n = sscanf(priv->ret_data, "DT1%02d%02d%02d", hour, min, sec); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: DT1 unable to parse '%s'\n", __func__, priv->ret_data); RETURNFUNC2(-RIG_EPROTO); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "DT2%c", cat_term); if ((err = newcat_get_cmd(rig)) != RIG_OK) { RETURNFUNC2(err); } // we keep utc_offset in HHMM format rather than converting n = sscanf(priv->ret_data, "DT2%d", utc_offset); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: DT2 unable to parse '%s'\n", __func__, priv->ret_data); RETURNFUNC2(-RIG_EPROTO); } RETURNFUNC2(retval); } hamlib-4.6.2/rigs/yaesu/Android.mk0000644000175000017500000000112014752216205013701 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ft100.c ft747.c ft817.c ft847.c ft890.c ft900.c ft920.c \ ft1000mp.c ft857.c ft897.c ft990.c frg8800.c \ ft757gx.c ft736.c frg100.c frg9600.c ft1000d.c \ vr5000.c ft767gx.c ft840.c ft980.c vx1700.c \ newcat.c ft450.c ft950.c ft2000.c ft9000.c ft5000.c \ ft1200.c ft991.c ft600.c ft3000.c ftdx101.c ftdx101mp.c \ ft891.c ftdx10.c \ yaesu.c LOCAL_MODULE := yaesu LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/yaesu/ft450.c0000644000175000017500000002155614752216205013015 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft450.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-450 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft450.h" /* * FT-450 rig capabilities */ struct rig_caps ft450_caps = { RIG_MODEL(RIG_MODEL_FT450), .model_name = "FT-450", .mfg_name = "Yaesu", .version = NEWCAT_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT450_WRITE_DELAY, .post_write_delay = FT450_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT450_FUNCS, .has_set_func = FT450_FUNCS, .has_get_level = FT450_LEVELS, .has_set_level = RIG_LEVEL_SET(FT450_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_VOXGAIN #define NO_LVL_NR #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_VOXGAIN #undef NO_LVL_NR [LVL_CWPITCH] = { .min = { .i = 400 }, .max = { .i = 800 }, .step = { .i = 100 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 11.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(1000), .agc_level_count = 4, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT450_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 450 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT450_RFPOWER_METER_CAL, .str_cal = FT450_STR_CAL, .chan_list = { { 1, 500, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 501, 504, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 1, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(60), FT450_ALL_RX_MODES, -1, -1, FT450_VFO_ALL, FT450_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_HF(1, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ FRQ_RNG_6m(1, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_6m(1, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT450_ALL_RX_MODES, -1, -1, FT450_VFO_ALL, FT450_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_HF(2, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ FRQ_RNG_6m(2, FT450_OTHER_TX_MODES, W(5), W(100), FT450_VFO_ALL, FT450_ANTS), FRQ_RNG_6m(2, FT450_AM_TX_MODES, W(2), W(25), FT450_VFO_ALL, FT450_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT450_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT450_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT450_AM_RX_MODES, Hz(100)}, /* Normal */ {FT450_AM_RX_MODES, kHz(1)}, /* Fast */ {FT450_FM_RX_MODES, Hz(100)}, /* Normal */ {FT450_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT450_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FT450_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FT450_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(6000)}, /* Normal AM */ {RIG_MODE_AM, Hz(3000)}, /* Narrow AM */ {FT450_FM_RX_MODES, Hz(12000)}, /* Normal FM */ {FT450_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 40, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft450d_caps; hamlib-4.6.2/rigs/yaesu/ft817.h0000644000175000017500000000520414752216205013021 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * Then, Tommi OH2BNS improved the code a lot in the framework of the * FT-857 backend. These improvements have now (August 2005) been * copied back and adopted for the FT-817. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT817_H #define _FT817_H 1 /* * No need to wait between written characters. */ #define FT817_WRITE_DELAY 1 /* * Wait 'delay' milliseconds after writing a command sequence. * * Setting this to zero means no delay but wait for an acknowledgement * from the rig after a command. This is undocumented but seems to work. * It's also the most optimal way as long as it works... * * A non-zero value disables waiting for the ack. Processing a command * seems to take about 60 ms so set this to 80 or so to be safe. */ #define FT817_POST_WRITE_DELAY 0 /* * Read timeout. */ #define FT817_TIMEOUT 3000 /* * Return from TX to RX may have a delay. If status is not changed * on the first attempt, wait this amount of milliseconds before * each next next attempts. */ #define FT817_RETRY_DELAY 100 /* * The time the TX, RX and FREQ/MODE status are cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is deliberately set lower than the time taken to process * a single command (~ 60 ms) so that a sequence * * rig_get_freq(); * rig_set_freq(); * rig_get_freq(); * * doesn't return a bogus (cached) value in the last rig_get_freq(). */ #define FT817_CACHE_TIMEOUT 50 int ft817_set_powerstat(RIG *rig, powerstat_t status); int ft817_read_ack(RIG *rig); #endif /* _FT817_H */ hamlib-4.6.2/rigs/yaesu/ftdx101.h0000644000175000017500000001502414752216205013340 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx101.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Mikael Nousiainen 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX101(D/MP) using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FTDX101_H #define _FTDX101_H 1 #define FTDX101_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) /* Receiver caps */ #define FTDX101_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX101_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX101_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FTDX101_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FTDX101_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX101_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) /* 100 W class */ #define FTDX101_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FTDX101_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_TEMP_METER|\ RIG_LEVEL_BAND_SELECT|RIG_LEVEL_USB_AF) #define FTDX101_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF|\ RIG_FUNC_SYNC) /* TBC */ #define FTDX101_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) #define FTDX101D_RFPOWER_METER_CAL \ { \ 6, \ { \ {0, 0.0f}, \ {38, 0.5f}, \ {94, 0.25f}, \ {147, 0.50f}, \ {176, 0.75f}, \ {205, 1.0f}, \ } \ } #define FTDX101D_RFPOWER_METER_WATTS_CAL \ { \ 6, \ { \ {0, 0.0f}, \ {38, 5.0f}, \ {94, 25.0f}, \ {147, 50.0f}, \ {176, 75.0f}, \ {205, 100.0f}, \ } \ } #define FTDX101MP_RFPOWER_METER_CAL \ { \ 11, \ { \ {0, 0.00f}, \ {69, 0.05f}, \ {111, 0.10f}, \ {129, 0.15f}, \ {143, 0.20f}, \ {158, 0.25f}, \ {184, 0.35f}, \ {200, 0.40f}, \ {211, 0.45f}, \ {222, 0.50f}, \ {255, 1.0f}, \ } \ } #define FTDX101MP_RFPOWER_METER_WATTS_CAL \ { \ 13, \ { \ {0, 0.0f}, \ {30, 5.0f}, \ {69, 20.0f}, \ {98, 40.0f}, \ {119, 60.0f}, \ {139, 80.0f}, \ {160, 100.0f}, \ {173, 120.0f}, \ {185, 140.0f}, \ {198, 160.0f}, \ {210, 180.0f}, \ {225, 200.0f}, \ {255, 210.0f}, \ } \ } // Based on testing with G3VPX Ian Sumner #define FTDX101D_SWR_CAL \ { \ 8, \ { \ {0, 1.0f}, \ {26, 1.2f}, \ {52, 1.5f}, \ {89, 2.0f}, \ {126, 3.0f}, \ {173, 4.0f}, \ {236, 5.0f}, \ {255, 25.0f}, \ } \ } #define FTDX101D_STR_CAL { 12, \ { \ { 0, -60 }, /* S0 */ \ { 17, -54 }, /* S0 */ \ { 25, -48 }, \ { 34, -42 }, \ { 51, -36 }, \ { 68, -30 }, \ { 85, -24 }, \ { 102, -18 }, \ { 119, -12 }, \ { 136, -6 }, \ { 160, 0 }, /* S9 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) */ #define FTDX101_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) #define FTDX101_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX101_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX101_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX101_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX101_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX101_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ /* Delay between bytes sent * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FTDX101_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX101_POST_WRITE_DELAY 5 #endif /* _FTDX101_H */ hamlib-4.6.2/rigs/yaesu/frg100.c0000644000175000017500000004107114752216205013144 00000000000000/* * frg100.c - (C) Stephane Fillod 2002-2005 * * This shared library provides an API for communicating * via serial interface to an FRG-100 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "frg100.h" enum frg100_native_cmd_e { FRG100_NATIVE_RECALL_MEM = 0, /* 0x02, p1=ch */ FRG100_NATIVE_VFO_TO_MEM, /* 0x03, p1=ch, p2=0 */ FRG100_NATIVE_MEM_HIDE, /* 0x03, p1=ch, p2=1 */ FRG100_NATIVE_VFO_A, /* 0x05 */ FRG100_NATIVE_FREQ_SET, /* 0x0a, p1:4=freq */ FRG100_NATIVE_MODE_SET_LSB, /* 0x0c, p1=0x00 */ FRG100_NATIVE_MODE_SET_USB, /* 0x0c, p1=0x01 */ FRG100_NATIVE_MODE_SET_CW_W, /* 0x0c, p1=0x02 */ FRG100_NATIVE_MODE_SET_CW_N, /* 0x0c, p1=0x03 */ FRG100_NATIVE_MODE_SET_AM, /* 0x0c, p1=0x04 */ FRG100_NATIVE_MODE_SET_RTTY_LSB_W, /* 0x0c, p1=0x08 */ FRG100_NATIVE_MODE_SET_RTTY_USB_W, /* 0x0c, p1=0x09 */ FRG100_NATIVE_MODE_SET_H3E, /* 0x0c, p1=0x0d */ FRG100_NATIVE_MODE_SET_RTTY_LSB_N, /* 0x0c, p1=0x0e */ FRG100_NATIVE_MODE_SET_RTTY_USB_N, /* 0x0c, p1=0x0f */ FRG100_NATIVE_PTT_OFF, /* 0x0f, p1=0 */ FRG100_NATIVE_PTT_ON, /* 0x0f, p1=1 */ FRG100_NATIVE_UPDATE_MEM_CHNL, /* 0x10, p1=1 */ FRG100_NATIVE_UPDATE_OP_DATA, /* 0x10, p1=2 */ FRG100_NATIVE_UPDATE_VFO_DATA, /* 0x10, p1=3 */ FRG100_NATIVE_TX_POWER_LOW, /* 0x18 */ FRG100_NATIVE_TX_POWER_MID, /* 0x28 */ FRG100_NATIVE_TX_POWER_HI, /* 0x48 */ FRG100_NATIVE_CPY_RX_TO_TX, /* 0x85 */ FRG100_NATIVE_TX_FREQ_SET, /* 0x8a, p1:4=freq */ FRG100_NATIVE_OP_FREQ_STEP_UP, /* 0x8e, p1=0 */ FRG100_NATIVE_OP_FREQ_STEP_DOWN, /* 0x8e, p1=1 */ FRG100_NATIVE_READ_METER, /* 0xf7 */ FRG100_NATIVE_READ_FLAGS, /* 0xfa */ FRG100_NATIVE_SIZE }; #define FRG100_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM) #define FRG100_VFOS (RIG_VFO_A) #define FRG100_ANTS 0 /* TODO: get real measure numbers */ #define FRG100_STR_CAL { 2, { \ { 0, -60 }, /* S0 -6dB */ \ { 60, 60 } /* +60 */ \ } } #define FRG100_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1 \ } static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* VFO to MEM */ { 0, { 0x00, 0x00, 0x01, 0x00, 0x03 } }, /* Hide Memory Channel */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW-W */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW-N */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB-W */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB-W */ { 1, { 0x00, 0x00, 0x00, 0x0d, 0x0c } }, /* OP Mode Set H3E */ { 1, { 0x00, 0x00, 0x00, 0x0e, 0x0c } }, /* OP Mode Set RTTY LSB-N */ { 1, { 0x00, 0x00, 0x00, 0x0f, 0x0c } }, /* OP Mode Set RTTY USB-N */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x18 } }, /* Set TX power low */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x28 } }, /* Set TX power mid */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x48 } }, /* Set TX power hi */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy RX to TX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* Set TX Freq only */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8e } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8e } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* Private helper function prototypes */ static int frg100_open(RIG *rig); static int frg100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int frg100_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int frg100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int frg100_set_vfo(RIG *rig, vfo_t vfo); static int frg100_set_powerstat(RIG *rig, powerstat_t status); static int frg100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #if 0 static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width); #endif static int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width); /* * frg100 rigs capabilities. * Also this struct is READONLY! * * TODO: * - Memory recall * - VFO->M & M->VFO * - Lock, Up/Down * - Status update * - Clock set, Timer * - Scan skip * - Step Frequency Size * - Dim */ struct rig_caps frg100_caps = { RIG_MODEL(RIG_MODEL_FRG100), .model_name = "FRG-100", .mfg_name = "Yaesu", .version = "20160409.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 20, .post_write_delay = 300, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 0x32, RIG_MTYPE_MEM, FRG100_MEM_CAP }, { 0x33, 0x34, RIG_MTYPE_EDGE }, }, .rx_range_list1 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { {kHz(50), MHz(30), FRG100_MODES, 0, 0, FRG100_VFOS, FRG100_ANTS }, RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, Hz(10)}, {RIG_MODE_FM | RIG_MODE_AM, Hz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(4)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = FRG100_STR_CAL, .rig_open = frg100_open, .get_freq = frg100_get_freq, .set_freq = frg100_set_freq, .set_mode = frg100_set_mode, .set_vfo = frg100_set_vfo, .get_level = frg100_get_level, .set_powerstat = frg100_set_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static inline int frg100_channel_is_ok(unsigned char channel) { return ((channel >= FRG100_MIN_CHANNEL) && (channel <= FRG100_MAX_CHANNEL)) ? 1 : 0; } static int frg100_do_transaction(RIG *rig, const unsigned char cmd[YAESU_CMD_LENGTH], unsigned char *retbuf, size_t retbuf_len) { hamlib_port_t *rp = RIGPORT(rig); unsigned char default_retbuf[1]; int retval; if (retbuf == NULL) { retbuf = default_retbuf; retbuf_len = sizeof(default_retbuf); } memset(retbuf, 0, retbuf_len); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } retval = read_block(rp, retbuf, retbuf_len); if (retval != retbuf_len) { if ((retval == 1) && (retbuf[0] == FRG100_CMD_RETCODE_ERROR)) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retval == 1) { if ((cmd[4] == FRG100_CMD_UPDATE) && (cmd[3] == 0x01)) { /* read memory channel number */ if (frg100_channel_is_ok(retbuf[0] + 1)) { /* WARNING: Documentation bug, actually we got 0--199 for channels 1--200 */ return RIG_OK; } if (retbuf[0] == FRG100_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retbuf[0] == FRG100_CMD_RETCODE_OK) { return RIG_OK; } if (retbuf[0] == FRG100_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } return RIG_OK; } static inline freq_t frg100_read_freq_from_buf(const unsigned char p[]) { /* WARNING: documentation bug, actually frequency stored in bytes 0..2 only, byte 3 is not used and contain zero */ return ((((((unsigned)p[2]) << 8) + p[1]) << 8) + p[0]) * 10.0; } static inline int frg100_read_op_data_raw(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return frg100_do_transaction(rig, ncmd[FRG100_NATIVE_UPDATE_OP_DATA].nseq, reply, FRG100_OP_DATA_LENGTH); } static int frg100_read_op_data(RIG *rig, unsigned char *hwmode, freq_t *rx_freq, freq_t *tx_freq) { int ret; unsigned char reply[FRG100_OP_DATA_LENGTH]; if ((ret = frg100_read_op_data_raw(rig, reply)) != RIG_OK) { return ret; } if (hwmode != NULL) { *hwmode = reply[7]; } if (rx_freq != NULL) { *rx_freq = frg100_read_freq_from_buf(reply + 2); } if (tx_freq != NULL) { *tx_freq = frg100_read_freq_from_buf(reply + 11); } return RIG_OK; } /* * frg100_open routine * */ int frg100_open(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0e}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* send 0 delay pacing */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { (void) vfo; return frg100_read_op_data(rig, NULL, freq, NULL); } int frg100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0a}; /* store bcd format in cmd (LSB) */ to_bcd(cmd, freq / 10, 8); /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0c}; /* fill in p1 */ cmd[3] = mode2rig(rig, mode, width); return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } /* * Actually, this is tape relay, 0xfe=on */ int frg100_set_powerstat(RIG *rig, powerstat_t status) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x20}; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cmd[3] = status == RIG_POWER_OFF ? 0x00 : 0x01; /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_VFO: case RIG_VFO_A: cmd[4] = 0x05; break; case RIG_VFO_MEM: /* TODO: cmd[3] = priv->current_mem_chan; */ cmd[4] = 0x02; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int frg100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xf7}; int retval; hamlib_port_t *rp = RIGPORT(rig); if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 5); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0]; return RIG_OK; } #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CWW 0x02 #define MODE_CWN 0x03 #define MODE_AMW 0x04 #define MODE_AMN 0x05 #define MODE_FMW 0x06 #define MODE_FMN 0x07 int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width) { int md; /* * translate mode from generic to frg100 specific */ switch (mode) { case RIG_MODE_USB: md = MODE_USB; break; case RIG_MODE_LSB: md = MODE_LSB; break; case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && (width != RIG_PASSBAND_NORMAL || width < rig_passband_normal(rig, mode))) { md = MODE_AMN; } else { md = MODE_AMW; } break; case RIG_MODE_FM: if (width != RIG_PASSBAND_NOCHANGE && (width != RIG_PASSBAND_NORMAL || width < rig_passband_normal(rig, mode))) { md = MODE_FMN; } else { md = MODE_FMW; } break; case RIG_MODE_CW: if (width != RIG_PASSBAND_NOCHANGE && (width != RIG_PASSBAND_NORMAL || width < rig_passband_normal(rig, mode))) { md = MODE_CWN; } else { md = MODE_CWW; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } /* function not used */ #if 0 int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width) { /* * translate mode from frg100 specific to generic */ switch (md) { case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_AMW: case MODE_AMN: *mode = RIG_MODE_AM; break; case MODE_FMW: case MODE_FMN: *mode = RIG_MODE_FM; break; case MODE_CWW: case MODE_CWN: *mode = RIG_MODE_CW; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (md == MODE_CWN || md == MODE_AMN || md == MODE_FMN) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } #endif hamlib-4.6.2/rigs/yaesu/ft710.h0000644000175000017500000001412414752216205013012 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * FT710.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Michael Black W9MDB 2020 * (C) Mikael Nousiainen 2023 * * This shared library provides an API for communicating * via serial interface to an FT-710 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT710_H #define _FT710_H 1 #define FT710_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT710_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FT710_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT710_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FT710_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN|RIG_MODE_PKTFMN) #define FT710_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT710_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_PKTFMN) /* 100 W class */ #define FT710_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ #define FT710_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT710_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_APF) /* TBC */ #define FT710_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT710_RFPOWER_METER_CAL \ { \ 5, \ { \ {27, 5.0f}, \ {94, 25.0f}, \ {147, 50.0f}, \ {176, 75.0f}, \ {205, 100.0f}, \ } \ } // Based on testing with G3VPX Ian Sumner for the FT7101D #define FT710_SWR_CAL \ { \ 8, \ { \ {0, 1.0f}, \ {26, 1.2f}, \ {52, 1.5f}, \ {89, 2.0f}, \ {126, 3.0f}, \ {173, 4.0f}, \ {236, 5.0f}, \ {255, 25.0f}, \ } \ } /* TBC */ #define FT710_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } #define FT710_ID_CAL { 7, \ { \ { 0, 0.0f }, \ { 53, 5.0f }, \ { 65, 6.0f }, \ { 78, 7.0f }, \ { 86, 8.0f }, \ { 98, 9.0f }, \ { 107, 10.0f } \ } \ } /* TBC */ #define FT710_VD_CAL { 2, \ { \ { 0, 0.0f }, \ { 192, 13.8f }, \ } \ } #define FT710_COMP_CAL { 9, \ { \ { 0, 0.0f }, \ { 40, 2.5f }, \ { 60, 5.0f }, \ { 85, 7.5f }, \ { 135, 10.0f }, \ { 150, 12.5f }, \ { 175, 15.0f }, \ { 195, 17.5f }, \ { 220, 20.0f } \ } \ } /* * Other features (used by rig_caps) */ #define FT710_TX_ANTS RIG_ANT_CURR #define FT710_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT710_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT710_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT710_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT710_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT710_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ /* Delay between bytes sent * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT710_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT710_POST_WRITE_DELAY 5 #endif /* _FT710_H */ hamlib-4.6.2/rigs/yaesu/frg100.h0000644000175000017500000000236214752216205013151 00000000000000/* * frg100.h - (C) Michael Black 2016 * * This shared library provides an API for communicating * via serial interface to an FRG-100 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #define FRG100_OP_DATA_LENGTH 19 /* 0x10 p1=02 return size */ #define FRG100_CMD_UPDATE 0x10 #define FRG100_MIN_CHANNEL 1 #define FRG100_MAX_CHANNEL 200 // Return codes #define FRG100_CMD_RETCODE_OK 0x00 #define FRG100_CMD_RETCODE_ERROR 0xF0 hamlib-4.6.2/rigs/yaesu/vr5000.c0000644000175000017500000004307414752216205013106 00000000000000/* * vr5000.c - (C) Stephane Fillod and Jacob Heder 2005 * * This shared library provides an API for communicating * via serial interface to an VR-5000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Undocumented notes on the VR5000. * * There are some mishaps in the manual. The CAT serial delay times seems * not to be correct. More correct estimates are 70 mS write_delay ( * between bytes), 200 mS post_write_delay (between command), but when * reading s-meter, the delay must be over 500 mS. * * The read s-meter CAT command seems only to return 17 to 23 depending * on the strength of the signal. Setting the RF attenuator on with no * attenna on does not decrease the level below 17. If you wish to read * the s-meter on a specific frequency, set the frequency and wait a * 500-1000 mS before reading it. * The vr5000 has two vfo, but only 1 native. The second vfo is a following * vfo which only can tune into the frequency range of VFO_A (+,-) 20 Mhz. * * The vr5000 has no CAT commands for reading the frequency, ts nor mode. * These function are emulated, because the vr5000 thunkates the input * frequency. Secondly when changing the mode, ts will change, and since * ts it the one that decides how the frequency is thunkated, the frequency * will change. * * True receiver range was not specified correctly in manual. No all * mode allow to go down to 100 Khz. Therefore the minimum frequency * which will be allowed is 101.5 kKz. Maximum is 2599.99 Mhz. * * * Supported : VFO_A, 101.5 Khz to 2599.99 Mhz. */ // cppcheck-suppress * #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #define VR5000_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_WFM) #define VR5000_VFOS RIG_VFO_A #define VR5000_ANTS 0 #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x04 #define MODE_AMW 0x44 #define MODE_AMN 0x84 #define MODE_WFM 0x48 #define MODE_FMN 0x88 #define SAFETY_WRITE_DELAY 70 /* security value for beta version, ok to set lower later */ #define SAFETY_POST_DELAY 210 /* security value for beta version, */ /* TODO: get real measure numbers */ #define VR5000_STR_CAL { 2, { \ { 0, -60 }, /* S0 -6dB */ \ { 63, 60 } /* +60 */ \ } } /* Private helper function prototypes */ static int vr5000_init(RIG *rig); static int vr5000_cleanup(RIG *rig); static int vr5000_open(RIG *rig); static int vr5000_close(RIG *rig); static int vr5000_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int vr5000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int vr5000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int vr5000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int vr5000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int vr5000_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int vr5000_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int vr5000_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); /* * Private helper function prototypes. */ static int set_vr5000(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width, shortfreq_t ts); static int mode2rig(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static void correct_frequency(RIG *rig, vfo_t vfo, freq_t curr_freq, freq_t *freq); static int find_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t *ts); static int check_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t ts); /* * vr5000 rigs capabilities. */ struct rig_caps vr5000_caps = { RIG_MODEL(RIG_MODEL_VR5000), .model_name = "VR-5000", .mfg_name = "Yaesu", .version = "20200505.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = SAFETY_WRITE_DELAY, .post_write_delay = SAFETY_POST_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { }, .rx_range_list1 = { {kHz(101) + 500, GHz(2.6) - 1000, VR5000_MODES, -1, -1, RIG_VFO_A, VR5000_ANTS }, RIG_FRNG_END, }, /* api supported region 1 rx ranges */ .tx_range_list1 = { RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {kHz(101) + 500, GHz(2.6) - 1000, VR5000_MODES, -1, -1, RIG_VFO_A, VR5000_ANTS }, RIG_FRNG_END, }, /* api supported region 2 rx ranges */ .tx_range_list2 = { RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW, Hz(20)}, {RIG_MODE_SSB | RIG_MODE_CW, Hz(100)}, {RIG_MODE_SSB | RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM | RIG_MODE_SSB | RIG_MODE_CW, kHz(1)}, {RIG_MODE_FM | RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(100)}, {RIG_MODE_AM | RIG_MODE_WFM | RIG_MODE_FM, kHz(500)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .str_cal = VR5000_STR_CAL, .rig_init = vr5000_init, .rig_cleanup = vr5000_cleanup, .rig_open = vr5000_open, .rig_close = vr5000_close, .get_level = vr5000_get_level, .get_dcd = vr5000_get_dcd, .set_freq = vr5000_set_freq, .get_freq = vr5000_get_freq, .set_mode = vr5000_set_mode, .get_mode = vr5000_get_mode, .set_ts = vr5000_set_ts, .get_ts = vr5000_get_ts, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * VR-5000 backend needs priv data to handle composite cmds */ struct vr5000_priv_data { vfo_t curr_vfo; shortfreq_t curr_ts; freq_t curr_freq; rmode_t curr_mode; pbwidth_t curr_width; }; int vr5000_init(RIG *rig) { STATE(rig)->priv = (struct vr5000_priv_data *) calloc(1, sizeof(struct vr5000_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } int vr5000_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * vr5000_open : Set CAT on and set tuner into known mode */ int vr5000_open(RIG *rig) { struct vr5000_priv_data *priv = STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; const unsigned char b_off[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x31}; int retval; /* CAT write command on */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } /* disable RIG_VFO_B (only on display) */ retval = write_block(rp, b_off, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } /* set RIG_VFO_A to 10 Mhz normal AM, step 10 kHz */ priv->curr_vfo = RIG_VFO_A; priv->curr_mode = RIG_MODE_WFM; priv->curr_width = RIG_PASSBAND_NORMAL; priv->curr_ts = kHz(10); priv->curr_freq = kHz(10000); retval = set_vr5000(rig, priv->curr_vfo, priv->curr_freq, priv->curr_mode, priv->curr_width, priv->curr_ts); if (retval != RIG_OK) { return retval; } return RIG_OK; } int vr5000_close(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x80}; return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int vr5000_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct vr5000_priv_data *priv = STATE(rig)->priv; return set_vr5000(rig, vfo, freq, priv->curr_mode, priv->curr_width, priv->curr_ts); } int vr5000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { const struct vr5000_priv_data *priv = STATE(rig)->priv; *freq = priv->curr_freq; return RIG_OK; } int vr5000_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct vr5000_priv_data *priv = STATE(rig)->priv; if (check_tuning_step(rig, vfo, mode, priv->curr_ts) != RIG_OK) { find_tuning_step(rig, vfo, mode, &priv->curr_ts); } priv->curr_mode = mode; return set_vr5000(rig, vfo, priv->curr_freq, mode, width, priv->curr_ts); } int vr5000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct vr5000_priv_data *priv = STATE(rig)->priv; *mode = priv->curr_mode; *width = priv->curr_width; return RIG_OK; } int vr5000_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { struct vr5000_priv_data *priv = STATE(rig)->priv; int retval; retval = check_tuning_step(rig, vfo, priv->curr_mode, ts); if (retval != RIG_OK) { return retval; } priv->curr_ts = ts; return set_vr5000(rig, vfo, priv->curr_freq, priv->curr_mode, priv->curr_width, ts); } int vr5000_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { const struct vr5000_priv_data *priv = STATE(rig)->priv; *ts = priv->curr_ts; return RIG_OK; } int vr5000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xe7}; int retval; hamlib_port_t *rp = RIGPORT(rig); if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 1); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0] & 0x3f; rig_debug(RIG_DEBUG_ERR, "Read(%x) RawValue(%x): \n", cmd[0], val->i); return RIG_OK; } int vr5000_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xe7}; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 1); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } *dcd = (cmd[0] & 0x80) ? RIG_DCD_ON : RIG_DCD_OFF; return RIG_OK; } int mode2rig(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int md; /* * translate mode from generic to vr5000 specific */ switch (mode) { case RIG_MODE_USB: md = MODE_USB; break; case RIG_MODE_LSB: md = MODE_LSB; break; case RIG_MODE_CW: md = MODE_CW; break; case RIG_MODE_WFM: md = MODE_WFM; break; case RIG_MODE_FM: md = MODE_FMN; break; case RIG_MODE_AM: if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md = MODE_AMN; } else if (width != RIG_PASSBAND_NORMAL && width > rig_passband_normal(rig, mode)) { md = MODE_AMW; } else { md = MODE_AM; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } /* * This function corrects the frequency */ void correct_frequency(RIG *rig, vfo_t vfo, freq_t curr_freq, freq_t *freq) { const struct vr5000_priv_data *priv = STATE(rig)->priv; shortfreq_t ts = priv->curr_ts; unsigned long long correct_freq = (unsigned long long)curr_freq; /* RIG_VFO_A frequency correction */ if (correct_freq % ts != 0) { if ((correct_freq % ts) > (ts >> 1)) { correct_freq += (ts - (correct_freq % ts)); } else { correct_freq -= (correct_freq % ts); } } /* Check for frequencies out on true rx range */ if ((freq_t)correct_freq < rig->caps->rx_range_list1->startf) { correct_freq = (unsigned long long)rig->caps->rx_range_list1->startf; if (correct_freq % ts != 0) { correct_freq += (ts - (correct_freq % ts)); } } else if ((freq_t)correct_freq > rig->caps->rx_range_list1->endf) { correct_freq = (unsigned long long)rig->caps->rx_range_list1->endf; if (correct_freq % ts != 0) { correct_freq -= (correct_freq % ts); } } *freq = (freq_t) correct_freq; return; } /* * Set mode and ts, then frequency. Both mode/ts and frequency are set * every time one of them changes. */ int set_vr5000(RIG *rig, vfo_t vfo, freq_t freq, rmode_t mode, pbwidth_t width, shortfreq_t ts) { struct vr5000_priv_data *priv = STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char cmd_mode_ts[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x07}; unsigned char cmd_freq[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01}; static const unsigned char steps[] = { 0x21, 0x42, 0x02, 0x03, 0x43, 0x53, 0x63, 0x04, 0x14, 0x24, 0x35, 0x44, 0x05, 0x45 }; unsigned int frq; int retval; int i; if (vfo == RIG_VFO_CURR) { vfo = priv->curr_vfo; } retval = mode2rig(rig, vfo, mode, width); if (retval < 0) { return retval; } /* fill in m1 */ cmd_mode_ts[0] = retval; for (i = 0; i < sizeof(steps); i++) { if (rig->caps->tuning_steps[i].ts == ts) { break; } } if (i >= sizeof(steps)) { return -RIG_EINVAL; /* not found, unsupported */ } /* fill in m2 */ cmd_mode_ts[1] = steps[i]; retval = write_block(rp, cmd_mode_ts, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } /* Correct frequency */ correct_frequency(rig, vfo, freq, &freq); priv->curr_freq = freq; frq = (unsigned int)(freq / 10); cmd_freq[0] = (frq >> 24) & 0xff; cmd_freq[1] = (frq >> 16) & 0xff; cmd_freq[2] = (frq >> 8) & 0xff; cmd_freq[3] = frq & 0xff; /* frequency set */ return write_block(rp, cmd_freq, YAESU_CMD_LENGTH); } /* * find_tuning_step : return the lowest ts for a giving mode */ int find_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t *ts) { int i; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if ((rig->caps->tuning_steps[i].modes & mode) != 0) { *ts = rig->caps->tuning_steps[i].ts; return RIG_OK; } } return -RIG_EINVAL; /* not found, unsupported */ } /* * check_tuning_step : return RIG_OK if this ts is supported by the mode */ int check_tuning_step(RIG *rig, vfo_t vfo, rmode_t mode, shortfreq_t ts) { int i; for (i = 0; i < HAMLIB_TSLSTSIZ; i++) { if (rig->caps->tuning_steps[i].ts == ts && ((rig->caps->tuning_steps[i].modes & mode) != 0)) { return RIG_OK; } } return -RIG_EINVAL; /* not found, unsupported */ } hamlib-4.6.2/rigs/yaesu/ft980.h0000644000175000017500000003521414752216205013026 00000000000000/* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft980.h - (C) Mat Breton, 2020 * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* This file is a bit of a hack at the moment, containing both public and private declarations * ToDo: Fix this point later, but temporarily necessary to sort stuff out right now */ #ifndef _FT980_H #define _FT980_H 1 /* Lets make the Linters Happy - remove later*/ #ifndef _RIG_H #include "hamlib/rig.h" #endif #ifndef _YAESU_H #include "yaesu.h" #endif #ifndef _BANDPLAN_H #include "bandplan.h" #endif /* End of Happy Linter Section */ /************************************************************************************* * Semi-Public prototypes: need to be placed before the caps construct * HAMLIB API implementation */ static int ft980_init(RIG *rig); static int ft980_cleanup(RIG *rig); static int ft980_open(RIG *rig); static int ft980_close(RIG *rig); static int ft980_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft980_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft980_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft980_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft980_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft980_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft980_set_vfo(RIG *rig, vfo_t vfo); static int ft980_get_vfo(RIG *rig, vfo_t *vfo); #if 0 static int ft980_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft980_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft980_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft980_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft980_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft980_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft980_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft980_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft980_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); #endif /************************************************************************************* * Constants (enums and defines, w/ a couple typedefs thrown in) */ /* Handy constants */ #ifndef TRUE #define TRUE 1 #endif #define ON TRUE #ifndef FALSE #define FALSE 0 #endif #define OFF FALSE /* FT-980 Status Return Message Lengths */ #define FT980_ALL_STATUS_LENGTH 148 #define FT980_OTHER_STATUS_LENGTH 22 #define FT980_RPTRSPLT_STATUS_LENGTH 6 #define FT980_UPDN_STATUS_LENGTH 5 #define FT980_ONEBYTE_STATUS_LENGTH 1 /* FT-980 Timing Constants (for caps structure)*/ /* Serial write timing values, in mS */ #define FT980_WRITE_DELAY 80 /* Delay sequential fast writes */ #define FT980_POST_WRITE_DELAY 5 /* Serial write timing values, in mS */ #define FT980_PACING_INTERVAL 5 /* The following may be deprecated into rig.c cache with 4.1 release*/ #define FT980_CACHE_TIMEOUT 500 /* Rough safe value for default read timeout = # bytes x (xmit speed + pacing_interval) x safety factor #define FT980_DEFAULT_READ_TIMEOUT FT980_ALL_DATA_LENGTH * ( 1.7 + FT980_PACING_INTERVAL) * 6 */ #define FT980_DEFAULT_READ_TIMEOUT 2000 /* FT-980 Configuration Constants (for caps structure)*/ #define FT980_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_RTTY|RIG_MODE_FM) #define FT980_ANTS (RIG_ANT_1) /* */ #define FT980_VFOS (RIG_VFO_CURR|RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) /* TODO: RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN */ #define FT980_VFO_OPS (RIG_OP_NONE) /* TODO: RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN #define FT890_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) */ /* * ft980 rigs capabilities. * * Protocol is documented in FT 980 Technical Supplement, page 13. * */ #define FT980_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ } struct rig_caps ft980_caps = { RIG_MODEL(RIG_MODEL_FT980), .model_name = "FT-980", .mfg_name = "Yaesu", .version = "20200114.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_SERIAL_RTS, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT980_WRITE_DELAY, .post_write_delay = FT980_POST_WRITE_DELAY, .timeout = FT980_DEFAULT_READ_TIMEOUT, .retry = 3, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = FT980_VFO_OPS, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(10000), .max_xit = Hz(10000), .max_ifshift = Hz(1500), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 16, RIG_MTYPE_MEM, FT980_MEM_CAP}, }, .rx_range_list1 = { {kHz(150), MHz(30) - 100, FT980_MODES, -1, -1, FT980_VFOS, FT980_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, RIG_MODE_SSB | RIG_MODE_CW, W(5), W(100), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(1, RIG_MODE_FM | RIG_MODE_RTTY, W(2), W(50), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(1, RIG_MODE_AM, W(2), W(25), FT980_VFOS, FT980_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30) - 100, FT980_MODES, -1, -1, FT980_VFOS, FT980_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, RIG_MODE_SSB | RIG_MODE_CW, W(5), W(100), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(2, RIG_MODE_FM | RIG_MODE_RTTY, W(2), W(50), FT980_VFOS, FT980_ANTS), FRQ_RNG_HF(2, RIG_MODE_AM, W(2), W(25), FT980_VFOS, FT980_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT980_MODES, Hz(10)}, {FT980_MODES, kHz(5)}, {FT980_MODES, kHz(500)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.5)}, {RIG_MODE_CW, Hz(300)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM, kHz(5)}, {RIG_MODE_AM, kHz(3)}, RIG_FLT_END, }, .rig_init = ft980_init, .rig_cleanup = ft980_cleanup, .rig_open = ft980_open, .rig_close = ft980_close, .set_freq = ft980_set_freq, .get_freq = ft980_get_freq, .set_mode = ft980_set_mode, .get_mode = ft980_get_mode, .set_mem = ft980_set_mem, .get_mem = ft980_get_mem, .get_vfo = ft980_get_vfo, .set_vfo = ft980_set_vfo, #ifdef XXREMOVEDXX .set_split_vfo = ft980_set_split_vfo, .set_split_freq = ft980_set_split_freq, .set_split_mode = ft980_set_split_mode, .set_rptr_shift = ft980_set_rptr_shift, .set_rptr_offs = ft980_set_rptr_offs, #endif }; /* FT-980 Status Return Lengths (for memory structure)*/ #define FT980_ALL_STATUS_LENGTH 148 #define FT980_OTHER_STATUS_LENGTH 22 #define FT980_RPTRSPLT_STATUS_LENGTH 6 #define FT980_UPDN_STATUS_LENGTH 5 #define FT980_ONEBYTE_STATUS_LENGTH 1 /* Do not change the order of the memory structure */ typedef struct _ft980_memory_t { unsigned char mem_16[4]; unsigned char vfo_16; unsigned char mode_16; unsigned char mem_15[4]; unsigned char vfo_15; unsigned char mode_15; unsigned char mem_14[4]; unsigned char vfo_14; unsigned char mode_14; unsigned char mem_13[4]; unsigned char vfo_13; unsigned char mode_13; unsigned char mem_12[4]; unsigned char vfo_12; unsigned char mode_12; unsigned char mem_11[4]; unsigned char vfo_11; unsigned char mode_11; unsigned char mem_10[4]; unsigned char vfo_10; unsigned char mode_10; unsigned char mem_9[4]; unsigned char vfo_9; unsigned char mode_9; unsigned char mem_8[4]; unsigned char vfo_8; unsigned char mode_8; unsigned char mem_7[4]; unsigned char vfo_7; unsigned char mode_7; unsigned char mem_6[4]; unsigned char vfo_6; unsigned char mode_6; unsigned char mem_5[4]; unsigned char vfo_5; unsigned char mode_5; unsigned char mem_4[4]; unsigned char vfo_4; unsigned char mode_4; unsigned char mem_3[4]; unsigned char vfo_3; unsigned char mode_3; unsigned char mem_2[4]; unsigned char vfo_2; unsigned char mode_2; unsigned char mem_1[4]; unsigned char vfo_1; unsigned char mode_1; unsigned char clar_freq[4]; unsigned char gen_vfo_freq[4]; unsigned char ham_vfo_freq[4]; unsigned char vfo; /* ??? */ unsigned char mode; /* ??? */ unsigned char mem_shift_freq[4]; unsigned char mem_clar_freq[4]; unsigned char mem_vfo; unsigned char mem_mode; unsigned char ldb_flag; unsigned char ext_ctl_flag; unsigned char if_shift; unsigned char rptr_split_code; unsigned char fsk_shift; unsigned char if_width; unsigned char mem_shift_flag; unsigned char clar_flag; unsigned char tab_flag; unsigned char freq_select_sws; unsigned char offset_sw; unsigned char mode_sw; unsigned char mem_ch_sw; unsigned char lower_tab_freq[4]; unsigned char upper_tab_freq[4]; unsigned char op_vfo; unsigned char op_mode; unsigned char op_freq[4]; unsigned char status_flag_bits; } _ft980_memory_t; /* * Start of Return Status Code Defines * These are the memory decode define (for the _ft980_memory_structure) */ /* status_flag_bits: STATUS FLAG BYTE BIT decode MASKS */ #define FT_980_STATUSFLAG_TXRX_MASK 0x01 #define FT_980_STATUSFLAG_SPLIT_MASK 0x08 #define FT_980_STATUSFLAG_VFO_MASK 0x20 #define FT_980_STATUSFLAG_UPDN_MASK 0X30 #define FT_980_STATUSFLAG_CLAR_MASK 0x40 /* op_vfo: VFO decode: Main, Gen, and 3 unused AUX */ #define FT980_VFO_HAM_SEL 0x80 #define FT980_VFO_GEN_SEL 0x00 #define FT980_VFO_AUX1_SEL 0x81 #define FT980_VFO_AUX2_SEL 0x82 #define FT980_VFO_AUX3_SEL 0x83 /* freq_select_sws: Frequency source decode, either a VFO, Mem, or Split */ #define FT980_FREQ_SRC_SW_VFO 0x00 #define FT980_FREQ_SRC_SW_MR 0x01 #define FT980_FREQ_SRC_SW_RXM 0x02 #define FT980_FREQ_SRC_SW_RXV 0x03 /* Clarifier Active Decode Masks */ #define FT980_CLAR_RX_FLAG 0x20 #define FT980_CLAR_TX_FLAG 0x40 /* FSK Shift Decode */ #define FT980_FSK_SHIFT_INT 0x00 #define FT980_FSK_SHIFT_425 0x40 #define FT980_FSK_SHIFT_850 0x80 #define FT980_FSK_SHIFT_170 0xC0 /* Repeater Split Codes */ /* TBD: Is this table even needed */ /* * Start of Command Code Defines */ static const unsigned char cmd_OK[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0B}; static const unsigned char cmd_ON_OFF[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; /* Opcodes 00 to 0B */ enum ft980_native_cmd_e { FT980_CMD_TOGGLE_EXT_CNTL = 0x00, FT980_CMD_ALL_STATUS_CHECK = 0x01, FT980_CMD_UP_10HZ = 0x02, FT980_CMD_DN_10HZ = 0x03, FT980_CMD_IF_WIDTH = 0x04, FT980_CMD_IF_SHIFT = 0x05, FT980_CMD_FSK_FREQ = 0x06, FT980_CMD_RPTR_SPLIT_CODE = 0x07, FT980_CMD_FREQ = 0x08, FT980_CMD_LDB_SET = 0x09, FT980_CMD_USER_PROG = 0x0A, FT980_CMD0A_OK_SIGNAL = 0x0B }; /* OpCode command 0x0A byte 3 sub-codes */ /* The first 16 subcodes 00-0F are to command the memory channel */ // Operating Mode Status enum ft980_native_cmd0A_e { FT980_CMD0A_MD_LSB = 0x10, FT980_CMD0A_MD_USB = 0x11, FT980_CMD0A_MD_CW = 0x12, FT980_CMD0A_MD_CWN = 0x13, FT980_CMD0A_MD_AM = 0x14, FT980_CMD0A_MD_AMN = 0x15, FT980_CMD0A_MD_RTTY = 0x16, FT980_CMD0A_MD_FM = 0x17, FT980_CMD0A_SHOW_OFFSET = 0x1B, /* Frequency Source Select */ FT980_CMD0A_FREQ_SEL_RXM = 0x1C, FT980_CMD0A_FREQ_SEL_RXV = 0x1D, FT980_CMD0A_FREQ_SEL_MR = 0x1E, FT980_CMD0A_FREQ_SEL_VFO = 0x1F, /* VFO Select; Question ... how do you set AUX1,2,3? */ FT980_CMD0A_VFO_SEL_GEN = 0x21, FT980_CMD0A_VFO_SEL_HAM = 0x22, /* Set Tab to Current Operating Frequency */ FT980_CMD0A_SET_UPPER_TAB = 0x23, FT980_CMD0A_SET_LOWER_TAB = 0x24, FT980_CMD0A_TOGGLE_TABS = 0x25, /* Clarifier Commands */ FT980_CMD0A_TOGGLE_TX_CLAR = 0x26, FT980_CMD0A_TOGGLE_RX_CLAR = 0x27, /* Memory Commands */ FT980_CMD0A_MEM_SHIFT = 0x28, FT980_CMD0A_MEM_WRITE = 0x29, /* More Frequency Skips */ FT980_CMD0A_UP_100Hz = 0x18, FT980_CMD0A_DN_100Hz = 0x20, FT980_CMD0A_UP_5KHz = 0x2C, FT980_CMD0A_DN_5KHz = 0x2B, FT980_CMD0A_BANDUP = 0x2F, FT980_CMD0A_BANDOWN = 0x2D /* Missing 0A Sub-op-codes: 19,1A,2A,2E, after 2F */ }; /* End of OpCode command 0x0A byte 3 sub-codes */ /************************************************************************************* * Macro Definitions */ #define UPDATE_DATA_OFS(p, o) (((unsigned char*)((p)+1))-(o)) #endif /* _FT980_H */ hamlib-4.6.2/rigs/yaesu/yaesu.h0000644000175000017500000000632014752216205013276 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * yaesu.h - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2001-2010 * * Common yaesu declarations for hamlib * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _YAESU_H #define _YAESU_H 1 #include "idx_builtin.h" /* * Length (in bytes) of yaesu command sequences */ #define YAESU_CMD_LENGTH 5 /* * Basic Data structure for yaesu native cmd set */ struct yaesu_cmd_set { unsigned char ncomp; /* 1 = complete, 0 = incomplete, needs extra info */ unsigned char nseq[YAESU_CMD_LENGTH]; /* native cmd sequence */ }; typedef struct yaesu_cmd_set yaesu_cmd_set_t; extern struct rig_caps ft100_caps; extern struct rig_caps ft450_caps; extern struct rig_caps ft450d_caps; extern struct rig_caps ft736_caps; extern struct rig_caps ft747_caps; extern struct rig_caps ft757gx_caps; extern struct rig_caps ft757gx2_caps; extern struct rig_caps ft600_caps; extern struct rig_caps ft767gx_caps; extern struct rig_caps ft817_caps; extern struct rig_caps ft857_caps; extern struct rig_caps ft897_caps; extern struct rig_caps ft897d_caps; extern struct rig_caps ft847_caps; extern struct rig_caps ft840_caps; extern struct rig_caps ft890_caps; extern struct rig_caps ft891_caps; extern struct rig_caps ft900_caps; extern struct rig_caps ft920_caps; extern struct rig_caps ft950_caps; extern struct rig_caps ft980_caps; extern struct rig_caps ft990_caps; extern struct rig_caps ft990uni_caps; extern struct rig_caps ft991_caps; extern struct rig_caps ft1000mp_caps; extern struct rig_caps ft1000mpmkv_caps; extern struct rig_caps ft1000mpmkvfld_caps; extern struct rig_caps ft1000_caps; extern struct rig_caps ft1000d_caps; extern struct rig_caps ft2000_caps; extern struct rig_caps ftdx3000_caps; extern struct rig_caps ftdx5000_caps; extern struct rig_caps ft9000_caps; extern struct rig_caps frg100_caps; extern struct rig_caps frg8800_caps; extern struct rig_caps frg9600_caps; extern struct rig_caps vr5000_caps; extern struct rig_caps vx1700_caps; extern struct rig_caps ftdx1200_caps; extern struct rig_caps ft847uni_caps; extern struct rig_caps ftdx101d_caps; extern struct rig_caps ft818_caps; extern struct rig_caps ftdx10_caps; extern struct rig_caps ftdx101mp_caps; extern struct rig_caps mchfqrp_caps; extern struct rig_caps ft650_caps; extern struct rig_caps ft710_caps; extern struct rig_caps ft9000Old_caps; extern struct rig_caps q900_caps; extern struct rig_caps pmr171_caps; #endif /* _YAESU_H */ hamlib-4.6.2/rigs/yaesu/ft2000.c0000644000175000017500000003005014752216205013053 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft2000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-2000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "yaesu.h" #include "newcat.h" #include "ft2000.h" #include "tones.h" const struct newcat_priv_caps ft2000_priv_caps = { .roofing_filter_count = 7, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, } }; const struct confparams ft2000_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft2000_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; /* * FT-2000 rig capabilities */ struct rig_caps ft2000_caps = { RIG_MODEL(RIG_MODEL_FT2000), .model_name = "FT-2000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT2000_WRITE_DELAY, .post_write_delay = FT2000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT2000_FUNCS, .has_set_func = FT2000_FUNCS, .has_get_level = FT2000_LEVELS, .has_set_level = RIG_LEVEL_SET(FT2000_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDRGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .vfo_ops = FT2000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the 2000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT2000D_RFPOWER_METER_CAL, .str_cal = FT2000_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FT2000_ALL_RX_MODES, -1, -1, FT2000_VFO_ALL, FT2000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_HF(1, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_6m(1, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FT2000_ALL_RX_MODES, -1, -1, FT2000_VFO_ALL, FT2000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_HF(2, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT2000_OTHER_TX_MODES, W(5), W(100), FT2000_VFO_ALL, FT2000_TX_ANTS), FRQ_RNG_6m(2, FT2000_AM_TX_MODES, W(2), W(25), FT2000_VFO_ALL, FT2000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT2000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT2000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT2000_AM_RX_MODES, Hz(100)}, /* Normal */ {FT2000_AM_RX_MODES, kHz(1)}, /* Fast */ {FT2000_FM_RX_MODES, Hz(100)}, /* Normal */ {FT2000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, /* Narrow CW, RTTY, PKT/USER */ {RIG_MODE_CW | RIG_MODE_CWR, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, /* Normal RTTY */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, /* Narrow RTTY */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(2400)}, /* Wide RTTY */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {FT2000_PKTSSB_RX_MODES, Hz(500)}, /* Normal PKTSSB */ {FT2000_PKTSSB_RX_MODES, Hz(200)}, /* Narrow PKTSSB */ {FT2000_PKTSSB_RX_MODES, Hz(2400)}, /* Wide PKTSSB */ {FT2000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ {FT2000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ {FT2000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FT2000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ RIG_FLT_END, }, .ext_tokens = ft2000_ext_tokens, .extlevels = ft2000_ext_levels, .priv = &ft2000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft9000.c0000644000175000017500000004121614752216205013070 00000000000000/* * hamlib - (C) Frank Singleton 9000 (javabear at users.sourceforge.net) * * ft9000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-9000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "yaesu.h" #include "newcat.h" #include "ft9000.h" #include "tones.h" /* * ft9000 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft9000_caps = { RIG_MODEL(RIG_MODEL_FT9000), .model_name = "FTDX-9000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT9000_WRITE_DELAY, .post_write_delay = FT9000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT9000_FUNCS, .has_set_func = FT9000_FUNCS, .has_get_level = FT9000_LEVELS, .has_set_level = RIG_LEVEL_SET(FT9000_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT9000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_ANT | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the 9000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT9000_RFPOWER_METER_CAL, .str_cal = FT9000_STR_CAL, .chan_list = { /* TBC */ { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham */ {kHz(30), MHz(60), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT9000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT9000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT9000_AM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_AM_RX_MODES, kHz(1)}, /* Fast */ {FT9000_FM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT9000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(6000)}, /* Normal AM */ {RIG_MODE_AM, Hz(3000)}, /* Narrow AM */ {FT9000_FM_RX_MODES, Hz(12000)}, /* Normal FM */ {FT9000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ RIG_FLT_END, }, .priv = NULL, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft9000Old_caps = { RIG_MODEL(RIG_MODEL_FT9000OLD), .model_name = "FTDX-9000 Old", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT9000_WRITE_DELAY, .post_write_delay = FT9000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT9000_FUNCS, .has_set_func = FT9000_FUNCS, .has_get_level = FT9000_LEVELS, .has_set_level = RIG_LEVEL_SET(FT9000_LEVELS), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT9000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_ANT | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the 9000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT9000_RFPOWER_METER_CAL, .str_cal = FT9000_STR_CAL, .chan_list = { /* TBC */ { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham */ {kHz(30), MHz(60), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(1, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT9000_ALL_RX_MODES, -1, -1, FT9000_VFO_ALL, FT9000_TX_ANTS | RIG_ANT_5}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_HF(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT9000_OTHER_TX_MODES, W(5), W(400), FT9000_VFO_ALL, FT9000_TX_ANTS), FRQ_RNG_6m(2, FT9000_AM_TX_MODES, W(2), W(100), FT9000_VFO_ALL, FT9000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT9000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT9000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT9000_AM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_AM_RX_MODES, kHz(1)}, /* Fast */ {FT9000_FM_RX_MODES, Hz(100)}, /* Normal */ {FT9000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT9000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FT9000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(6000)}, /* Normal AM */ {RIG_MODE_AM, Hz(3000)}, /* Narrow AM */ {FT9000_FM_RX_MODES, Hz(12000)}, /* Normal FM */ {FT9000_FM_RX_MODES, Hz(8000)}, /* Narrow FM */ RIG_FLT_END, }, .priv = NULL, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, // .set_vfo = newcat_set_vfo, // old FTDX9000 does not have VS command // .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft950.h0000644000175000017500000001155714752216205013027 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft950.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT950_H #define _FT950_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT950_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT950_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_FMN) #define FT950_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT950_AM_RX_MODES (RIG_MODE_AM) #define FT950_FM_WIDE_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FT950_FM_RX_MODES (FT950_FM_WIDE_RX_MODES|RIG_MODE_FMN) #define FT950_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT950_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT950_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB) /* 100 W class */ #define FT950_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ #define FT950_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_BAND_SELECT) #define FT950_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER) #define FT950_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT950_RFPOWER_METER_CAL \ { \ 6, \ { \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT950_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT950_ANTS (RIG_ANT_1|RIG_ANT_2) #define FT950_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT950_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT950_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT950_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT950_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT950_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT950_PACING_INTERVAL 5 // #define FT950_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-950 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT950_WRITE_DELAY 0 /* Delay sequential fast writes */ //#define FT950_POST_WRITE_DELAY 5 #define FT950_POST_WRITE_DELAY 50 #endif /* _FT950_H */ hamlib-4.6.2/rigs/yaesu/ft710.c0000644000175000017500000002663014752216205013012 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft710.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2023 * * This shared library provides an API for communicating * via serial interface to an FT-710 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ft710.h" const struct newcat_priv_caps ft710_priv_caps = { .roofing_filter_count = 0, .roofing_filters = {} }; const struct confparams ft710_ext_levels[] = { { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ft710_ext_tokens[] = { TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; struct rig_caps ft710_caps = { RIG_MODEL(RIG_MODEL_FT710), .model_name = "FT-710", .mfg_name = "Yaesu", .version = NEWCAT_VER ".7", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 1000, .retry = 3, .has_get_func = FT710_FUNCS, .has_set_func = FT710_FUNCS, .has_get_level = FT710_LEVELS, .has_set_level = RIG_LEVEL_SET(FT710_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BAND4M"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT710_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the FT-710 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT710_RFPOWER_METER_CAL, .swr_cal = FT710_SWR_CAL, .str_cal = FT710_STR_CAL, .id_meter_cal = FT710_ID_CAL, .vd_meter_cal = FT710_VD_CAL, .comp_meter_cal = FT710_COMP_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FT710_ALL_RX_MODES, -1, -1, FT710_VFO_ALL, FT710_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_HF(1, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_6m(1, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FT710_ALL_RX_MODES, -1, -1, FT710_VFO_ALL, FT710_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_HF(2, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_6m(2, FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FT710_OTHER_TX_MODES, W(5), W(200), FT710_VFO_ALL, FT710_TX_ANTS), FRQ_RNG_4m_REGION2(FT710_AM_TX_MODES, W(2), W(75), FT710_VFO_ALL, FT710_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT710_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT710_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT710_AM_RX_MODES, Hz(100)}, /* Normal */ {FT710_AM_RX_MODES, kHz(1)}, /* Fast */ {FT710_FM_RX_MODES, Hz(100)}, /* Normal */ {FT710_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FT710_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FT710_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FT710_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FT710_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FT710_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ft710_ext_tokens, .extlevels = ft710_ext_levels, .priv = &ft710_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_clarifier_frequency, .get_rit = newcat_get_clarifier_frequency, .set_xit = newcat_set_clarifier_frequency, .get_xit = newcat_get_clarifier_frequency, .set_ant = NULL, .get_ant = NULL, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft890.c0000644000175000017500000015267214752216205013031 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft890.c - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002-2005 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-890 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft890.h" /* * Functions considered to be Beta code (2003-04-11): * set_freq * get_freq * set_mode * get_mode * set_vfo * get_vfo * set_ptt * get_ptt * set_split * get_split * set_rit * get_rit * set_func * get_func * get_level * * Functions considered to be Alpha code (2003-04-11): * vfo_op * * functions not yet implemented (2003-04-11): * set_split_freq * get_split_freq * set_split_mode * get_split_mode * */ /* * Native FT890 functions. More to come :-) * */ enum ft890_native_cmd_e { FT890_NATIVE_SPLIT_OFF = 0, FT890_NATIVE_SPLIT_ON, FT890_NATIVE_RECALL_MEM, FT890_NATIVE_VFO_TO_MEM, FT890_NATIVE_VFO_A, FT890_NATIVE_VFO_B, FT890_NATIVE_MEM_TO_VFO, FT890_NATIVE_CLARIFIER_OPS, FT890_NATIVE_FREQ_SET, FT890_NATIVE_MODE_SET, FT890_NATIVE_PACING, FT890_NATIVE_PTT_OFF, FT890_NATIVE_PTT_ON, FT890_NATIVE_MEM_CHNL, FT890_NATIVE_OP_DATA, FT890_NATIVE_VFO_DATA, FT890_NATIVE_MEM_CHNL_DATA, FT890_NATIVE_TUNER_OFF, FT890_NATIVE_TUNER_ON, FT890_NATIVE_TUNER_START, FT890_NATIVE_READ_METER, FT890_NATIVE_READ_FLAGS, FT890_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft890_native_cmd_e ft890_native_cmd_t; /* * Internal MODES - when setting modes via FT890_NATIVE_MODE_SET * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW_W 0x02 #define MODE_SET_CW_N 0x03 #define MODE_SET_AM_W 0x04 #define MODE_SET_AM_N 0x05 #define MODE_SET_FM 0x06 /* * Internal Clarifier parms - when setting clarifier via * FT890_NATIVE_CLARIFIER_OPS * * The manual seems to be incorrect with regard to P1 and P2 values * P1 = 0x00 clarifier off * P1 = 0x01 clarifier on * P1 = 0xff clarifier set * P2 = 0x00 clarifier up * P2 = 0xff clarifier down */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA requests the FT-890 to return its status flags. * These flags consist of 3 bytes (plus 2 filler bytes) and are documented * in the FT-890 manual on page 33. * */ #define FT890_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_GC (1<<1) /* General Coverage Reception selected */ #define SF_SPLIT (1<<2) /* Split active */ #define SF_MCK (1<<3) /* memory Checking in progress */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_MR (1<<5) /* Memory Mode selected */ #define SF_A (0<<6) /* bit 6 clear, VFO A */ #define SF_B (1<<6) /* bit 6 set, VFO B */ #define SF_VFO (1<<7) /* bit 7 set, VFO A or B active */ #define SF_VFOA (SF_VFO|SF_A) /* bit 7 set, bit 6 clear, VFO A */ #define SF_VFOB (SF_VFO|SF_B) /* bit 7 set, bit 6 set, VFO B */ #define SF_VFO_MASK (SF_VFOB) /* bits 6 and 7 */ #define SF_MEM_MASK (SF_MCK|SF_MT|SF_MR) /* bits 3, 4 and 5 */ #define FT890_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define FT890_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 1 */ #define SF_PTT_OFF (0<<7) /* bit 7 set, PTT open */ #define SF_PTT_ON (1<<7) /* bit 7 set, PTT closed */ #define SF_PTT_MASK (SF_PTT_ON) /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03, 04 * * The FT-890 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (19 bytes) * CAT command 0x10, P1 = 03 returns VFO A & B data (18 bytes) * CAT command 0x10, P1 = 04, P4 = 0x01-0x20 returns memory channel data (19 bytes) * In all cases the format is (from the FT-890 manual page 32): * * Offset Value * 0x00 Band Selection (BPF selection: 0x00 - 0x30 (bit 7 =1 on a blanked memory)) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x04 Clarifier Offset (signed value between -999d (0xfc19) and +999d (0x03e7)) * 0x06 Mode Data * 0x07 CTCSS tone code (0x00 - 0x20) * 0x08 Flags (Operating flags -- manual page 33) * * Memory Channel data has the same layout and offsets as the operating * data record. * When either of the 19 byte records is read (P1 = 02, 04), the offset is * +1 as the leading byte is the memory channel number. * The VFO data command (P1 = 03) returns 18 bytes and the VFO B data has * the same layout, but the offset starts at 0x09 and continues through 0x12 * */ #define FT890_SUMO_MEM_CHANNEL 0x00 /* Memory Channel from 0xfa, P1 = 1 */ #define FT890_SUMO_DISPLAYED_FREQ 0x02 /* Current main display, can be VFO A, Memory data, Memory tune (3 bytes) */ #define FT890_SUMO_DISPLAYED_CLAR 0x05 /* RIT offset -- current display */ #define FT890_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT890_SUMO_DISPLAYED_FLAG 0x09 #define FT890_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT890_SUMO_VFO_A_CLAR 0x04 /* RIT offset -- VFO A */ #define FT890_SUMO_VFO_A_MODE 0x06 /* VFO A mode, not necessarily currently displayed! */ #define FT890_SUMO_VFO_A_FLAG 0x08 #define FT890_SUMO_VFO_B_FREQ 0x0a /* Current sub display && VFO B */ #define FT890_SUMO_VFO_B_CLAR 0x0d /* RIT offset -- VFO B */ #define FT890_SUMO_VFO_B_MODE 0x0f /* Current sub display && VFO B */ #define FT890_SUMO_VFO_B_FLAG 0x11 /* * Read meter offset * * FT-890 returns the level of the S meter when in RX and ALC or PO or SWR * when in TX. The level is replicated in the first four bytes sent by the * rig with the final byte being a constant 0xf7 * * The manual states that the returned value will range between 0x00 and 0xff * while "in practice the highest value returned will be around 0xf0". The * manual is silent when this value is returned as my rig returns 0x00 for * S0, 0x44 for S9 and 0x9D for S9 +60. * */ #define FT890_SUMO_METER 0x00 /* Meter level */ /* * Narrow filter selection flag from offset 0x08 or 0x11 * in VFO/Memory Record * * used when READING modes from FT-890 * */ #define FLAG_AM_N (1<<6) #define FLAG_CW_N (1<<7) #define FLAG_MASK (FLAG_AM_N|FLAG_CW_N) /* * Mode Bitmap from offset 0x06 or 0x0f in VFO/Memory Record. * * used when READING modes from FT-890 * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 /* All relevant bits */ #define MODE_MASK (MODE_LSB|MODE_USB|MODE_CW|MODE_AM|MODE_FM) /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 /* * API local implementation * */ static int ft890_init(RIG *rig); static int ft890_cleanup(RIG *rig); static int ft890_open(RIG *rig); static int ft890_close(RIG *rig); static int ft890_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft890_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft890_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft890_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft890_set_vfo(RIG *rig, vfo_t vfo); static int ft890_get_vfo(RIG *rig, vfo_t *vfo); static int ft890_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft890_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft890_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft890_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft890_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft890_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft890_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private helper function prototypes */ static int ft890_get_update_data(RIG *rig, unsigned char ci, unsigned char rl); static int ft890_send_static_cmd(RIG *rig, unsigned char ci); static int ft890_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft890_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft890_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); /* * Native ft890 cmd set prototypes. These are READ ONLY as each * rig instance will copy from these and modify if required. * Complete sequences (1) can be read and used directly as a cmd sequence. * Incomplete sequences (0) must be completed with extra parameters * eg: mem number, or freq etc.. * * TODO: Shorten this static array with parameter substitution -N0NB * */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split = off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split = on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* recall memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* memory operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo A */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo B */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* copy memory data to vfo A */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* clarifier operations */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set display freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* update interval/pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Status Update Data--Memory Channel Number (1 byte) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Status Update Data--Current operating data for VFO/Memory (19 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Status Update DATA--VFO A and B Data (18 bytes) */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Status Update Data--Memory Channel Data (19 bytes) P4 = 0x01-0x20 Memory Channel Number */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* tuner off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* tuner on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* tuner start*/ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read meter, S on RX, ALC|PO|SWR on TX */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read status flags */ }; /* * future - private data * * FIXME: Does this need to be exposed to the application/frontend through * ft890_caps.priv? -N0NB */ struct ft890_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of 1 constructed CAT cmd */ unsigned char update_data[FT890_ALL_DATA_LENGTH]; /* returned data--max value, some are less */ unsigned char current_mem; /* private memory channel number */ }; /* * ft890 rigs capabilities. * Also this struct is READONLY! * */ struct rig_caps ft890_caps = { RIG_MODEL(RIG_MODEL_FT890), .model_name = "FT-890", .mfg_name = "Yaesu", .version = "20200323.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT890_WRITE_DELAY, .post_write_delay = FT890_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_TUNER, .has_set_func = RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TUNE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list: 32 */ .rx_range_list1 = { {kHz(100), MHz(30), FT890_ALL_RX_MODES, -1, -1, FT890_VFO_ALL, FT890_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT890_OTHER_TX_MODES, W(5), W(100), FT890_VFO_ALL, FT890_ANTS), FRQ_RNG_HF(1, FT890_AM_TX_MODES, W(2), W(25), FT890_VFO_ALL, FT890_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT890_ALL_RX_MODES, -1, -1, FT890_VFO_ALL, FT890_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT890_OTHER_TX_MODES, W(5), W(100), FT890_VFO_ALL, FT890_ANTS), FRQ_RNG_HF(2, FT890_AM_TX_MODES, W(2), W(25), FT890_VFO_ALL, FT890_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT890_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT890_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT890_AM_RX_MODES, Hz(100)}, /* Normal */ {FT890_AM_RX_MODES, kHz(1)}, /* Fast */ {FT890_FM_RX_MODES, Hz(100)}, /* Normal */ {FT890_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.2)}, /* standard SSB filter bandwidth */ {RIG_MODE_CW, kHz(2.2)}, /* normal CW filter */ {RIG_MODE_CW, kHz(0.5)}, /* CW filter with narrow selection (must be installed!) */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.2)}, /* AM filter with narrow selection (SSB filter switched in) */ {RIG_MODE_FM, kHz(12)}, /* FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft890_init, .rig_cleanup = ft890_cleanup, .rig_open = ft890_open, /* port opened */ .rig_close = ft890_close, /* port closed */ .set_freq = ft890_set_freq, .get_freq = ft890_get_freq, .set_mode = ft890_set_mode, .get_mode = ft890_get_mode, .set_vfo = ft890_set_vfo, .get_vfo = ft890_get_vfo, .set_ptt = ft890_set_ptt, .get_ptt = ft890_get_ptt, .set_split_vfo = ft890_set_split_vfo, .get_split_vfo = ft890_get_split_vfo, .set_rit = ft890_set_rit, .get_rit = ft890_get_rit, .set_func = ft890_set_func, .get_level = ft890_get_level, .vfo_op = ft890_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init * */ static int ft890_init(RIG *rig) { struct ft890_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft890_priv_data *) calloc(1, sizeof(struct ft890_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; /* TODO: read pacing from preferences */ priv->pacing = FT890_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_MAIN; /* default to whatever */ return RIG_OK; } /* * rig_cleanup * * the serial port is closed by the frontend * */ static int ft890_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open * */ static int ft890_open(RIG *rig) { hamlib_port_t *rp = RIGPORT(rig); struct ft890_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, rp->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, rp->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close * */ static int ft890_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq * * Set frequency for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * If vfo differs from stored value then VFO will be set to the * passed vfo. * */ static int ft890_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft890_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { /* force a VFO change if requested vfo value differs from stored value */ err = ft890_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } err = ft890_send_dial_freq(rig, FT890_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq * * Return Freq for a given VFO * */ static int ft890_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft890_priv_data *priv; unsigned char *p; unsigned char offset; freq_t f; int err, cmd_index, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { err = ft890_get_vfo(rig, &priv->current_vfo); if (err != RIG_OK) { return err; } vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_A_FREQ; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_B_FREQ; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT890_NATIVE_OP_DATA; offset = FT890_SUMO_DISPLAYED_FREQ; count = FT890_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } err = ft890_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); *freq = f; /* return displayed frequency */ return RIG_OK; } /* * rig_set_mode * * set mode and passband: eg AM, CW etc for a given VFO * * If vfo is set to RIG_VFO_CUR then vfo from priv_data is used. * */ static int ft890_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft890_priv_data *priv; unsigned char mode_parm; /* mode parameter */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %li Hz\n", __func__, width); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* translate mode from generic to ft890 specific */ switch (vfo) { case RIG_VFO_A: /* force to VFO */ case RIG_VFO_VFO: err = ft890_set_vfo(rig, RIG_VFO_A); if (err != RIG_OK) { return err; } break; case RIG_VFO_B: err = ft890_set_vfo(rig, RIG_VFO_B); if (err != RIG_OK) { return err; } break; case RIG_VFO_MEM: /* MEM TUNE or user doesn't care */ case RIG_VFO_MAIN: break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } switch (mode) { case RIG_MODE_AM: mode_parm = MODE_SET_AM_W; break; case RIG_MODE_CW: mode_parm = MODE_SET_CW_W; break; case RIG_MODE_USB: mode_parm = MODE_SET_USB; break; case RIG_MODE_LSB: mode_parm = MODE_SET_LSB; break; case RIG_MODE_FM: mode_parm = MODE_SET_FM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width (shamelessly stolen from ft847.c and then butchered :) * The FT-890 only supports narrow width in AM and CW modes * */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_CW: mode_parm = MODE_SET_CW_N; break; case RIG_MODE_AM: mode_parm = MODE_SET_AM_N; break; default: return -RIG_EINVAL; /* Invalid mode, how can caller know? */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { return -RIG_EINVAL; /* Invalid width, how can caller know? */ } } } rig_debug(RIG_DEBUG_TRACE, "%s: set mode_parm = 0x%02x\n", __func__, mode_parm); err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_MODE_SET, mode_parm, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; /* good */ } /* * rig_get_mode * * get mode eg AM, CW etc for a given VFO * */ static int ft890_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft890_priv_data *priv; unsigned char my_mode, m_offset; /* ft890 mode, mode offset */ unsigned char flag, f_offset; /* CW/AM narrow flag */ int err, cmd_index, norm, count; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT890_NATIVE_VFO_DATA; m_offset = FT890_SUMO_VFO_A_MODE; f_offset = FT890_SUMO_VFO_A_FLAG; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_DATA; m_offset = FT890_SUMO_VFO_B_MODE; f_offset = FT890_SUMO_VFO_B_FLAG; count = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: cmd_index = FT890_NATIVE_OP_DATA; m_offset = FT890_SUMO_DISPLAYED_MODE; f_offset = FT890_SUMO_DISPLAYED_FLAG; count = FT890_OP_DATA_LENGTH; break; default: return -RIG_EINVAL; } err = ft890_get_update_data(rig, cmd_index, count); if (err != RIG_OK) { return err; } my_mode = MODE_MASK & priv->update_data[m_offset]; flag = FLAG_MASK & priv->update_data[f_offset]; rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: flag = 0x%02x\n", __func__, flag); /* * translate mode from ft890 to generic. */ switch (my_mode) { case MODE_LSB: *mode = RIG_MODE_LSB; norm = TRUE; break; case MODE_USB: *mode = RIG_MODE_USB; norm = TRUE; break; case MODE_CW: *mode = RIG_MODE_CW; if (flag & FLAG_CW_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_AM: *mode = RIG_MODE_AM; if (flag & FLAG_AM_N) { norm = FALSE; } else { norm = TRUE; } break; case MODE_FM: *mode = RIG_MODE_FM; norm = TRUE; break; default: return -RIG_EINVAL; /* Oops! file bug report */ } if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = %s\n", __func__, rig_strrmode(*mode)); rig_debug(RIG_DEBUG_TRACE, "%s: set width = %d Hz\n", __func__, (int)*width); return RIG_OK; } /* * rig_set_vfo * * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft890_set_vfo(RIG *rig, vfo_t vfo) { struct ft890_priv_data *priv; unsigned char cmd_index; /* index of sequence to send */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } /* FIXME: Include support for RIG_VFO_MAIN */ switch (vfo) { case RIG_VFO_A: cmd_index = FT890_NATIVE_VFO_A; priv->current_vfo = vfo; /* update active VFO */ break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_B; priv->current_vfo = vfo; break; case RIG_VFO_MEM: /* reset to memory channel stored by previous get_vfo * The recall mem channel command uses 0x01 though 0x20 */ err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_RECALL_MEM, (priv->current_mem + 1), 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = vfo; rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->current_mem); return RIG_OK; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_vfo * * get current RX vfo/mem and store requested vfo for * later RIG_VFO_CURR requests plus pass the tested vfo/mem * back to the frontend. * */ static int ft890_get_vfo(RIG *rig, vfo_t *vfo) { struct ft890_priv_data *priv; unsigned char status_0; /* ft890 status flag 0 */ unsigned char stat_vfo, stat_mem; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft890_get_update_data(rig, FT890_NATIVE_READ_FLAGS, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_0 = priv->update_data[FT890_SUMO_DISPLAYED_STATUS_0]; stat_vfo = status_0 & SF_VFO_MASK; /* get VFO active bits */ stat_mem = status_0 & SF_MEM_MASK; /* get MEM active bits */ rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_0 = 0x%02x\n", __func__, status_0); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, stat_vfo); rig_debug(RIG_DEBUG_TRACE, "%s: stat_mem = 0x%02x\n", __func__, stat_mem); /* * translate vfo and mem status from ft890 to generic. * * First a test is made on bits 6 and 7 of status_0. Bit 7 is set * when FT-890 is in VFO mode on display. Bit 6 is set when VFO B * is active and cleared when VFO A is active. * * Conversely, bit 7 is cleared when MEM or MEM TUNE mode is selected * Bit 6 still follows last selected VFO (A or B), but this is not * tested right now. */ switch (stat_vfo) { case SF_VFOA: *vfo = RIG_VFO_A; priv->current_vfo = RIG_VFO_A; break; case SF_VFOB: *vfo = RIG_VFO_B; priv->current_vfo = RIG_VFO_B; break; default: switch (stat_mem) { case SF_MT: case SF_MR: *vfo = RIG_VFO_MEM; priv->current_vfo = RIG_VFO_MEM; /* * Per Hamlib policy capture and store memory channel number * for future set_vfo command. */ err = ft890_get_update_data(rig, FT890_NATIVE_MEM_CHNL, FT890_MEM_CHNL_LENGTH); if (err != RIG_OK) { return err; } priv->current_mem = priv->update_data[FT890_SUMO_MEM_CHANNEL]; rig_debug(RIG_DEBUG_TRACE, "%s: stored mem channel = 0x%02x\n", __func__, priv->current_mem); break; default: /* Oops! */ return -RIG_EINVAL; /* sorry, wrong current VFO */ } } rig_debug(RIG_DEBUG_TRACE, "%s: set vfo = 0x%02x\n", __func__, *vfo); return RIG_OK; } /* * rig_set_ptt * * set the '890 into TX mode * * vfo is respected by calling ft890_set_vfo if * passed vfo != priv->current_vfo * */ static int ft890_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft890_priv_data *priv; unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft890_set_vfo(rig, vfo); } switch (ptt) { case RIG_PTT_OFF: cmd_index = FT890_NATIVE_PTT_OFF; break; case RIG_PTT_ON: cmd_index = FT890_NATIVE_PTT_ON; break; default: return -RIG_EINVAL; /* wrong PTT state! */ } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt * * get current PTT status * */ static int ft890_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft890_priv_data *priv; unsigned char status_2; /* ft890 status flag 2 */ unsigned char stat_ptt; /* status tests */ int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft890_get_update_data(rig, FT890_NATIVE_READ_FLAGS, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } status_2 = priv->update_data[FT890_SUMO_DISPLAYED_STATUS_2]; stat_ptt = status_2 & SF_PTT_MASK; /* get PTT active bit */ rig_debug(RIG_DEBUG_TRACE, "%s: ptt status_2 = 0x%02x\n", __func__, status_2); switch (stat_ptt) { case SF_PTT_OFF: *ptt = RIG_PTT_OFF; break; case SF_PTT_ON: *ptt = RIG_PTT_ON; break; default: /* Oops! */ return -RIG_EINVAL; /* Invalid PTT bit?! */ } return RIG_OK; } /* * rig_set_split_vfo * * set the '890 into split TX/RX mode * * VFO cannot be set as the set split on command only changes the * TX to the other VFO. Setting split off returns the TX to the * main display. * */ static int ft890_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); switch (split) { case RIG_SPLIT_OFF: cmd_index = FT890_NATIVE_SPLIT_OFF; break; case RIG_SPLIT_ON: cmd_index = FT890_NATIVE_SPLIT_ON; break; default: return -RIG_EINVAL; } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo * * Get whether the '890 is in split mode * * vfo value is not used * */ static int ft890_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft890_priv_data *priv; unsigned char status_0; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; /* Get flags for VFO split status */ err = ft890_get_update_data(rig, FT890_NATIVE_READ_FLAGS, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } /* get Split active bit */ status_0 = SF_SPLIT & priv->update_data[FT890_SUMO_DISPLAYED_STATUS_0]; rig_debug(RIG_DEBUG_TRACE, "%s: split status_0 = 0x%02x\n", __func__, status_0); switch (status_0) { case SF_SPLIT: *split = RIG_SPLIT_ON; break; default: *split = RIG_SPLIT_OFF; break; } return RIG_OK; } /* * rig_set_rit * * VFO and MEM rit values are independent. * * passed vfo value is respected. * * Clarifier offset is retained in the rig for either VFO when the * VFO is changed. Offset is not retained when in memory tune mode * and VFO mode is selected or another memory channel is selected. * */ static int ft890_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft890_priv_data *priv; // unsigned char offset; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (rit < -9990 || rit > 9990) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li\n", __func__, rit); priv = (struct ft890_priv_data *)STATE(rig)->priv; /* * The assumption here is that the user hasn't changed * the VFO manually. Does it really need to be checked * every time? My goal is to reduce the traffic on the * serial line to a minimum, but respect the application's * request to change the VFO with this call. * */ if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous rig_get_vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } else if (vfo != priv->current_vfo) { ft890_set_vfo(rig, vfo); } /* * Shuts clarifier off but does not set frequency to 0 Hz */ if (rit == 0) { err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_CLARIFIER_OPS, CLAR_RX_OFF, 0, 0, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: clarifier off error: %s\n", __func__, rigerror(err)); } return err; } /* * Clarifier must first be turned on then the frequency can * be set, +9990 Hz to -9990 Hz */ err = ft890_send_dynamic_cmd(rig, FT890_NATIVE_CLARIFIER_OPS, CLAR_RX_ON, 0, 0, 0); if (err != RIG_OK) { return err; } err = ft890_send_rit_freq(rig, FT890_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rit * * Rig returns offset as hex from 0x0000 to 0x03e7 for 0 to +9.990 kHz * and 0xffff to 0xfc19 for -1 to -9.990 kHz * */ static int ft890_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft890_priv_data *priv; unsigned char *p; unsigned char offset; shortfreq_t f; int err, cmd_index, length; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; /* from previous vfo cmd */ rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_MEM: cmd_index = FT890_NATIVE_OP_DATA; offset = FT890_SUMO_DISPLAYED_CLAR; length = FT890_OP_DATA_LENGTH; break; case RIG_VFO_A: case RIG_VFO_VFO: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_A_CLAR; length = FT890_VFO_DATA_LENGTH; break; case RIG_VFO_B: cmd_index = FT890_NATIVE_VFO_DATA; offset = FT890_SUMO_VFO_B_CLAR; length = FT890_VFO_DATA_LENGTH; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set cmd_index = %i\n", __func__, cmd_index); rig_debug(RIG_DEBUG_TRACE, "%s: set offset = 0x%02x\n", __func__, offset); err = ft890_get_update_data(rig, cmd_index, length); if (err != RIG_OK) { return err; } p = &priv->update_data[offset]; /* big endian integer */ f = (p[0] << 8) + p[1]; /* returned value is hex to nearest hundred Hz */ if (f > 0xfc18) /* 0xfc19 to 0xffff is negative offset */ { f = ~(0xffff - f); } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, f * 10); *rit = f * 10; /* store clarifier frequency */ return RIG_OK; } /* * rig_set_func * * set the '890 supported functions * * vfo is ignored for tuner as it is an independent function * */ static int ft890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %i\n", __func__, status); switch (func) { case RIG_FUNC_TUNER: switch (status) { case OFF: cmd_index = FT890_NATIVE_TUNER_OFF; break; case ON: cmd_index = FT890_NATIVE_TUNER_ON; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_level * * get the '890 meter level * * vfo is ignored for now * * Meter level returned from FT-890 is S meter when rig is in RX * Meter level returned is one of ALC or PO or SWR when rig is in TX * depending on front panel meter selection. Meter selection is NOT * available via CAT. * * TODO: Add support for TX values * */ static int ft890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft890_priv_data *priv; unsigned char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed level = %s\n", __func__, rig_strlevel(level)); priv = (struct ft890_priv_data *)STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: err = ft890_get_update_data(rig, FT890_NATIVE_READ_METER, FT890_STATUS_FLAGS_LENGTH); if (err != RIG_OK) { return err; } p = &priv->update_data[FT890_SUMO_METER]; /* * My FT-890 returns a range of 0x00 to 0x44 for S0 to S9 and 0x44 to * 0x9d for S9 to S9 +60 * * For ease of calculation I rounded S9 up to 0x48 (72 decimal) and * S9 +60 up to 0xa0 (160 decimal). I calculated a divisor for readings * less than S9 by dividing 72 by 54 and the divisor for readings greater * than S9 by dividing 88 (160 - 72) by 60. The result tracks rather well. * * The greatest error is around S1 and S2 and then from S9 to S9 +35. Such * is life when mapping non-linear S-meters to a linear scale. * */ if (*p > 160) { val->i = 60; } else if (*p <= 72) { val->i = ((72 - *p) / 1.3333) * -1; } else { val->i = ((*p - 72) / 1.4667); } rig_debug(RIG_DEBUG_TRACE, "%s: calculated level = %i\n", __func__, val->i); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op * * VFO operations--tuner start, etc * * vfo is ignored for now * */ static int ft890_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int err, cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed op = 0x%02x\n", __func__, op); switch (op) { case RIG_OP_TUNE: cmd_index = FT890_NATIVE_TUNER_START; break; default: return -RIG_EINVAL; } err = ft890_send_static_cmd(rig, cmd_index); if (err != RIG_OK) { return err; } return RIG_OK; } /* * ************************************ * * Private functions to ft890 backend * * ************************************ */ /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 890 has several ways to * get data and several ways to return it. * * Need to use this when doing ft890_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_get_update_data(RIG *rig, unsigned char ci, unsigned char rl) { struct ft890_priv_data *priv; int n, err; /* for read_ */ rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft890_priv_data *)STATE(rig)->priv; err = ft890_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } n = read_block(RIGPORT(rig), priv->update_data, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft890_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; priv->p_cmd[P3] = p3; priv->p_cmd[P4] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft890_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft890_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT890_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT890_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the RIT frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * p1 P1 value -- CLAR_SET_FREQ * p2 P2 value -- CLAR_OFFSET_PLUS || CLAR_OFFSET_MINUS * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function * * Assumes: rit doesn't exceed tuning limits of rig */ static int ft890_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft890_priv_data *priv; unsigned char p1; unsigned char p2; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = %i\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft890_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } p1 = CLAR_SET_FREQ; if (rit < 0) { rit = labs(rit); /* get absolute value of rit */ p2 = CLAR_OFFSET_MINUS; } else { p2 = CLAR_OFFSET_PLUS; } /* Copy native cmd clarifier ops to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, rit / 10, FT890_BCD_RIT); rig_debug(RIG_DEBUG_TRACE, "%s: requested rit after conversion = %d Hz\n", __func__, (int)from_bcd(priv->p_cmd, FT890_BCD_RIT) * 10); priv->p_cmd[P1] = p1; /* ick */ priv->p_cmd[P2] = p2; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft980.c0000644000175000017500000011455414752216205013026 00000000000000/* * ft980.c - (C) Stephane Fillod 2004-2010 * (C) Wolfgang Buesser 2010 * * (C) Mathew Breton 2021 * * This shared library provides an API for communicating * via serial interface to an FT-980 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * FT-980 Hamlib API functions considered to be Stable: * sadly, none yet * * Functions considered to be Beta: * init * cleanup * set_freq * get_freq * set_mode * get_mode * set_mem * get_mem * open * close * * Functions considered to be Alpha: * set_vfo * get_vfo * * Functions not yet implemented * get_xit * set_xit * set_func * get_func * get_ptt * set_ptt * get_dcd * set_rptr_shift * get_rptr_shift * set_rptr_offs * get_rptr_offs * set_split_freq * get_split_freq * set_split_mode * get_split_mode * set_split_freq_mode * get_split_freq_mode * set_split_vfo * get_split_vfo * set_ts * get_ts * vfo_op * * Functions the radio does not support: see readme.ft980 for more details * power2mW * mW2power * newcat_get_ant * newcat_set_ant * set_dcs_code * get_dcs_code * set_tone * get_tone * set_ctcss_tone * get_ctcss_tone * set_dcs_sql * get_dcs_sql * set_tone_sql * get_tone_sql * set_ctcss_sql * get_ctcss_sql * set_powerstat * get_powerstat * set_ant * get_ant * send_dtmf * recv_dtmf * send_morse * stop_morse * wait_morse * send_voice_mem * set_trn * get_trn * set_channel * get_channel * set_bank * scan * set_parm * get_parm * get_info * reset * set_vfo_opt * decode_event * * No idea yet what these do * set_chan_all_cb * get_chan_all_cb * set_conf * get_conf */ #include #include /* String function definitions */ #include /* for timeofday call */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft980.h" /* * Private data */ struct ft980_priv_data { _ft980_memory_t update_data; /* returned data */ vfo_t current_vfo; /* active VFO from last cmd */ struct timeval status_tv; /* update_data caching */ }; /************************************************************************************* * Private Prototype Declarations */ static int ft980_transaction(RIG *rig, const unsigned char *cmd, unsigned char *data, int expected_len); static int ft980_get_status_data(RIG *rig); /* Dump routines are for debug purposes */ static void dump_freq(unsigned char *data); static void dump_vfo(unsigned char data); static void dump_mode(unsigned char data); static void dump_switch(unsigned char data); static void dump_if_shift(unsigned char data); static void dump_rptr_split_code(unsigned char data); static void dump_fsk_shift(unsigned char data); static void dump_if_width(unsigned char data); static void dump_mem_shift_flag(unsigned char data); static void dump_clar_flag(unsigned char data); static void dump_tab_flag(unsigned char data); static void dump_freq_select_sws(unsigned char data); static void dump_mode_sw(unsigned char data); static void dump_mem_ch_sw(unsigned char data); static void dump_status_flag_bits(unsigned char data); static void dump_memory(_ft980_memory_t *memory); static void dump_freq(unsigned char *data) { rig_debug(RIG_DEBUG_TRACE, "%02x%02x%02x%02x ", data[3], data[2], data[1], data[0]); } static void dump_vfo(unsigned char data) { switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "GEN"); break; case 128: rig_debug(RIG_DEBUG_TRACE, "%s", "HAM"); break; } } static void dump_mode(unsigned char data) { switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", " LSB\n"); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", " USB\n"); break; case 2: rig_debug(RIG_DEBUG_TRACE, "%s", " CW-W\n"); break; case 3: rig_debug(RIG_DEBUG_TRACE, "%s", " CW-N\n"); break; case 4: rig_debug(RIG_DEBUG_TRACE, "%s", " AM-W\n"); break; case 5: rig_debug(RIG_DEBUG_TRACE, "%s", " AM-N\n"); break; case 6: rig_debug(RIG_DEBUG_TRACE, "%s", " FSK\n"); break; case 7: rig_debug(RIG_DEBUG_TRACE, "%s", " FM\n"); break; } } static void dump_switch(unsigned char data) { switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF"); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", "ON "); break; } } static void dump_if_shift(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%d\n", __func__, data - 15); } static void dump_rptr_split_code(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%02x\n", __func__, data); } static void dump_fsk_shift(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%02x\n", __func__, data); } static void dump_if_width(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:%d\n", __func__, data); } static void dump_mem_shift_flag(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s:", __func__); switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF\n"); break; case 16: rig_debug(RIG_DEBUG_TRACE, "%s", "ON\n"); break; } } static void dump_clar_flag(unsigned char data) { unsigned char RX_CLAR = data & 0x20; unsigned char TX_CLAR = data & 0x40; rig_debug(RIG_DEBUG_TRACE, "%s", "CLAR_SHIFT RX/TX:"); switch ((unsigned int)RX_CLAR) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF "); break; case 0x20: rig_debug(RIG_DEBUG_TRACE, "%s", "ON "); break; } switch ((unsigned int)TX_CLAR) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", " OFF "); break; case 0x40: rig_debug(RIG_DEBUG_TRACE, "%s", " ON "); break; } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_tab_flag(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s", "TAB FLAG :"); switch (data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "OFF\n"); break; case 0x80: rig_debug(RIG_DEBUG_TRACE, "%s", "ON\n"); break; } } static void dump_freq_select_sws(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s", "freq_select_sws :"); switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "VFO "); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", "MR "); break; case 2: rig_debug(RIG_DEBUG_TRACE, "%s", "RX_M"); break; case 3: rig_debug(RIG_DEBUG_TRACE, "%s", "RX_V"); break; } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_mode_sw(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "%s", "mode_sw :"); switch ((unsigned int)data) { case 0: rig_debug(RIG_DEBUG_TRACE, "%s", "LSB "); break; case 1: rig_debug(RIG_DEBUG_TRACE, "%s", "USB "); break; case 2: rig_debug(RIG_DEBUG_TRACE, "%s", "CW-W"); break; case 3: rig_debug(RIG_DEBUG_TRACE, "%s", "CW-N"); break; case 4: rig_debug(RIG_DEBUG_TRACE, "%s", "AM-W"); break; case 5: rig_debug(RIG_DEBUG_TRACE, "%s", "AM-N"); break; case 6: rig_debug(RIG_DEBUG_TRACE, "%s", "FSK"); break; case 7: rig_debug(RIG_DEBUG_TRACE, "%s", "FM"); break; } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_mem_ch_sw(unsigned char data) { rig_debug(RIG_DEBUG_TRACE, "mem_ch_sw :%d\n", data + 1); } static void dump_status_flag_bits(unsigned char data) { unsigned char TX = data & 0x01; unsigned char SPLIT = data & 0x08; unsigned char VFO = data & 0x20; unsigned char CLAR = data & 0x40; rig_debug(RIG_DEBUG_TRACE, "%s", "status_flag_bits :"); if (TX) { rig_debug(RIG_DEBUG_TRACE, "%s", "TX "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "RX "); } if (SPLIT) { rig_debug(RIG_DEBUG_TRACE, "%s", "SPLIT "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "SIMPLEX "); } if (VFO) { rig_debug(RIG_DEBUG_TRACE, "%s", "VFO "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "MEMORY "); } if (CLAR) { rig_debug(RIG_DEBUG_TRACE, "%s", "CLAR_ON "); } else { rig_debug(RIG_DEBUG_TRACE, "%s", "CLAR_OFF"); } rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); } static void dump_memory(_ft980_memory_t *memory) { if (!rig_need_debug(RIG_DEBUG_TRACE)) { return; } rig_debug(RIG_DEBUG_TRACE, "%s", "mem_1 :"); dump_freq(memory->mem_1); dump_vfo(memory->vfo_1); dump_mode(memory->mode_1); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_2 :"); dump_freq(memory->mem_2); dump_vfo(memory->vfo_2); dump_mode(memory->mode_2); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_3 :"); dump_freq(memory->mem_3); dump_vfo(memory->vfo_3); dump_mode(memory->mode_3); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_4 :"); dump_freq(memory->mem_4); dump_vfo(memory->vfo_4); dump_mode(memory->mode_4); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_5 :"); dump_freq(memory->mem_5); dump_vfo(memory->vfo_5); dump_mode(memory->mode_5); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_6 :"); dump_freq(memory->mem_6); dump_vfo(memory->vfo_6); dump_mode(memory->mode_6); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_7 :"); dump_freq(memory->mem_7); dump_vfo(memory->vfo_7); dump_mode(memory->mode_7); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_8 :"); dump_freq(memory->mem_8); dump_vfo(memory->vfo_8); dump_mode(memory->mode_8); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_9 :"); dump_freq(memory->mem_9); dump_vfo(memory->vfo_9); dump_mode(memory->mode_9); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_10 :"); dump_freq(memory->mem_10); dump_vfo(memory->vfo_10); dump_mode(memory->mode_10); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_11 :"); dump_freq(memory->mem_11); dump_vfo(memory->vfo_11); dump_mode(memory->mode_11); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_12 :"); dump_freq(memory->mem_12); dump_vfo(memory->vfo_12); dump_mode(memory->mode_12); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_13 :"); dump_freq(memory->mem_13); dump_vfo(memory->vfo_13); dump_mode(memory->mode_13); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_14 :"); dump_freq(memory->mem_14); dump_vfo(memory->vfo_14); dump_mode(memory->mode_14); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_15 :"); dump_freq(memory->mem_15); dump_vfo(memory->vfo_15); dump_mode(memory->mode_15); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_16 :"); dump_freq(memory->mem_16); dump_vfo(memory->vfo_16); dump_mode(memory->mode_16); rig_debug(RIG_DEBUG_TRACE, "%s", "gen_vfo_freq :"); dump_freq(memory->gen_vfo_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\nHAM :"); dump_freq(memory->ham_vfo_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n "); dump_vfo(memory->vfo); dump_mode(memory->mode); rig_debug(RIG_DEBUG_TRACE, "%s", "clar_freq :"); dump_freq(memory->clar_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_shift_freq :"); dump_freq(memory->mem_shift_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "mem_clar_freq :"); dump_freq(memory->mem_clar_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", " "); dump_vfo(memory->vfo); dump_mode(memory->mode); rig_debug(RIG_DEBUG_TRACE, "%s", "ldb_flag :"); dump_switch(memory->ldb_flag); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "ext_ctl_flag :"); dump_switch(memory->ext_ctl_flag); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); dump_if_shift(memory->if_shift); dump_rptr_split_code(memory->rptr_split_code); dump_fsk_shift(memory->fsk_shift); dump_if_width(memory->if_width); dump_mem_shift_flag(memory->mem_shift_flag); dump_clar_flag(memory->clar_flag); dump_tab_flag(memory->tab_flag); dump_freq_select_sws(memory->freq_select_sws); rig_debug(RIG_DEBUG_TRACE, "%s", "offset_sw :"); dump_switch(memory->offset_sw); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); dump_mode_sw(memory->mode_sw); dump_mem_ch_sw(memory->mem_ch_sw); rig_debug(RIG_DEBUG_TRACE, "%s", "lower_tab_freq :"); dump_freq(memory->lower_tab_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", "upper_tab_freq :"); dump_freq(memory->upper_tab_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); rig_debug(RIG_DEBUG_TRACE, "%s", " "); dump_vfo(memory->op_vfo); dump_mode(memory->op_mode); rig_debug(RIG_DEBUG_TRACE, "%s", "op_freq :"); dump_freq(memory->op_freq); rig_debug(RIG_DEBUG_TRACE, "%s", "\n"); dump_status_flag_bits(memory->status_flag_bits); } int ft980_transaction(RIG *rig, const unsigned char *cmd, unsigned char *data, int expected_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); unsigned char echo_back[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } retval = read_block(rp, echo_back, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } if (retval != YAESU_CMD_LENGTH || (memcmp(echo_back, cmd, YAESU_CMD_LENGTH) != 0)) { return -RIG_EPROTO; } retval = write_block(rp, cmd_OK, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } retval = read_block(rp, data, expected_len); if (retval < 0) { return retval; } if (retval != expected_len) { return -RIG_EPROTO; } return RIG_OK; } int ft980_get_status_data(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01 }; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig_check_cache_timeout(&priv->status_tv, FT980_CACHE_TIMEOUT)) { return RIG_OK; } retval = ft980_transaction(rig, cmd, (unsigned char *)&priv->update_data, FT980_ALL_STATUS_LENGTH); if (retval != RIG_OK) { return retval; } /* update cache date */ gettimeofday(&priv->status_tv, NULL); dump_memory(&priv->update_data); return retval; } /**************************************************************************** * rig_init* * * Initialize memory & rig private data structure * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Nothing special here * */ int ft980_init(RIG *rig) { struct ft980_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft980_priv_data *) calloc(1, sizeof(struct ft980_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = (struct ft980_priv_data *)STATE(rig)->priv; memset(priv, 0, sizeof(struct ft980_priv_data)); // Initialize operating vfo mode to current VFO priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /**************************************************************************** * rig_cleanup* * * Release memory in rig private data structure for a clean exit * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Nothing special here * */ int ft980_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /**************************************************************************** * rig_open* * * Initialize memory & rig private data structure * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Should be able to optimize * ToDo: add check so we don't get stuck in EXT CTRL toggle trap/loop * */ int ft980_open(RIG *rig) { unsigned char echo_back[YAESU_CMD_LENGTH]; struct ft980_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int retry_count1 = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft980_priv_data *)STATE(rig)->priv; /* send Ext Cntl ON: Activate CAT */ do { int retval; int retry_count2 = 0; do { write_block(rp, cmd_ON_OFF, YAESU_CMD_LENGTH); retval = read_block(rp, echo_back, YAESU_CMD_LENGTH); } while (retval != 5 && retry_count2++ < rp->retry); write_block(rp, cmd_OK, YAESU_CMD_LENGTH); read_block(rp, (unsigned char *) &priv->update_data, FT980_ALL_STATUS_LENGTH); } while (!priv->update_data.ext_ctl_flag && retry_count1++ < rp->retry); return RIG_OK; } /**************************************************************************** * rig_close* * * Send command to toggle out of EXT CTRL mode * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Nothing special here * Could be optimized. * */ int ft980_close(RIG *rig) { unsigned char echo_back[YAESU_CMD_LENGTH]; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retry_count1 = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); do { int retval; int retry_count2 = 0; do { write_block(rp, cmd_ON_OFF, YAESU_CMD_LENGTH); retval = read_block(rp, echo_back, YAESU_CMD_LENGTH); } while (retval != 5 && retry_count2++ < rp->retry); write_block(rp, cmd_OK, YAESU_CMD_LENGTH); read_block(rp, (unsigned char *) &priv->update_data, FT980_ALL_STATUS_LENGTH); } while (priv->update_data.ext_ctl_flag && retry_count1++ < rp->retry); return RIG_OK; } /* * Only the current VFO frequency can be set * Other Hamlib backends (ex FT-990) switch VFO, change freq, then exit * They do not return to the original VFO. * We will stick with this convention for now. * * ToDo: Check return data to verify frequency was set correctly */ /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * Issues: an error will occur with the 4.0 rig.c set_cache_freq routine when * targeting VFO_MEM. */ int ft980_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x08}; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, " %s: passed freq = %lf Hz\n", __func__, freq); // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, " %s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft980_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } /* store bcd format in cmd (MSB) */ to_bcd(cmd, freq / 10, 8); /* why is this done ? */ rig_force_cache_timeout(&priv->status_tv); /* Frequency set */ return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, 5), 5); } /* * We can get HAM, GEN, Memory Shift (?), "Operating" * What is memory "Shift"? */ /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft980_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval; freq_t f; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); /* Frequency get */ retval = ft980_get_status_data(rig); if (retval != RIG_OK) { return retval; } switch (vfo) { case RIG_VFO_CURR: f = from_bcd(priv->update_data.op_freq, 8); break; case RIG_VFO_MAIN: f = from_bcd(priv->update_data.ham_vfo_freq, 8); break; case RIG_VFO_SUB: f = from_bcd(priv->update_data.gen_vfo_freq, 8); break; case RIG_VFO_MEM: f = from_bcd(priv->update_data.mem_shift_freq, 8); break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: Selected Memory Freq = %lf\n", __func__, f * 10); *freq = f * 10; /* return displayed frequency */ return RIG_OK; } /* * Only the current VFO mode can be set * Other Hamlib backends (ex FT-990) switch VFO, change mode, then exit * They do not return to the original VFO. * We will stick with this convention for now. * * ToDo: Check return data to verify mode was set correctly */ /* * rig_set_mode* * * Set mode for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, Sub, MEM * mode | input | byte * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft980_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0A}; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; unsigned char md; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, " %s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, " %s: passed width = %ld Hz\n", __func__, width); // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft980_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } /* * translate mode from generic to ft980 specific */ switch (mode) { case RIG_MODE_CW : md = FT980_CMD0A_MD_CW; break; case RIG_MODE_USB: md = FT980_CMD0A_MD_USB; break; case RIG_MODE_LSB: md = FT980_CMD0A_MD_LSB; break; case RIG_MODE_FM: md = FT980_CMD0A_MD_FM; break; case RIG_MODE_AM: md = FT980_CMD0A_MD_AM; break; case RIG_MODE_RTTY: md = FT980_CMD0A_MD_RTTY; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { switch (md) { case FT980_CMD0A_MD_CW: md = FT980_CMD0A_MD_CWN; break; case FT980_CMD0A_MD_AM: md = FT980_CMD0A_MD_AMN; break; } } cmd[3] = md; /* Might be deprecated in Hamlib 4.1 */ rig_force_cache_timeout(&priv->status_tv); /* Mode set */ return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); } /* * rig_get_mode * * get mode eg AM, CW etc * ??? What is the difference between byte 6 (operating mode vfo_op * and byte 30 (selected VFO mode) ??? */ /* * rig_get_mode* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * mode * | output | byte * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft980_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { unsigned char my_mode; /* ft890 mode, mode offset */ struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval, norm; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, " %s: passed vfo = 0x%02x\n", __func__, vfo); retval = ft980_get_status_data(rig); if (retval != RIG_OK) { return retval; } switch (vfo) { case RIG_VFO_CURR: my_mode = priv->update_data.op_mode; rig_debug(RIG_DEBUG_TRACE, " %s: Current VFO Mode = 0x%02x\n", __func__, my_mode); break; case RIG_VFO_MAIN: case RIG_VFO_SUB: /* This is a point of confusion: what exactly is byte 30? */ my_mode = priv->update_data.mode; rig_debug(RIG_DEBUG_TRACE, " %s: HAM/GEN VFO Mode = 0x%02x\n", __func__, my_mode); break; case RIG_VFO_MEM: my_mode = priv->update_data.mem_mode; rig_debug(RIG_DEBUG_TRACE, " %s: MEM VFO Mode = 0x%02x\n", __func__, my_mode); break; default: return -RIG_EVFO; } /* * translate mode from ft980 to generic. */ switch (my_mode) { case 0: *mode = RIG_MODE_LSB; norm = 1; break; case 1: *mode = RIG_MODE_USB; norm = 1; break; case 2: *mode = RIG_MODE_CW; norm = 1; break; case 3: *mode = RIG_MODE_CW; norm = 0; break; case 4: *mode = RIG_MODE_AM; norm = 1; break; case 5: *mode = RIG_MODE_AM; norm = 0; break; case 6: *mode = RIG_MODE_RTTY; norm = 1; break; case 7: *mode = RIG_MODE_FM; norm = 1; break; default: return -RIG_EPROTO; /* Oops! file bug report */ } rig_debug(RIG_DEBUG_TRACE, " %s: Hamlib mode = %s\n", __func__, rig_strrmode(*mode)); if (norm) { *width = rig_passband_normal(rig, *mode); } else { *width = rig_passband_narrow(rig, *mode); } rig_debug(RIG_DEBUG_TRACE, " %s: Filter width = %d Hz\n", __func__, (int)*width); return RIG_OK; } int ft980_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { return -RIG_ENIMPL; #if 0 // deprecated as was ignored before now unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x8e}; /* * this can be misleading as Yaesu call it "Full duplex" * or "sat mode", and split Yaesu terms is repeater shift. */ cmd[4] = split == RIG_SPLIT_ON ? 0x0e : 0x8e; return write_block(RIGPORT(rig), (char *) cmd, YAESU_CMD_LENGTH); #endif } int ft980_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { return -RIG_ENIMPL; } int ft980_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return -RIG_ENIMPL; } int ft980_set_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0A }; struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (ch > 16 || ch < 1) { return -RIG_EINVAL; } cmd[3] = ch - 1; return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); } /**************************************************************************** * rig_get_mem * * Get the number of the currently selected memory * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | Not applicable for FT-980 * ch | output | pointer to channel integer to be returned * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: returns currently selected memory channel regardlessof front * panel knob selection (can be different when CAT is enabled). */ int ft980_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft980_priv_data *priv = (struct ft980_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = ft980_get_status_data(rig); if (retval != RIG_OK) { return retval; } *ch = priv->update_data.mem_ch_sw + 1; return RIG_OK; } /**************************************************************************** * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFO_MAIN, VFOB/GEN, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will essentially "no op" * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ /* VFO_CURR: Whatever is shown in op_freq/op_mode */ /* VFO_MAIN: Mode = VFO, VFO = MAIN */ /* VFO_SUB: Mode = VFO, VFO = GEN */ /* VFO_MEM: Mode = Memory, VFO = don't care */ int ft980_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0A }; struct ft980_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EARG; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); priv = (struct ft980_priv_data *)STATE(rig)->priv; switch (vfo) { case RIG_VFO_CURR: rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, priv->current_vfo); return RIG_OK; break; case RIG_VFO_MAIN: cmd[3] = FT980_CMD0A_VFO_SEL_HAM; rig_debug(RIG_DEBUG_TRACE, "%s: set VFO GEN/HAM = 0x%02x\n", __func__, cmd[3]); err = ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); if (err != RIG_OK) { return err; } cmd[3] = FT980_CMD0A_FREQ_SEL_VFO; break; case RIG_VFO_SUB: cmd[3] = FT980_CMD0A_VFO_SEL_GEN; rig_debug(RIG_DEBUG_TRACE, "%s: set VFO GEN/HAM = 0x%02x\n", __func__, cmd[3]); err = ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); if (err != RIG_OK) { return err; } cmd[3] = FT980_CMD0A_FREQ_SEL_VFO; break; case RIG_VFO_MEM: cmd[3] = FT980_CMD0A_FREQ_SEL_MR; break; default: return -RIG_EVFO; } rig_debug(RIG_DEBUG_TRACE, "%s: set VFO Status = %s\n", __func__, rig_strvfo(vfo)); return ft980_transaction(rig, cmd, UPDATE_DATA_OFS(&priv->update_data, FT980_OTHER_STATUS_LENGTH), FT980_OTHER_STATUS_LENGTH); } /**************************************************************************** * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | currVFO, VFO_MAIN, VFOB/GEN, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: * VFO_MAIN: If (Status = VFO && VFO = MAIN) || (Status = RXV && VFO = MAIN) * VFO_SUB: If (Status = VFO && VFO = GEN) || (Status = RXV && VFO = GEN) * VFO_MEM: If *Status = Memory) || (Status = RXM) * * If operating in split (RXM, RXV) then get_vfo returns the receive vfo */ int ft980_get_vfo(RIG *rig, vfo_t *vfo) { int err; struct ft980_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EARG; } priv = (struct ft980_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft980_get_status_data(rig); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: status_flag_bits = 0x%02x\n", __func__, priv->update_data.status_flag_bits); rig_debug(RIG_DEBUG_TRACE, "%s: op_vfo = %s\n", __func__, rig_strvfo(priv->update_data.op_vfo)); /* Decode the VFO Setting and VFO States */ if (!(priv->update_data.status_flag_bits & FT_980_STATUSFLAG_VFO_MASK)) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.op_vfo == FT980_VFO_HAM_SEL) { priv->current_vfo = RIG_VFO_MAIN; } else if (priv->update_data.op_vfo == FT980_VFO_GEN_SEL) { priv->current_vfo = RIG_VFO_SUB; } else { return -RIG_EVFO; } rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = %s\n", __func__, rig_strvfo(priv->current_vfo)); *vfo = priv->current_vfo; return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft736.c0000644000175000017500000004151414752216205013020 00000000000000/* * ft736.c - (C) Stephane Fillod 2004-2010 * * This shared library provides an API for communicating * via serial interface to an FT-736R using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "tones.h" #include "cache.h" #define FT736_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_CWN) #define FT736_VFOS (RIG_VFO_A) /* Measurement by Ron W6FM using a signal generator. * Raw values supposed to be between 0x30 and 0xad according to manual. */ #define FT736_STR_CAL { 3, { \ { 0x1d, -54 }, /* S0 */ \ { 0x54, 0 }, /* S9 */ \ { 0x9d, 60 } /* +60 */ \ } } struct ft736_priv_data { split_t split; }; /* Private helper function prototypes */ static int ft736_open(RIG *rig); static int ft736_close(RIG *rig); static int ft736_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft736_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); // cached answer static int ft736_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft736_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft736_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft736_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft736_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft736_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft736_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft736_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft736_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft736_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft736_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft736_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft736_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); /* Some tones are present twice, the second value is * higher Q (80), according to manual. */ static tone_t ft736_ctcss_list[] = { 670, 719, 770, 825, 885, 948, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 670, 719, 744, 770, 797, 825, 854, 885, 915, 0 }; #define FT736_CTCSS_NB 42 /* * ft736 rigs capabilities. * * TODO: * - AQS */ struct rig_caps ft736_caps = { RIG_MODEL(RIG_MODEL_FT736R), .model_name = "FT-736R", .mfg_name = "Yaesu", .version = "20240921.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, /* RTS low, DTR high, and CTS low. */ .write_delay = 30, /* 50ms to be real safe */ .post_write_delay = 0, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_TONE | RIG_FUNC_TSQL, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_NONE, .ctcss_list = ft736_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {MHz(50), MHz(53.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(144), MHz(145.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(430), MHz(439.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, -1, -1, FT736_VFOS }, RIG_FRNG_END, }, /* Region 1 rx ranges */ .tx_range_list1 = { {MHz(50), MHz(53.99999), FT736_MODES, W(5), W(30), FT736_VFOS }, {MHz(144), MHz(145.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(430), MHz(439.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, W(5), W(45), FT736_VFOS }, RIG_FRNG_END, }, /* region 1 TX ranges */ .rx_range_list2 = { {MHz(50), MHz(53.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(144), MHz(147.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(220), MHz(224.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(430), MHz(449.99999), FT736_MODES, -1, -1, FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, -1, -1, FT736_VFOS }, RIG_FRNG_END, }, /* Region 2 rx ranges */ .tx_range_list2 = { {MHz(50), MHz(53.99999), FT736_MODES, W(5), W(30), FT736_VFOS }, {MHz(144), MHz(147.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(220), MHz(224.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(430), MHz(449.99999), FT736_MODES, W(5), W(60), FT736_VFOS }, {MHz(1240), MHz(1299.99999), FT736_MODES, W(5), W(45), FT736_VFOS }, RIG_FRNG_END, }, /* region 2 TX ranges */ .tuning_steps = { {FT736_MODES, Hz(10)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW | RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FMN, kHz(8)}, {RIG_MODE_CWN, Hz(600)}, RIG_FLT_END, }, .str_cal = FT736_STR_CAL, .rig_open = ft736_open, .rig_close = ft736_close, .set_freq = ft736_set_freq, .get_freq = ft736_get_freq, .get_mode = ft736_get_mode, .set_mode = ft736_set_mode, .set_ptt = ft736_set_ptt, .get_dcd = ft736_get_dcd, .get_level = ft736_get_level, .set_split_vfo = ft736_set_split_vfo, .set_split_freq = ft736_set_split_freq, .set_split_mode = ft736_set_split_mode, .set_rptr_shift = ft736_set_rptr_shift, .set_rptr_offs = ft736_set_rptr_offs, .set_func = ft736_set_func, .set_ctcss_tone = ft736_set_ctcss_tone, .set_ctcss_sql = ft736_set_ctcss_sql, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft736_open routine * */ int ft736_open(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x00}; struct ft736_priv_data *priv; int ret; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); STATE(rig)->priv = (struct ft736_priv_data *) calloc(1, sizeof(struct ft736_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->split = RIG_SPLIT_OFF; /* send Ext Cntl ON: Activate CAT */ ret = write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); if (ret != RIG_OK) { free(priv); } return ret; } int ft736_close(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x80, 0x80, 0x80, 0x80, 0x80}; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); free(STATE(rig)->priv); /* send Ext Cntl OFF: Deactivate CAT */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x01}; const struct ft736_priv_data *priv = (struct ft736_priv_data *)STATE(rig)->priv; int retval; // we will assume requesting to set VFOB is split mode if (vfo == RIG_VFO_B) { return rig_set_split_freq(rig, vfo, freq); } if (priv->split == RIG_SPLIT_ON) { cmd[4] = 0x1e; } /* store bcd format in cmd (MSB) */ to_bcd_be(cmd, freq / 10, 8); /* special case for 1.2GHz band */ if (freq > GHz(1.2)) { cmd[0] = (cmd[0] & 0x0f) | 0xc0; } retval = write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); if (retval == RIG_OK) { rig_set_cache_freq(rig, vfo, freq); } return retval; } int ft736_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) { *freq = CACHE(rig)->freqMainA; } else { rig_get_cache_freq(rig, vfo, freq, NULL); } return RIG_OK; } #define MD_LSB 0x00 #define MD_USB 0x01 #define MD_CW 0x02 #define MD_CWN 0x82 #define MD_FM 0x08 #define MD_FMN 0x88 static int ft736_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *mode = CACHE(rig)->modeMainA; switch (*mode) { case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_CW: *width = 2200; break; case RIG_MODE_CWN: *width = 600; break; case RIG_MODE_FM: *width = 12000; break; case RIG_MODE_FMN: *width = 800; break; default: *width = 2200; break; } return RIG_OK; } int ft736_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x07}; unsigned char md; const struct ft736_priv_data *priv = (struct ft736_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_B) { return ft736_set_split_mode(rig, vfo, mode, width); } if (priv->split == RIG_SPLIT_ON) { cmd[4] = 0x17; } /* * translate mode from generic to ft736 specific */ switch (mode) { case RIG_MODE_CW: md = MD_CW; break; case RIG_MODE_CWN: md = MD_CWN; break; case RIG_MODE_USB: md = MD_USB; break; case RIG_MODE_LSB: md = MD_LSB; break; case RIG_MODE_FM: md = MD_FM; break; case RIG_MODE_FMN: md = MD_FMN; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (width != RIG_PASSBAND_NOCHANGE && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md |= 0x80; } cmd[0] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x8e}; struct ft736_priv_data *priv = (struct ft736_priv_data *)STATE(rig)->priv; int ret; /* * this can be misleading as Yaesu call it "Full duplex" * or "sat mode", and split Yaesu terms is repeater shift. */ cmd[4] = split == RIG_SPLIT_ON ? 0x0e : 0x8e; ret = write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); if (ret == RIG_OK) { priv->split = split; } return ret; } int ft736_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x2e}; int retval = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { return retval; } /* store bcd format in cmd (MSB) */ to_bcd_be(cmd, freq / 10, 8); /* special case for 1.2GHz band */ if (freq > GHz(1.2)) { cmd[0] = (cmd[0] & 0x0f) | 0xc0; } /* Frequency set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x27}; unsigned char md; /* * translate mode from generic to ft736 specific */ switch (mode) { case RIG_MODE_CW: md = MD_CW; break; case RIG_MODE_CWN: md = MD_CWN; break; case RIG_MODE_USB: md = MD_USB; break; case RIG_MODE_LSB: md = MD_LSB; break; case RIG_MODE_FM: md = MD_FM; break; case RIG_MODE_FMN: md = MD_FMN; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (RIG_PASSBAND_NOCHANGE != width && width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { md |= 0x80; } cmd[0] = md; /* Mode set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x88}; cmd[4] = ptt == RIG_PTT_ON ? 0x08 : 0x88; /* Tx/Rx set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xe7}; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 5); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read squelch failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } *dcd = cmd[0] == 0x00 ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } int ft736_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xf7}; int retval; hamlib_port_t *rp = RIGPORT(rig); if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send Test S-meter cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 5); if (retval < 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0]; return RIG_OK; } int ft736_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x89}; switch (shift) { case RIG_RPT_SHIFT_NONE: /* There's a typo in the manual. * "Split Dir. simplex" is in fact 0x89, and 0x88 is PTT off! */ cmd[4] = 0x89; break; case RIG_RPT_SHIFT_MINUS: cmd[4] = 0x09; break; case RIG_RPT_SHIFT_PLUS: cmd[4] = 0x49; break; default: return -RIG_EINVAL; } return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xf9}; /* store bcd format in cmd (MSB) */ to_bcd_be(cmd, offs / 10, 8); /* Offset set */ return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x8a}; switch (func) { case RIG_FUNC_TONE: cmd[4] = status ? 0x4a : 0x8a; break; case RIG_FUNC_TSQL: cmd[4] = status ? 0x0a : 0x8a; break; default: return -RIG_EINVAL; } return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0xfa}; int i; for (i = 0; i < FT736_CTCSS_NB; i++) { if (ft736_ctcss_list[i] == tone) { break; } } if (i == FT736_CTCSS_NB) { return -RIG_EINVAL; } cmd[0] = 0x3e - i; return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } int ft736_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { /* same opcode as tone */ return ft736_set_ctcss_tone(rig, vfo, tone); } hamlib-4.6.2/rigs/yaesu/ft757gx.h0000644000175000017500000000520314752216205013362 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * * ft757gx.h - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * This shared library provides an API for communicating * via serial interface to an FT-757GX using the "CAT" interface * box (FIF-232C) or similar (max232 + some capacitors :-) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT757GX_H #define _FT757GX_H 1 #define FT757GX_STATUS_UPDATE_DATA_LENGTH 75 #define FT757GX_PACING_INTERVAL 0 #define FT757GX_PACING_DEFAULT_VALUE 0 #define FT757GX_WRITE_DELAY 50 /* number of BCD digits--2 digits per octet */ #define BCD_LEN 8 /* Sequential fast writes confuse my FT757GX without this delay */ #define FT757GX_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT757GX_DEFAULT_READ_TIMEOUT FT757GX_STATUS_UPDATE_DATA_LENGTH * (5 + (FT757GX_PACING_INTERVAL * FT757GX_PACING_DEFAULT_VALUE)) /* * Some useful offsets in the status update map (offset = book byte value - 1) * * Status Update Chart, FT757GXII */ #define STATUS_CURR_FREQ 5 /* Operating Frequency */ #define STATUS_CURR_MODE 9 #define STATUS_VFOA_FREQ 10 #define STATUS_VFOA_MODE 14 #define STATUS_VFOB_FREQ 15 #define STATUS_VFOB_MODE 19 /* Mode values for both set and get */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CWW 0x02 #define MODE_CWN 0x03 #define MODE_AM 0x04 #define MODE_FM 0x05 /* TODO: get better measure numbers */ #define FT757GXII_STR_CAL { 2, { \ { 0, -60 }, /* S0 -6dB */ \ { 15, 60 } /* +60 */ \ } } #define FT757_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1 \ } /* * Receiver caps */ #define FT757GX_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* * TX caps */ #define FT757GX_ALL_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #endif /* _FT757GX_H */ hamlib-4.6.2/rigs/yaesu/ft990.c0000755000175000017500000027307014752216205013031 00000000000000/* * hamlib - (C) Stephane Fillod 2002-2010 (fillods at users.sourceforge.net) * (C) Terry Embry 2009 * * ft990.c - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* THIS FILE WAS MODIFIED IN DECEMBER 2016 TO REMOVE ANY REFERENCE TO THE FT-1000/D. SEPARATE ft1000d.c and .h FILES * WERE CREATED TO HANDLE FT-1000/D COMMANDS AND PROVIDE THE FULL RANGE OF FUNCTIONS AVAILABLE ON THE FT-1000/D * TO MAXIMISE COMPATIBILITY WITH RIGCTL. * G0OAN */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft990.h" // FT990 native commands enum ft990_native_cmd_e { FT990_NATIVE_SPLIT_OFF = 0, FT990_NATIVE_SPLIT_ON, FT990_NATIVE_RECALL_MEM, FT990_NATIVE_VFO_TO_MEM, FT990_NATIVE_LOCK_OFF, FT990_NATIVE_LOCK_ON, FT990_NATIVE_VFO_A, FT990_NATIVE_VFO_B, FT990_NATIVE_MEM_TO_VFO, FT990_NATIVE_VFO_STEP_UP, FT990_NATIVE_VFO_STEP_UP_FAST, FT990_NATIVE_VFO_STEP_DOWN, FT990_NATIVE_VFO_STEP_DOWN_FAST, FT990_NATIVE_RX_CLARIFIER_OFF, FT990_NATIVE_RX_CLARIFIER_ON, FT990_NATIVE_TX_CLARIFIER_OFF, FT990_NATIVE_TX_CLARIFIER_ON, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET, FT990_NATIVE_CLARIFIER_OPS, FT990_NATIVE_FREQ_SET, FT990_NATIVE_MODE_SET_LSB, FT990_NATIVE_MODE_SET_USB, FT990_NATIVE_MODE_SET_CW_W, FT990_NATIVE_MODE_SET_CW_N, FT990_NATIVE_MODE_SET_AM_W, FT990_NATIVE_MODE_SET_AM_N, FT990_NATIVE_MODE_SET_FM, FT990_NATIVE_MODE_SET_RTTY_LSB, FT990_NATIVE_MODE_SET_RTTY_USB, FT990_NATIVE_MODE_SET_PKT_LSB, FT990_NATIVE_MODE_SET_PKT_FM, FT990_NATIVE_PACING, FT990_NATIVE_PTT_OFF, FT990_NATIVE_PTT_ON, FT990_NATIVE_UPDATE_ALL_DATA, FT990_NATIVE_UPDATE_MEM_CHNL, FT990_NATIVE_UPDATE_OP_DATA, FT990_NATIVE_UPDATE_VFO_DATA, FT990_NATIVE_UPDATE_MEM_CHNL_DATA, FT990_NATIVE_TUNER_OFF, FT990_NATIVE_TUNER_ON, FT990_NATIVE_TUNER_START, FT990_NATIVE_RPTR_SHIFT_NONE, FT990_NATIVE_RPTR_SHIFT_MINUS, FT990_NATIVE_RPTR_SHIFT_PLUS, FT990_NATIVE_VFO_TO_VFO, FT990_NATIVE_BANDWIDTH, FT990_NATIVE_OP_FREQ_STEP_UP, FT990_NATIVE_OP_FREQ_STEP_DOWN, FT990_NATIVE_READ_METER, FT990_NATIVE_DIM_LEVEL, FT990_NATIVE_RPTR_OFFSET, FT990_NATIVE_READ_FLAGS, FT990_NATIVE_SIZE }; /* HAMLIB API implementation */ static int ft990_init(RIG *rig); static int ft990_cleanup(RIG *rig); static int ft990_open(RIG *rig); static int ft990_close(RIG *rig); static int ft990_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft990_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft990_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft990_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft990_set_vfo(RIG *rig, vfo_t vfo); static int ft990_get_vfo(RIG *rig, vfo_t *vfo); static int ft990_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft990_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft990_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft990_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); static int ft990_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft990_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft990_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft990_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft990_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft990_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft990_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft990_set_parm(RIG *rig, setting_t parm, value_t val); static int ft990_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft990_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft990_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft990_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft990_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft990_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft990_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ft990_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); /* Private helper function prototypes */ static int ft990_get_update_data(RIG *rig, unsigned char ci, unsigned short ch); static int ft990_send_static_cmd(RIG *rig, unsigned char ci); static int ft990_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft990_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft990_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* Split (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* Split (On) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* Memory Operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* Lock (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* Lock (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* Select VFO (B) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* Copy Memory Data to VFO A */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* OP Freq Up 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x07 } }, /* OP Freq Up 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* OP Freq Down 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x08 } }, /* OP Freq Down 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* RX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* RX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* TX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* TX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0xff, 0x09 } }, /* Clear Clarifier Offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* Clarifier */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW 500Hz */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM 6KHz */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* OP Mode Set AM 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* OP Mode Set FM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* OP Mode Set PKT LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* OP Mode Set PKT FM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* Pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* Update All Data (1508 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Update Memory Ch Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* Tuner (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* Tuner (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* Tuner (Start) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* Repeater Mode (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* Repeater Mode (Minus) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* Repeater Mode (Plus) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy displayed VFO (A=B || B=A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8C } }, /* Select Bandwidth */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8E } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8E } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf8 } }, /* DIM Level */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* Set Offset for Repeater Shift */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* * Private data */ struct ft990_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of CAT cmd */ ft990_update_data_t update_data; /* returned data */ }; /* * ft990 rigs capabilities. */ #define FT990_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } struct rig_caps ft990_caps = { RIG_MODEL(RIG_MODEL_FT990), .model_name = "FT-990", .mfg_name = "Yaesu", .version = "20211231.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT990_WRITE_DELAY, .post_write_delay = FT990_POST_WRITE_DELAY, .timeout = 2000, .retry = 0, .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | \ RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_BACKLIGHT, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 90, RIG_MTYPE_MEM, FT990_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(1, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT990_ALL_RX_MODES, -1, -1, FT990_VFO_ALL, FT990_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT990_OTHER_TX_MODES, W(5), W(100), FT990_VFO_ALL, FT990_ANTS), FRQ_RNG_HF(2, FT990_AM_TX_MODES, W(2), W(25), FT990_VFO_ALL, FT990_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT990_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT990_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT990_AM_RX_MODES, Hz(100)}, /* Normal */ {FT990_AM_RX_MODES, kHz(1)}, /* Fast */ {FT990_FM_RX_MODES, Hz(100)}, /* Normal */ {FT990_FM_RX_MODES, kHz(1)}, /* Fast */ {FT990_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT990_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft990_init, .rig_cleanup = ft990_cleanup, .rig_open = ft990_open, /* port opened */ .rig_close = ft990_close, /* port closed */ .set_freq = ft990_set_freq, .get_freq = ft990_get_freq, .set_mode = ft990_set_mode, .get_mode = ft990_get_mode, .set_vfo = ft990_set_vfo, .get_vfo = ft990_get_vfo, .set_ptt = ft990_set_ptt, .get_ptt = ft990_get_ptt, .set_rptr_shift = ft990_set_rptr_shift, .get_rptr_shift = ft990_get_rptr_shift, .set_rptr_offs = ft990_set_rptr_offs, .set_split_vfo = ft990_set_split_vfo, .get_split_vfo = ft990_get_split_vfo, .set_rit = ft990_set_rit, .get_rit = ft990_get_rit, .set_xit = ft990_set_xit, .get_xit = ft990_get_xit, .set_func = ft990_set_func, .get_func = ft990_get_func, .set_parm = ft990_set_parm, .get_level = ft990_get_level, .set_mem = ft990_set_mem, .get_mem = ft990_get_mem, .vfo_op = ft990_vfo_op, .set_channel = ft990_set_channel, .get_channel = ft990_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init */ int ft990_init(RIG *rig) { struct ft990_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft990_priv_data *) calloc(1, sizeof(struct ft990_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; // Set default pacing value priv->pacing = FT990_PACING_DEFAULT_VALUE; // Set operating vfo mode to current VFO priv->current_vfo = RIG_VFO_MAIN; return RIG_OK; } /* * rig_cleanup */ int ft990_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open */ int ft990_open(RIG *rig) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } // Get current rig settings and status err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_close */ int ft990_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft990_priv_data *priv; int err; vfo_t vfo_save; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); // Frequency range sanity check if (freq < 100000 || freq > 30000000) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; vfo_save = priv->current_vfo; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != vfo_save) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990_send_dial_freq(rig, FT990_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } if (vfo != vfo_save) { err = ft990_set_vfo(rig, vfo_save); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft990_priv_data *priv; unsigned char *p; freq_t f; int err; int ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = priv->update_data.vfoa.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = priv->update_data.vfob.basefreq; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = priv->update_data.current_front.basefreq; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update data structure to obtain get frequency err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: p0=0x%02x p1=0x%02x p2=0x%02x\n", __func__, p[0], p[1], p[2]); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); // Frequency sanity check if (f < 100000 || f > 30000000) { return -RIG_EINVAL; } *freq = f; return RIG_OK; } /* * rig_set_ptt* * * Control PTT for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft990_priv_data *priv; int err; unsigned char ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (ptt) { case RIG_PTT_ON: ci = FT990_NATIVE_PTT_ON; break; case RIG_PTT_OFF: ci = FT990_NATIVE_PTT_OFF; break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt* * * Get PTT line status * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * ptt * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the PTT status * is independent from the VFO selection. */ int ft990_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } *ptt = ((priv->update_data.flag1 & FT990_SF_XMIT) != 0); rig_debug(RIG_DEBUG_TRACE, "%s: set ptt = 0x%02x\n", __func__, *ptt); return RIG_OK; } /* * rig_set_rptr_shift* * * Set repeater shift for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | - = negative repeater shift, * | | + = positive repeater shift, * | | any other character = simplex (is this a bug?) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be set when in FM mode. */ int ft990_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct ft990_priv_data *priv; unsigned char ci; char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rptr_shift = 0x%02x\n", __func__, rptr_shift); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Construct update query switch (vfo) { case RIG_VFO_A: p = (char *) &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (char *) &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: p = (char *) &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, *p); // Shift mode settings are only valid in FM mode if ((*p & FT990_MODE_FM) == 0) { return -RIG_EINVAL; } // Construct repeater shift command switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: ci = FT990_NATIVE_RPTR_SHIFT_NONE; break; case RIG_RPT_SHIFT_MINUS: ci = FT990_NATIVE_RPTR_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: ci = FT990_NATIVE_RPTR_SHIFT_PLUS; break; default: return -RIG_EINVAL; } // Set repeater shift err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rptr_shift* * * Get repeater shift setting for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * shift * | output | 0 = simplex * | | 1 = negative repeater shift * | | 2 = positive repeater shift * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be obtained when in FM mode. */ int ft990_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct ft990_priv_data *priv; ft990_op_data_t *p; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, p->mode); // Shift mode settings are only valid in FM mode if (p->mode & FT990_MODE_FM) { *rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } else { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set rptr shift = 0x%02x\n", __func__, *rptr_shift); return RIG_OK; } /* * rig_set_rptr_offs* * * Set repeater frequency offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * off | input | 0 - 199999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * repeater frequency offset is independent from the VFO selection. */ int ft990_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char bcd[(int) FT990_BCD_RPTR_OFFSET / 2]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed offs = %d\n", __func__, (int)offs); // Check for valid offset if (offs < 0 || offs > 199999) { return -RIG_EINVAL; } to_bcd(bcd, offs / 10, FT990_BCD_RPTR_OFFSET); rig_debug(RIG_DEBUG_TRACE, "%s: set bcd[0] = 0x%02x, bcd[1] = 0x%02x, bcd[2] = 0x%02x\n", __func__, bcd[0], bcd[1], bcd[2]); err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_RPTR_OFFSET, 0, bcd[2], bcd[1], bcd[0]); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ int ft990_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft990_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo = priv->current.vfo = 0x%02x\n", __func__, vfo); } if (tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = priv->current.vfo = 0x%02x\n", __func__, tx_vfo); } // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if (vfo == tx_vfo || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } // Set TX VFO first if RIG_VFO_MEM selected for RX VFO if (vfo == RIG_VFO_MEM) { err = ft990_set_vfo(rig, tx_vfo); if (err != RIG_OK) { return err; } } // Set RX VFO err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } switch (split) { case RIG_SPLIT_ON: ci = FT990_NATIVE_SPLIT_ON; break; case RIG_SPLIT_OFF: ci = FT990_NATIVE_SPLIT_OFF; break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored in order to * preserve the current split vfo system settings. */ int ft990_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Read status flags err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } // Get split mode status *split = priv->update_data.flag1 & FT990_SF_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, *split); // Get transmit vfo switch (priv->current_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: if (priv->update_data.flag1 & FT990_SF_VFOB) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx_vfo = 0x%02x\n", __func__, *tx_vfo); return RIG_OK; } /* * rig_set_rit* * * Set receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * rit = 0 && xit enabled -> disable rit * rit = 0 && xit disabled -> disable rit and set frequency = 0 */ int ft990_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)rit); // Check for valid clarifier offset frequency if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // If rit = 0 disable RX clarifier if (rit == 0) { err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_TX_EN) == 0) { err = ft990_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } // Disable RX Clarifier err = ft990_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable RX Clarifier err = ft990_send_static_cmd(rig, FT990_NATIVE_RX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set RX clarifier offset err = ft990_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_rit* * * Get receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft990_priv_data *priv; unsigned char ci; ft990_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } // Get update for selected VFO/MEM err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_RX_EN) { *rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *rit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: rit freq = %li Hz\n", __func__, *rit); return RIG_OK; } /* * rig_set_xit* * * Set transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * xit = 0 && rit enabled -> disable xit * xit = 0 && rit disabled -> disable xit and set frequency = 0 */ int ft990_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)xit); if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Disable TX clarifier and return if xit = 0 if (xit == 0) { err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT990_CLAR_RX_EN) == 0) { err = ft990_send_static_cmd(rig, FT990_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } err = ft990_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable TX Clarifier err = ft990_send_static_cmd(rig, FT990_NATIVE_TX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set TX clarifier offset err = ft990_send_rit_freq(rig, FT990_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_xit* * * Get transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct ft990_priv_data *priv; unsigned char ci; ft990_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT990_NATIVE_UPDATE_VFO_DATA; p = (ft990_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT990_NATIVE_UPDATE_OP_DATA; p = (ft990_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT990_CLAR_TX_EN) { *xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *xit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, *xit); return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER * status | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig functions are vfo independent. */ int ft990_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_LOCK: if (status) { ci = FT990_NATIVE_LOCK_ON; } else { ci = FT990_NATIVE_LOCK_OFF; } break; case RIG_FUNC_TUNER: if (status) { ci = FT990_NATIVE_TUNER_ON; } else { ci = FT990_NATIVE_TUNER_OFF; } break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get status of a rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER, MON * status * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig function are vfo independent. */ int ft990_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); priv = (struct ft990_priv_data *)STATE(rig)->priv; err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } switch (func) { case RIG_FUNC_LOCK: *status = ((priv->update_data.flag2 & FT990_SF_LOCKED) != 0); break; case RIG_FUNC_TUNER: *status = ((priv->update_data.flag3 & FT990_SF_TUNER_ON) != 0); break; case RIG_FUNC_MON: *status = ((priv->update_data.flag3 & FT990_SF_XMIT_MON) != 0); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_parm* * * Set rig parameters that are not VFO specific * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * parm | input | BACKLIGHT * val | input | 0.0..1.0 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: */ int ft990_set_parm(RIG *rig, setting_t parm, value_t val) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed parm = %s\n", __func__, rig_strparm(parm)); rig_debug(RIG_DEBUG_TRACE, "%s: passed val = %f\n", __func__, val.f); switch (parm) { case RIG_PARM_BACKLIGHT: err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_DIM_LEVEL, (unsigned char)(0x0d * val.f), 0, 0, 0); break; default: return -RIG_EINVAL; } if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_mode* * * Set operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width | input | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft990_priv_data *priv; unsigned char bw; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft990_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (mode) { case RIG_MODE_AM: if (width == rig_passband_narrow(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_N; } else if (width == rig_passband_normal(rig, mode)) { ci = FT990_NATIVE_MODE_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT990_NATIVE_MODE_SET_CW_W; break; case RIG_MODE_USB: ci = FT990_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: ci = FT990_NATIVE_MODE_SET_LSB; break; case RIG_MODE_RTTY: ci = FT990_NATIVE_MODE_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT990_NATIVE_MODE_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT990_NATIVE_MODE_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT990_NATIVE_MODE_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT990_NATIVE_MODE_SET_PKT_FM; break; default: return -RIG_EINVAL; } err = ft990_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT990_NATIVE_MODE_SET_AM_N || ci == FT990_NATIVE_MODE_SET_AM_W || ci == FT990_NATIVE_MODE_SET_FM || ci == FT990_NATIVE_MODE_SET_PKT_FM) { return RIG_OK; } if (width <= 250) { bw = FT990_BW_F250; } else if (width <= 500) { bw = FT990_BW_F500; } else if (width <= 2000) { bw = FT990_BW_F2000; } else { bw = FT990_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_mode* * * Get operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width * | output | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft990_priv_data *priv; unsigned char *p; unsigned char *fl; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_B: p = &priv->update_data.vfob.mode; ci = FT990_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfob.filter; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front.mode; ci = FT990_NATIVE_UPDATE_OP_DATA; fl = &priv->update_data.current_front.filter; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft990_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: fl = 0x%02x\n", __func__, *fl); rig_debug(RIG_DEBUG_TRACE, "%s: current mode = 0x%02x\n", __func__, *p); switch (*p) { case FT990_MODE_LSB: *mode = RIG_MODE_LSB; break; case FT990_MODE_USB: *mode = RIG_MODE_USB; break; case FT990_MODE_CW: *mode = RIG_MODE_CW; break; case FT990_MODE_AM: *mode = RIG_MODE_AM; break; case FT990_MODE_FM: *mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_RTTYR; } else { *mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (*fl & FT990_BW_FMPKTRTTY) { *mode = RIG_MODE_PKTFM; } else { *mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get mode = %s\n", __func__, rig_strrmode(*mode)); // The FT990 firmware appears to have a bug since the // AM bandwidth for 2400Hz and 6000Hz are interchanged. switch (*fl & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 8000; } else if (*mode == RIG_MODE_AM) // <- FT990 firmware bug? { *width = 6000; } else { *width = 2400; } break; case FT990_BW_F2000: *width = 2000; break; case FT990_BW_F500: *width = 500; break; case FT990_BW_F250: *width = 250; break; case FT990_BW_F6000: *width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get width = %li Hz\n", __func__, *width); return RIG_OK; } /* * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_set_vfo(RIG *rig, vfo_t vfo) { struct ft990_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_A; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_B; break; case RIG_VFO_MEM: ci = FT990_NATIVE_RECALL_MEM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set ci = %i\n", __func__, ci); if (vfo == RIG_VFO_MEM) { err = ft990_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->update_data.channelnumber + 1); } else { err = ft990_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } priv->current_vfo = vfo; return RIG_OK; } /* * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * The result is stored in the priv->current_vfo data structure * for later retrieval. */ int ft990_get_vfo(RIG *rig, vfo_t *vfo) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } if (priv->update_data.flag2 & FT990_SF_MEM || priv->update_data.flag2 & FT990_SF_MTUNE) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.flag1 & FT990_SF_VFOB) { priv->current_vfo = RIG_VFO_B; } else { priv->current_vfo = RIG_VFO_A; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_2 = 0x%02x\n", __func__, priv->update_data.flag2); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, priv->current_vfo); *vfo = priv->current_vfo; return RIG_OK; } /* * rig_get_level * * This function will read the meter level.The data * is processed depending upon selection of the level * parameter. The following are the currently supported * levels and returned value range: * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * level | input | STRENGTH, ALC, COMP, RFPOWER, SWR * value * | output | see table below * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * ---------------------------------------------------------- * level | Description | Returned Value | Units | * ---------------------------------------------------------- * STRENGTH | Signal Strength | -54 .. +60 | db | * COMP | Compression | 0.0 .. 1.0 | %/100 | * RFPOWER | RF Power Output | 0.0 .. 1.0 | %/100 | * SWR | Standing Wave Ratio | 0.0 .. 1.0 | %/100 | * ---------------------------------------------------------- * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value) { struct ft990_priv_data *priv; unsigned char mdata[YAESU_CMD_LENGTH]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed level %s\n", __func__, rig_strlevel(level)); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft990_send_static_cmd(rig, FT990_NATIVE_READ_METER); if (err != RIG_OK) { return err; } err = read_block(RIGPORT(rig), mdata, FT990_READ_METER_LENGTH); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: meter data %d\n", __func__, mdata[0]); switch (level) { case RIG_LEVEL_STRENGTH: value->i = mdata[0] / 2.246 - 54; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %d\n", __func__, value->i); break; case RIG_LEVEL_ALC: case RIG_LEVEL_COMP: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_SWR: value->f = (float) mdata[0] / 255; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %f\n", __func__, value->f); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op* * * Perform vfo operations * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | VFOA, VFOB, MEM * op | input | CPY = copy from VFO to VFO * | | FROM_VFO = copy from VFO to MEM * | | TO_VFO = copy from MEM to VFO * | | UP = step dial frequency up * | | DOWN = step dial frequency down * | | TUNE = start antenna tuner * | | TOGGLE = toggle between VFOA and VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ int ft990_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ft990_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed op %s\n", __func__, rig_strvfop(op)); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft990_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (op) { case RIG_OP_CPY: ci = FT990_NATIVE_VFO_TO_VFO; break; case RIG_OP_FROM_VFO: ci = FT990_NATIVE_VFO_TO_MEM; break; case RIG_OP_TO_VFO: ci = FT990_NATIVE_MEM_TO_VFO; break; case RIG_OP_UP: ci = FT990_NATIVE_OP_FREQ_STEP_UP; break; case RIG_OP_DOWN: ci = FT990_NATIVE_OP_FREQ_STEP_DOWN; break; case RIG_OP_TUNE: ci = FT990_NATIVE_TUNER_START; break; case RIG_OP_TOGGLE: switch (vfo) { case RIG_VFO_A: ci = FT990_NATIVE_VFO_B; vfo = RIG_VFO_B; break; case RIG_VFO_B: ci = FT990_NATIVE_VFO_A; vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (op == RIG_OP_TO_VFO || op == RIG_OP_FROM_VFO) err = ft990_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); else { err = ft990_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } if (op == RIG_OP_TOGGLE) { priv->current_vfo = vfo; } return RIG_OK; } /* * rig_set_mem* * * Set main vfo to selected memory channel number * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch | input | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the channel selection is vfo independent. */ int ft990_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ch = %i\n", __func__, ch); priv = (struct ft990_priv_data *) STATE(rig)->priv; // Check for valid channel number if (ch < 1 || ch > 90) { return -RIG_EINVAL; } // Recall selected memory channel err = ft990_send_dynamic_cmd(rig, FT990_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = RIG_VFO_MEM; priv->update_data.channelnumber = ch - 1; return RIG_OK; } /* * rig_get_mem* * * Get memory channel number used by main vfo * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch * | output | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since * the channel selection is vfo independent. */ int ft990_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: channel number %i\n", __func__, priv->update_data.channelnumber + 1); *ch = priv->update_data.channelnumber + 1; // Check for valid channel number if (*ch < 1 || *ch > 90) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_channel* * * Set memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | channel attribute data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure */ int ft990_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return -RIG_ENIMPL; } /* * rig_get_channel* * * Get memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | (chan->vfo) currVFO, VFOA, VFOB, MEM * | | (chan->channel_num) 0 - 90 * chan * | output | channel attributes data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing a memory channel number of 0 returns information on * the current channel or channel last in use. * * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ int ft990_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ft990_priv_data *priv; ft990_op_data_t *p; char ci; int err; channel_t _chan; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->vfo = %s\n", __func__, rig_strvfo(chan->vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->channel_num = %i\n", __func__, chan->channel_num); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (chan->channel_num < 0 || chan->channel_num > 90) { return -RIG_EINVAL; } /* * Get a clean slate so we don't have to assign value to * variables that are not relevant to this equipment */ _chan.channel_num = chan->channel_num; _chan.vfo = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = _chan.channel_num; chan->vfo = _chan.vfo; if (chan->channel_num == 0) { switch (chan->vfo) { // Current or last selected memory channel case RIG_VFO_MEM: err = ft990_get_update_data(rig, FT990_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } chan->channel_num = priv->update_data.channelnumber + 1; p = (ft990_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; break; case RIG_VFO_A: p = (ft990_op_data_t *) &priv->update_data.vfoa; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (ft990_op_data_t *) &priv->update_data.vfob; ci = FT990_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_CURR: p = (ft990_op_data_t *) &priv->update_data.current_front; ci = FT990_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } } else { p = (ft990_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT990_NATIVE_UPDATE_MEM_CHNL_DATA; chan->vfo = RIG_VFO_MEM; } /* * Get data for selected VFO/MEM */ err = ft990_get_update_data(rig, ci, chan->channel_num); if (err != RIG_OK) { return err; } // Blanked memory, nothing to report if (p->bpf & FT990_EMPTY_MEM) { return RIG_OK; } /* * Get RX frequency */ chan->freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_RTTYR; } else { chan->mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->mode = RIG_MODE_PKTFM; } else { chan->mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = 0x%02x\n", __func__, p->mode); rig_debug(RIG_DEBUG_TRACE, "%s: filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->width = 8000; } else if (chan->mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->width = 6000; } else { chan->width = 2400; } break; case FT990_BW_F2000: chan->width = 2000; break; case FT990_BW_F500: chan->width = 500; break; case FT990_BW_F250: chan->width = 250; break; case FT990_BW_F6000: chan->width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } err = ft990_get_update_data(rig, FT990_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, priv->update_data.flag1); /* * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ if (chan->vfo & RIG_VFO_CURR) { chan->split = (priv->update_data.flag1 & FT990_SF_SPLIT); if (priv->update_data.flag1 & FT990_SF_XMIT_MON) { chan->funcs |= RIG_FUNC_MON; } if (priv->update_data.flag1 & FT990_SF_TUNER_ON) { chan->funcs |= RIG_FUNC_TUNER; } if (priv->update_data.flag1 & FT990_SF_FAST) { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 1000; } else { chan->tuning_step = 100; } } else { if (chan->mode & (FT990_AM_RX_MODES | FT990_FM_RX_MODES)) { chan->tuning_step = 100; } else { chan->tuning_step = 10; } } } /* * Get RIT frequencies */ if (p->status & FT990_CLAR_RX_EN) { chan->rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } if (chan->split & RIG_SPLIT_ON) { // Get data for the transmit VFO p = (ft990_op_data_t *) &priv->update_data.current_rear; /* FT1000D * if (RIG_MODEL_FT1000D == rig->caps->rig_model) * p = (ft990_op_data_t *) &priv->update_data.vfob; * chan->tx_freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + * p->basefreq[2]) * 10; * * THIS SECTION WAS REMOVED IN DECEMBER 2016. SEE SEPARATE ft1000d.c and .h FILES */ /* Get RX operating mode */ switch (p->mode) { case FT990_MODE_LSB: chan->tx_mode = RIG_MODE_LSB; break; case FT990_MODE_USB: chan->tx_mode = RIG_MODE_USB; break; case FT990_MODE_CW: chan->tx_mode = RIG_MODE_CW; break; case FT990_MODE_AM: chan->tx_mode = RIG_MODE_AM; break; case FT990_MODE_FM: chan->tx_mode = RIG_MODE_FM; break; case FT990_MODE_RTTY: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_RTTYR; } else { chan->tx_mode = RIG_MODE_RTTY; } break; case FT990_MODE_PKT: if (p->filter & FT990_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_PKTFM; } else { chan->tx_mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx mode = %s\n", __func__, rig_strrmode(chan->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: tx filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT990 firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT990_BW_FMPKTRTTY)) { case FT990_BW_F2400: if (chan->tx_mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->tx_width = 8000; } else if (chan->tx_mode == RIG_MODE_AM) // <- FT990 firmware bug? { chan->tx_width = 6000; } else { chan->tx_width = 2400; } break; case FT990_BW_F2000: chan->tx_width = 2000; break; case FT990_BW_F500: chan->tx_width = 500; break; case FT990_BW_F250: chan->tx_width = 250; break; case FT990_BW_F6000: chan->tx_width = 2400; // <- FT990 firmware bug? break; default: return -RIG_EINVAL; } if (priv->update_data.flag1 & FT990_SF_VFOB) { if (chan->tx_vfo & (RIG_VFO_A | RIG_VFO_MEM)) { chan->tx_vfo = RIG_VFO_B; } else if (chan->vfo & RIG_VFO_MEM) { chan->tx_vfo = RIG_VFO_A; } else { chan->tx_vfo = RIG_VFO_MEM; } } else { if (chan->vfo & RIG_VFO_A) { chan->tx_vfo = RIG_VFO_MEM; } else { chan->tx_vfo = RIG_VFO_A; } } /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } else { /* * RX/TX frequency, mode, bandwidth and vfo are identical in simplex mode */ chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->tx_vfo = chan->vfo; /* * Get XIT frequencies */ if (p->status & FT990_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, p->status); /* * Repeater shift only possible if transmit mode is FM */ if (chan->tx_mode & RIG_MODE_FM) { chan->rptr_shift = (p->status & FT990_RPT_MASK) >> 2; } /* * Check for skip channel for memory channels */ if (chan->vfo & RIG_VFO_MEM) { chan->flags |= RIG_CHFLAG_SKIP; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 990 has several ways to * get data and several ways to return it. * * Need to use this when doing ft990_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_get_update_data(RIG *rig, unsigned char ci, unsigned short ch) { struct ft990_priv_data *priv; int n; int err; int rl; unsigned char temp[5]; unsigned char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed ch 0x%02x\n", __func__, ch); if (!rig) { return -RIG_EINVAL; } priv = (struct ft990_priv_data *)STATE(rig)->priv; if (ci == FT990_NATIVE_UPDATE_MEM_CHNL_DATA) // P4 = 0x01 to 0x5a for channel 1 - 90 { err = ft990_send_dynamic_cmd(rig, ci, 4, 0, 0, ch); } else { err = ft990_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } switch (ci) { case FT990_NATIVE_UPDATE_ALL_DATA: return RIG_OK; break; case FT990_NATIVE_UPDATE_MEM_CHNL: p = (unsigned char *) &priv->update_data.channelnumber; rl = FT990_MEM_CHNL_LENGTH; break; case FT990_NATIVE_UPDATE_OP_DATA: p = (unsigned char *) &priv->update_data.current_front; rl = FT990_OP_DATA_LENGTH; break; case FT990_NATIVE_UPDATE_VFO_DATA: p = (unsigned char *) &priv->update_data.vfoa; rl = FT990_VFO_DATA_LENGTH; break; case FT990_NATIVE_UPDATE_MEM_CHNL_DATA: p = (unsigned char *) &priv->update_data.channel[ch]; rl = FT990_MEM_CHNL_DATA_LENGTH; break; case FT990_NATIVE_READ_FLAGS: p = temp; rl = FT990_STATUS_FLAGS_LENGTH; break; default: return -RIG_EINVAL; } n = read_block(RIGPORT(rig), p, rl); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); if (ci == FT990_NATIVE_READ_FLAGS) { memcpy(&priv->update_data, p, FT990_STATUS_FLAGS_LENGTH - 2); } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_static_cmd(RIG *rig, unsigned char ci) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(RIGPORT(rig), ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[3] = p1; priv->p_cmd[2] = p2; priv->p_cmd[1] = p3; priv->p_cmd[0] = p4; err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft990_priv_data *priv; int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft990_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT990_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT990_BCD_DIAL) * 10); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } /* * Private helper function to build and send a complete command to * change the rit frequency. * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ int ft990_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft990_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft990_priv_data *) STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } // Copy native command into privat command storage area memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); // Reset current clarifier offset priv->p_cmd[3] = FT990_CLAR_CLEAR; // Check and set tuning direction - up or down if (rit < 0) { priv->p_cmd[2] = FT990_CLAR_TUNE_DOWN; } else { priv->p_cmd[2] = FT990_CLAR_TUNE_UP; } // Store bcd format into privat command storage area to_bcd(priv->p_cmd, labs(rit) / 10, FT990_BCD_RIT); err = write_block(RIGPORT(rig), (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft5000.c0000644000175000017500000003070414752216205013064 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft5000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-DX5000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft5000.h" #include "tones.h" const struct newcat_priv_caps ftdx5000_priv_caps = { .roofing_filter_count = 11, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = '4', .get_value = '7', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = '8', .width = 300, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 7, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 8, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, { .index = 9, .set_value = 0, .get_value = '9', .width = 600, .optional = 0 }, { .index = 10, .set_value = 0, .get_value = 'A', .width = 300, .optional = 0 }, }, }; const struct confparams ftdx5000_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "600 Hz (Main)", "300 Hz (Main)", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", "AUTO - 600 Hz (Main)", "AUTO - 300 Hz (Main)", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "S. Narrow", "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx5000_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; struct rig_caps ftdx5000_caps = { RIG_MODEL(RIG_MODEL_FTDX5000), .model_name = "FTDX-5000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".11", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX5000_WRITE_DELAY, .post_write_delay = FTDX5000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX5000_FUNCS, .has_set_func = FTDX5000_FUNCS, .has_get_level = FTDX5000_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX5000_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_NOTCHF #define NO_LVL_COMP #define NO_LVL_VOXGAIN #include "level_gran_yaesu.h" #undef NO_LVL_NOTCHF #undef NO_LVL_COMP #undef NO_LVL_VOXGAIN [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_VOXGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, /* TBC: Not specified in manual */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX5000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_ANT | RIG_TARGETABLE_ROOFING, .transceive = RIG_TRN_OFF, /* May enable later as the 5000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT5000_RFPOWER_METER_CAL, .str_cal = FTDX5000_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m_REGION1(FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m_REGION1(FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS | RIG_ANT_5, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m_REGION2(FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m_REGION2(FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX5000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX5000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX5000_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX5000_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1700)}, /* Normal CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {FTDX5000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ {FTDX5000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ {FTDX5000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FTDX5000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx5000_ext_tokens, .extlevels = ftdx5000_ext_levels, .priv = &ftdx5000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft897.h0000644000175000017500000000444014752216205013032 00000000000000/* * ft897.h - (C) Tomi Manninen 2003 (oh2bns@sral.fi) * * ...derived but heavily modified from: * * ft817.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT897_H #define _FT897_H 1 /* * No need to wait between written characters. */ #define FT897_WRITE_DELAY 5 /* * Wait 'delay' milliseconds after writing a command sequence. * * Setting this to zero means no delay but wait for an acknowledgement * from the rig after a command. This is undocumented but seems to work. * It's also the most optimal way as long as it works... * * A non-zero value disables waiting for the ack. Processing a command * seems to take about 60 ms so set this to 80 or so to be safe. */ #define FT897_POST_WRITE_DELAY 0 /* * Read timeout. */ #define FT897_TIMEOUT 200 /* * The time the TX, RX and FREQ/MODE status are cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is deliberately set lower than the time taken to process * a single command (~ 60 ms) so that a sequence * * rig_get_freq(); * rig_set_freq(); * rig_get_freq(); * * doesn't return a bogus (cached) value in the last rig_get_freq(). */ #define FT897_CACHE_TIMEOUT 50 extern int ft857_set_vfo(RIG *rig, vfo_t vfo); extern int ft857_get_vfo(RIG *rig, vfo_t *vfo); #endif /* _FT897_H */ hamlib-4.6.2/rigs/yaesu/ft950.c0000644000175000017500000003113714752216205013016 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft950.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "yaesu.h" #include "newcat.h" #include "ft950.h" const struct newcat_priv_caps ft950_priv_caps = { .roofing_filter_count = 7, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, } }; const struct confparams ft950_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", NULL } } } }, { RIG_CONF_END, NULL, } }; int ft950_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_BACKEND_NONE }; /* * FT-950 rig capabilities */ struct rig_caps ft950_caps = { RIG_MODEL(RIG_MODEL_FT950), .model_name = "FT-950", .mfg_name = "Yaesu", .version = NEWCAT_VER ".5", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FT950_WRITE_DELAY, .post_write_delay = FT950_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FT950_FUNCS, .has_set_func = FT950_FUNCS, .has_get_level = FT950_LEVELS, .has_set_level = RIG_LEVEL_SET(FT950_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_CWPITCH #define NO_LVL_KEYSPD #define NO_LVL_NOTCHF #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_CWPITCH #undef NO_LVL_KEYSPD #undef NO_LVL_NOTCHF #undef NO_LVL_RFPOWER [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3000 }, .step = { .i = 10 } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FT950_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 950 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FT950_RFPOWER_METER_CAL, .str_cal = FT950_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 125, 128, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* 60M Channels U51-U54 or US1-US4, if available */ { 130, 130, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* 60M Channel U55 or US5, if available */ { 131, 131, RIG_MTYPE_BAND, NEWCAT_MEM_CAP }, /* EU5, 5167.5 KHz Alaska Emergency Freq, if available */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), MHz(56), FT950_ALL_RX_MODES, -1, -1, FT950_VFO_ALL, FT950_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, /* FIXME: Are these the correct Region 1 values? */ .tx_range_list1 = { FRQ_RNG_HF(1, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_HF(1, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ FRQ_RNG_6m(1, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_6m(1, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FT950_ALL_RX_MODES, -1, -1, FT950_VFO_ALL, FT950_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_HF(2, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ FRQ_RNG_6m(2, FT950_OTHER_TX_MODES, W(5), W(100), FT950_VFO_ALL, FT950_ANTS), FRQ_RNG_6m(2, FT950_AM_TX_MODES, W(2), W(25), FT950_VFO_ALL, FT950_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT950_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT950_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT950_AM_RX_MODES, Hz(100)}, /* Normal */ {FT950_AM_RX_MODES, kHz(1)}, /* Fast */ {FT950_FM_RX_MODES, Hz(100)}, /* Normal */ {FT950_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FT950_CW_RTTY_PKT_RX_MODES, Hz(1700)}, /* Normal CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(2000)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(1400)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(800)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(400)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(200)}, /* CW, RTTY, PKT */ {FT950_CW_RTTY_PKT_RX_MODES, Hz(100)}, /* CW, RTTY, PKT */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_SSB, Hz(2900)}, /* SSB */ {RIG_MODE_SSB, Hz(2800)}, /* SSB */ {RIG_MODE_SSB, Hz(2700)}, /* SSB */ {RIG_MODE_SSB, Hz(2600)}, /* SSB */ {RIG_MODE_SSB, Hz(2500)}, /* SSB */ {RIG_MODE_SSB, Hz(2250)}, /* SSB */ {RIG_MODE_SSB, Hz(2100)}, /* SSB */ {RIG_MODE_SSB, Hz(1950)}, /* SSB */ {RIG_MODE_SSB, Hz(1650)}, /* SSB */ {RIG_MODE_SSB, Hz(1500)}, /* SSB */ {RIG_MODE_SSB, Hz(1350)}, /* SSB */ {RIG_MODE_SSB, Hz(1100)}, /* SSB */ {RIG_MODE_SSB, Hz(850)}, /* SSB */ {RIG_MODE_SSB, Hz(600)}, /* SSB */ {RIG_MODE_SSB, Hz(400)}, /* SSB */ {RIG_MODE_SSB, Hz(200)}, /* SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ {FT950_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM */ {FT950_FM_WIDE_RX_MODES, Hz(9000)}, /* Narrow FM */ {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ {FT950_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ft950_ext_tokens, .extlevels = ft950_ext_levels, .priv = &ft950_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .set_ts = newcat_set_ts, .get_ts = newcat_get_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft847.c0000644000175000017500000016500314752216205013023 00000000000000/* * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft847.c - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * This shared library provides an API for communicating * via serial interface to an FT-847 using the "CAT" interface. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO - Remove static stuff, see ft747 for new style [started] * - create yaesu.h for common command structure etc..[started] * - add mode set before freq set to avoid prior mode offset (eg: CW) * */ /* * Notes on limitations in RIG control capabilities. These are * related to the Yaesu's FT847 design, not my program :-) * * 1. Rig opcodes allow only 10Hz resolution. * 2. Cannot select VFO B * 3. Using CAT and Tuner controls simultaneously can * cause problems. * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft847.h" #include "misc.h" #include "bandplan.h" #include "tones.h" /* * Native FT847 functions. This is what I have to work with :-) * */ enum ft847_native_cmd_e { /* Set commands to the rig */ FT_847_NATIVE_CAT_ON = 0, FT_847_NATIVE_CAT_OFF, FT_847_NATIVE_CAT_PTT_ON, FT_847_NATIVE_CAT_PTT_OFF, FT_847_NATIVE_CAT_SAT_MODE_ON, FT_847_NATIVE_CAT_SAT_MODE_OFF, FT_847_NATIVE_CAT_SET_FREQ_MAIN, FT_847_NATIVE_CAT_SET_FREQ_SAT_RX_VFO, FT_847_NATIVE_CAT_SET_FREQ_SAT_TX_VFO, FT_847_NATIVE_CAT_SET_MODE_MAIN_LSB, /* MAIN VFO */ FT_847_NATIVE_CAT_SET_MODE_MAIN_USB, FT_847_NATIVE_CAT_SET_MODE_MAIN_CW, FT_847_NATIVE_CAT_SET_MODE_MAIN_CWR, FT_847_NATIVE_CAT_SET_MODE_MAIN_AM, FT_847_NATIVE_CAT_SET_MODE_MAIN_FM, FT_847_NATIVE_CAT_SET_MODE_MAIN_CWN, FT_847_NATIVE_CAT_SET_MODE_MAIN_CWRN, FT_847_NATIVE_CAT_SET_MODE_MAIN_AMN, FT_847_NATIVE_CAT_SET_MODE_MAIN_FMN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_LSB, /* SAT RX VFO */ FT_847_NATIVE_CAT_SET_MODE_SAT_RX_USB, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CW, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CWR, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_AM, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_FM, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CWN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_CWRN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_AMN, FT_847_NATIVE_CAT_SET_MODE_SAT_RX_FMN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_LSB, /* SAT TX VFO */ FT_847_NATIVE_CAT_SET_MODE_SAT_TX_USB, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CW, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CWR, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_AM, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_FM, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CWN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_CWRN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_AMN, FT_847_NATIVE_CAT_SET_MODE_SAT_TX_FMN, FT_847_NATIVE_CAT_SET_DCS_ON_MAIN, /* MAIN CTCSS/DCS */ FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_MAIN, FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_MAIN, FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_MAIN, FT_847_NATIVE_CAT_SET_DCS_ON_SAT_RX, /* SAT RX CTCSS/DCS */ FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_SAT_RX, FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_SAT_RX, FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_SAT_RX, FT_847_NATIVE_CAT_SET_DCS_ON_SAT_TX, /* SAT TX CTCSS/DCS */ FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_SAT_TX, FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_SAT_TX, FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_SAT_TX, FT_847_NATIVE_CAT_SET_CTCSS_FREQ_MAIN, /* CTCSS Freq */ FT_847_NATIVE_CAT_SET_CTCSS_FREQ_SAT_RX, FT_847_NATIVE_CAT_SET_CTCSS_FREQ_SAT_TX, FT_847_NATIVE_CAT_SET_DCS_CODE_MAIN, /* DCS code */ FT_847_NATIVE_CAT_SET_DCS_CODE_SAT_RX, FT_847_NATIVE_CAT_SET_DCS_CODE_SAT_TX, FT_847_NATIVE_CAT_SET_RPT_SHIFT_MINUS, /* RPT SHIFT */ FT_847_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT_847_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT_847_NATIVE_CAT_SET_RPT_OFFSET, /* RPT Offset frequency */ /* Get info from the rig */ FT_847_NATIVE_CAT_GET_RX_STATUS, FT_847_NATIVE_CAT_GET_TX_STATUS, FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_MAIN, FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_SAT_RX, FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_SAT_TX, FT_847_NATIVE_SIZE /* end marker, value indicates number of */ /* native cmd entries */ }; typedef enum ft847_native_cmd_e ft847_native_cmd_t; /* * API local implementation */ static int ft847_init(RIG *rig); static int ft847_open(RIG *rig); static int ft847_cleanup(RIG *rig); static int ft847_close(RIG *rig); static int ft847_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft847_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft847_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft847_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft847_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft847_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft847_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft847_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft847_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft847_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft847_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft847_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft847_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft847_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft847_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft847_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft847_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft847_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft847_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft847_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs); /* * ft847 instance - private data * */ struct ft847_priv_data { split_t sat_mode; unsigned char rx_status; /* tx returned data */ unsigned char tx_status; /* rx returned data */ /* for early ft847's we keep our own memory items */ /* Early rigs are one-way com to the rig */ freq_t freqA, freqB; mode_t mode; pbwidth_t width; ptt_t ptt; }; /* prototypes */ static int ft847_send_priv_cmd(RIG *rig, int cmd_index); /* Native ft847 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* CAT = On */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* CAT = Off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x88 } }, /* ptt off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x4e } }, /* sat mode on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8e } }, /* sat mode off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq main */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x11 } }, /* set freq sat rx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x21 } }, /* set freq sat tx */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x82, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWN */ { 1, { 0x83, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWRN */ { 1, { 0x84, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AMN */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FMN */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx FM */ { 1, { 0x82, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CWN */ { 1, { 0x83, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx CWRN */ { 1, { 0x84, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx AMN */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x17 } }, /* mode set sat rx FMN */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx FM */ { 1, { 0x82, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CWN */ { 1, { 0x83, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx CWRN */ { 1, { 0x84, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx AMN */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x27 } }, /* mode set sat tx FMN */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on, main */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS enc/dec on, main */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS enc on, main */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off, main */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x1a } }, /* set DCS on, sat rx */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x1a } }, /* set CTCSS/DCS enc/dec on, sat rx */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x1a } }, /* set CTCSS/DCS enc on, sat rx */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x1a } }, /* set CTCSS/DCS off, sat rx */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x2a } }, /* set DCS on, sat tx */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x2a } }, /* set CTCSS/DCS enc/dec on, sat tx */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x2a } }, /* set CTCSS/DCS enc on, sat tx */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x2a } }, /* set CTCSS/DCS off, sat tx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS freq, main */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x1b } }, /* set CTCSS freq, sat rx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x2b } }, /* set CTCSS freq, sat tx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code, main */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x1c } }, /* set DCS code, sat rx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x2c } }, /* set DCS code, sat tx */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x49 } }, /* set RPT shift PLUS */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x89 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status, main */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x13 } }, /* get FREQ and MODE status, sat rx */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x23 } }, /* get FREQ and MODE status, sat tx */ }; /* * Receiver caps */ #define UNIDIRECTIONAL (rig->caps->rig_model == RIG_MODEL_FT847UNI || rig->caps->rig_model == RIG_MODEL_FT650) #define FT847_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM) #define FT847_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB) #define FT847_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) /* tx doesn't have WFM. * 100W in 160-6m (25 watts AM carrier) * 50W in 2m/70cm (12.5 watts AM carrier) */ #define FT847_OTHER_TX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define FT847_AM_TX_MODES (RIG_MODE_AM) #define FT847_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL) #define FT847_LEVEL_ALL (RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ALC) #define FT847_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB) /* FT-847 has different antennas connectors, but no rig_set_ant() ability */ #define FT847_ANTS RIG_ANT_1 #define FT847_STR_CAL { 3, \ { \ { 0, -60 }, /* S0 */ \ { 16, 0 }, /* S9 */ \ { 31, 60 }, /* +60 dB */ \ } } /* * 39 CTCSS sub-audible tones * c.f. ft847_set_ctcss_tone() */ static tone_t ft847_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }; #if 0 static tone_t ft650_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0 }; #endif /* * ft847 rig capabilities. * Notice that some rigs share the same functions. */ struct rig_caps ft847_caps = { RIG_MODEL(RIG_MODEL_FT847), .model_name = "FT-847", .mfg_name = "Yaesu", .version = "20230512.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, .has_get_level = FT847_LEVEL_ALL, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft847_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FT847_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { FRQ_RNG_HF(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .tuning_steps = { {FT847_SSB_CW_RX_MODES, 1}, /* normal */ {FT847_SSB_CW_RX_MODES, 10}, /* fast */ {FT847_SSB_CW_RX_MODES, 100}, /* faster */ {FT847_AM_FM_RX_MODES, 10}, /* normal */ {FT847_AM_FM_RX_MODES, 100}, /* fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ .set_split_vfo = ft847_set_split_vfo, .get_split_vfo = ft847_get_split_vfo, .set_split_freq = ft847_set_split_freq, .get_split_freq = ft847_get_split_freq, .set_split_mode = ft847_set_split_mode, .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ .get_dcd = ft847_get_dcd, /* get dcd */ .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, .set_ctcss_sql = ft847_set_ctcss_sql, .set_dcs_sql = ft847_set_dcs_sql, .set_rptr_shift = ft847_set_rptr_shift, .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft600 rigs capabilities. * Notice that some rigs share the same functions. */ struct rig_caps ft650_caps = { RIG_MODEL(RIG_MODEL_FT650), .model_name = "FT-650", .mfg_name = "Yaesu", .version = "20230512.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, //.has_get_level = FT847_LEVEL_ALL, //.has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, //.ctcss_list = ft847_ctcss_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), //.targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {MHz(24.5), MHz(56), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_4m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {MHz(24.5), MHz(56), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { {kHz(24500), kHz(25000), FT847_OTHER_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(24500), kHz(25000), FT847_AM_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(28000), kHz(29700), FT847_OTHER_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(28000), kHz(29700), FT847_AM_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(50000), kHz(54000), FT847_OTHER_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, {kHz(50000), kHz(54000), FT847_AM_TX_MODES, W(10), W(100), FT847_VFOS, FT847_ANTS}, RIG_FRNG_END, }, /* tx range end */ .tuning_steps = { {RIG_MODE_ALL, 1}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.4)}, {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_SSB, kHz(2.0)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_CW, Hz(1200)}, {RIG_MODE_CW, Hz(600)}, {RIG_MODE_CW, Hz(300)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ // .set_split_vfo = ft847_set_split_vfo, // .get_split_vfo = ft847_get_split_vfo, // .set_split_freq = ft847_set_split_freq, // .get_split_freq = ft847_get_split_freq, // .set_split_mode = ft847_set_split_mode, // .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ // .get_dcd = ft847_get_dcd, /* get dcd */ // .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, // .set_ctcss_sql = ft847_set_ctcss_sql, // .set_dcs_sql = ft847_set_dcs_sql, // .set_rptr_shift = ft847_set_rptr_shift, // .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps mchfqrp_caps = { RIG_MODEL(RIG_MODEL_MCHFQRP), .model_name = "mcHF QRP", .mfg_name = "M0NKA", .version = "20230512.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, .has_get_level = FT847_LEVEL_ALL, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft847_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FT847_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, /* rx range begin */ // {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, // {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, // {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_4m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_4m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(1, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(1, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, /* rx range begin */ // {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, // {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, // {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { FRQ_RNG_HF(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), // FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), // FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .tuning_steps = { {FT847_SSB_CW_RX_MODES, 1}, /* normal */ {FT847_SSB_CW_RX_MODES, 10}, /* fast */ {FT847_SSB_CW_RX_MODES, 100}, /* faster */ {FT847_AM_FM_RX_MODES, 10}, /* normal */ {FT847_AM_FM_RX_MODES, 100}, /* fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ .set_split_vfo = ft847_set_split_vfo, .get_split_vfo = ft847_get_split_vfo, .set_split_freq = ft847_set_split_freq, .get_split_freq = ft847_get_split_freq, .set_split_mode = ft847_set_split_mode, .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ .get_dcd = ft847_get_dcd, /* get dcd */ .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, .set_ctcss_sql = ft847_set_ctcss_sql, .set_dcs_sql = ft847_set_dcs_sql, .set_rptr_shift = ft847_set_rptr_shift, .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft847uni rigs capabilities. * Notice that some rigs share the same functions. * Also this struct is READONLY! Yaesu appears to use the following format for serial numbers on their amateur products: Year of manufacture-Month of manufacture-Production Run-Individual Unit number, where the month of manufacture is offset by 2, so "C" means January, "D" means February, "E" means March, and so forth. Example: 8G051234 = 1998, May (fifth month, or "G"), Production Run 05, unit #1234 in this run. One key serial number range is 8G05. This seems to be the point at which Yaesu had corrected the bi-directional CAT issue and made some other improvements. This version was made in May 1998. Later serial numbers (e.g., 8L09nnnn) all seem to have incorporated the earlier improvements plus new ones...." */ struct rig_caps ft847uni_caps = { RIG_MODEL(RIG_MODEL_FT847UNI), .model_name = "FT-847UNI", .mfg_name = "Yaesu", .version = "20230511.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT847_WRITE_DELAY, .post_write_delay = FT847_POST_WRITE_DELAY, .timeout = 1000, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT847_FUNC_ALL, .has_get_level = FT847_LEVEL_ALL, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft847_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, /* no preamp/att in CAT */ .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_TONE | RIG_TARGETABLE_FUNC, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FT847_STR_CAL, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan list: 78, but only in clonable mode? */ .rx_range_list1 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "EUR"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list1 = { FRQ_RNG_HF(1, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(1, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, /* tx range end */ .rx_range_list2 = { {kHz(100), MHz(30), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, /* rx range begin */ {MHz(36), MHz(76), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(108), MHz(174), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, {MHz(420), MHz(512), FT847_ALL_RX_MODES, -1, -1, FT847_VFOS, FT847_ANTS, "USA"}, RIG_FRNG_END, }, /* rx range end */ .tx_range_list2 = { FRQ_RNG_HF(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_HF(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_OTHER_TX_MODES, W(5), W(100), FT847_VFOS, FT847_ANTS), FRQ_RNG_6m(2, FT847_AM_TX_MODES, W(1), W(25), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_2m(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_OTHER_TX_MODES, W(1), W(50), FT847_VFOS, FT847_ANTS), FRQ_RNG_70cm(2, FT847_AM_TX_MODES, W(1), W(12.5), FT847_VFOS, FT847_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT847_SSB_CW_RX_MODES, 1}, /* normal */ {FT847_SSB_CW_RX_MODES, 10}, /* fast */ {FT847_SSB_CW_RX_MODES, 100}, /* faster */ {FT847_AM_FM_RX_MODES, 10}, /* normal */ {FT847_AM_FM_RX_MODES, 100}, /* fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(9)}, RIG_FLT_END, }, .priv = NULL, .rig_init = ft847_init, .rig_cleanup = ft847_cleanup, .rig_open = ft847_open, .rig_close = ft847_close, .set_freq = ft847_set_freq, /* set freq */ .get_freq = ft847_get_freq, /* get freq */ .set_mode = ft847_set_mode, /* set mode */ .get_mode = ft847_get_mode, /* get mode */ .set_split_vfo = ft847_set_split_vfo, .get_split_vfo = ft847_get_split_vfo, .set_split_freq = ft847_set_split_freq, .get_split_freq = ft847_get_split_freq, .set_split_mode = ft847_set_split_mode, .get_split_mode = ft847_get_split_mode, .set_ptt = ft847_set_ptt, /* set ptt */ .get_ptt = ft847_get_ptt, /* get ptt */ .get_dcd = ft847_get_dcd, /* get dcd */ .get_level = ft847_get_level, /* get level */ .set_func = ft847_set_func, .set_ctcss_tone = ft847_set_ctcss_tone, .set_ctcss_sql = ft847_set_ctcss_sql, .set_dcs_sql = ft847_set_dcs_sql, .set_rptr_shift = ft847_set_rptr_shift, .set_rptr_offs = ft847_set_rptr_offs, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * setup *priv * serial port is already open (STATE(rig)->fd) */ static int ft847_init(RIG *rig) { struct ft847_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called \n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft847_priv_data *) calloc(1, sizeof(struct ft847_priv_data)); if (!STATE(rig)->priv) { /* whoops! memory shortage! */ return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->sat_mode = RIG_SPLIT_OFF; /* for early FT-847's we have our own memory items due to one way comm*/ /* until these are set we won't know what the values are */ priv->freqA = 1; /* 1Hz default */ priv->freqB = 1; /* 1Hz default */ priv->mode = RIG_MODE_USB; /* mode USB by default to avoid users not setting mode */ priv->width = 1; /* 1Hz default */ return RIG_OK; } /* * ft847_cleanup routine * the serial port is closed by the frontend */ static int ft847_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* * ft847_open routine * */ static int ft847_open(RIG *rig) { int retval; /* Good time to set CAT ON */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); retval = ft847_send_priv_cmd(rig, FT_847_NATIVE_CAT_ON); RETURNFUNC2(retval); } /* * ft847_close routine * */ static int ft847_close(RIG *rig) { /* Good time to set CAT OFF */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); /* don't care about return value */ ft847_send_priv_cmd(rig, FT_847_NATIVE_CAT_OFF); return RIG_OK; } /* * private helper function to send a private command * sequence . Must only be complete sequences. * */ static int ft847_send_priv_cmd(RIG *rig, int cmd_index) { if (! ncmd[cmd_index].ncomp) { rig_debug(RIG_DEBUG_VERBOSE, "%s: attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } return write_block(RIGPORT(rig), ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); } /* * opcode_vfo() copy into cmd the 5 byte command designated by cmd_index, * and patch the opcode with VFO targeting (MAIN 0x0-, SAT RX 0x1-, SAT TX 0x2-) */ static int opcode_vfo(RIG *rig, unsigned char *cmd, int cmd_index, vfo_t vfo) { struct ft847_priv_data *p = (struct ft847_priv_data *)STATE(rig)->priv; memcpy(cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); /* If the sat_mode is not enabled, * then leave the OpCode untouched (MAIN VFO) */ if (p->sat_mode == RIG_SPLIT_ON || vfo == RIG_VFO_SUB) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_MAIN: cmd[4] &= 0x0f; cmd[4] |= 0x10; /* MAIN VFO -> SAT RX VFO */ break; case RIG_VFO_SUB: case RIG_VFO_TX: cmd[4] &= 0x0f; cmd[4] |= 0x20; /* SAT TX VFO */ break; default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; /* sorry, wrong VFO */ } } return RIG_OK; } /* * Set frequency to freq Hz. Note 10 Hz resolution -- YUK -- FS * */ static int ft847_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz \n"; if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "ft847: requested freq = %"PRIfreq" Hz, vfo=%s\n", freq, rig_strvfo(vfo)); ret = opcode_vfo(rig, p_cmd, FT_847_NATIVE_CAT_SET_FREQ_MAIN, vfo); if (ret != RIG_OK) { return ret; } to_bcd_be(p_cmd, freq / 10, 8); /* store bcd format in in p_cmd */ rig_debug(RIG_DEBUG_VERBOSE, fmt, __func__, (int64_t)from_bcd_be(p_cmd, 8) * 10); if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_MAIN) { priv->freqA = freq; rig_debug(RIG_DEBUG_TRACE, "%s: freqA=%"PRIfreq"\n", __func__, priv->freqA); } else { priv->freqB = freq; rig_debug(RIG_DEBUG_TRACE, "%s: freqB=%"PRIfreq"\n", __func__, priv->freqB); } } return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } #define MD_LSB 0x00 #define MD_USB 0x01 #define MD_CW 0x02 #define MD_CWR 0x03 #define MD_AM 0x04 #define MD_FM 0x08 #define MD_CWN 0x82 #define MD_CWNR 0x83 #define MD_AMN 0x84 #define MD_FMN 0x88 static int get_freq_and_mode(RIG *rig, vfo_t vfo, freq_t *freq, rmode_t *mode, pbwidth_t *width) { hamlib_port_t *rp = RIGPORT(rig); unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ unsigned char cmd_index; /* index of sequence to send */ unsigned char data[8]; int n; struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo =%s \n", __func__, rig_strvfo(vfo)); if (UNIDIRECTIONAL) { if (vfo == RIG_VFO_MAIN) { *freq = priv->freqA; rig_debug(RIG_DEBUG_TRACE, "%s: freqA=%"PRIfreq"\n", __func__, priv->freqA); } else { *freq = priv->freqB; rig_debug(RIG_DEBUG_TRACE, "%s: freqB=%"PRIfreq"\n", __func__, priv->freqB); } *mode = priv->mode; *width = priv->width; return RIG_OK; } cmd_index = FT_847_NATIVE_CAT_GET_FREQ_MODE_STATUS_MAIN; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); /* change opcode according to vfo */ n = opcode_vfo(rig, p_cmd, cmd_index, vfo); if (n != RIG_OK) { return n; } n = write_block(rp, p_cmd, YAESU_CMD_LENGTH); if (n < 0) { return n; } n = read_block(rp, data, YAESU_CMD_LENGTH); if (n != YAESU_CMD_LENGTH) { rig_debug(RIG_DEBUG_ERR, "ft847: read_block returned %d\n", n); return n < 0 ? n : -RIG_EPROTO; } /* Remember, this is 10Hz resolution */ *freq = 10 * from_bcd_be(data, 8); *width = RIG_PASSBAND_NORMAL; switch (data[4]) { case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_CWN: *width = rig_passband_narrow(rig, RIG_MODE_CW); case MD_CW: *mode = RIG_MODE_CW; break; case MD_CWNR: *width = rig_passband_narrow(rig, RIG_MODE_CW); case MD_CWR: *mode = RIG_MODE_CWR; break; case MD_AMN: *width = rig_passband_narrow(rig, RIG_MODE_AM); case MD_AM: *mode = RIG_MODE_AM; break; case MD_FMN: *width = rig_passband_narrow(rig, RIG_MODE_FM); case MD_FM: *mode = RIG_MODE_FM; break; default: *mode = RIG_MODE_NONE; rig_debug(RIG_DEBUG_VERBOSE, "ft847: Unknown mode %02x\n", data[4]); } if (*width == RIG_PASSBAND_NORMAL) { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * Note taken from http://www.supercontrol.de/cat/ft847faq/page4.htm#pollingcodes * The FT-847, as originally delivered, could not poll the radio for frequency * and mode information. This was added beginning with the 8G05 production * runs. The Operating Manual does not show the codes for polling the radio. * Note that you cannot query the sub-VFO, nor can you swap VFOs via software. */ static int ft847_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rmode_t mode; pbwidth_t width; return get_freq_and_mode(rig, vfo, freq, &mode, &width); } static int ft847_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; /* * translate mode from generic to ft847 specific */ rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; priv->mode = mode; priv->width = width; } switch (mode) { case RIG_MODE_AM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_AM; break; case RIG_MODE_CW: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CW; break; case RIG_MODE_CWR: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CWR; break; case RIG_MODE_USB: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_USB; break; case RIG_MODE_LSB: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_LSB; break; case RIG_MODE_FM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_FM; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } /* * Now set width */ if (width != RIG_PASSBAND_NOCHANGE) { if (width == rig_passband_narrow(rig, mode)) { switch (mode) { case RIG_MODE_AM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_AMN; break; case RIG_MODE_FM: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_FMN; break; case RIG_MODE_CW: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CWN; break; case RIG_MODE_CWR: cmd_index = FT_847_NATIVE_CAT_SET_MODE_MAIN_CWRN; break; case RIG_MODE_USB: case RIG_MODE_LSB: break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode/width: %s/%d, narrow: %d\n", __func__, rig_strrmode(mode), (int)width, (int)rig_passband_narrow(rig, mode)); return -RIG_EINVAL; /* sorry, wrong MODE/WIDTH combo */ } } else { if (width != RIG_PASSBAND_NORMAL && width != rig_passband_normal(rig, mode)) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode/width: %s/%d, narrow: %d\n", __func__, rig_strrmode(mode), (int)width, (int)rig_passband_narrow(rig, mode)); return -RIG_EINVAL; /* sorry, wrong MODE/WIDTH combo */ } } } /* * Now send the command */ ret = opcode_vfo(rig, p_cmd, cmd_index, vfo); if (ret != RIG_OK) { return ret; } return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { freq_t freq; return get_freq_and_mode(rig, vfo, &freq, mode, width); } /* * Not exactly Split mode, this will set *SAT* Mode */ static int ft847_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; unsigned char cmd_index; /* index of sequence to send */ int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (split) { case RIG_SPLIT_ON: cmd_index = FT_847_NATIVE_CAT_SAT_MODE_ON; break; case RIG_SPLIT_OFF: cmd_index = FT_847_NATIVE_CAT_SAT_MODE_OFF; break; default: return -RIG_EINVAL; /* sorry, wrong split range */ } ret = ft847_send_priv_cmd(rig, cmd_index); if (ret == RIG_OK) { priv->sat_mode = split; } return ret; } static int ft847_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *split = priv->sat_mode; *tx_vfo = RIG_VFO_SUB; return RIG_OK; } static int ft847_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (retval != RIG_OK) { RETURNFUNC2(retval); } return ft847_set_freq(rig, RIG_VFO_TX, freq); } static int ft847_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq) { return ft847_get_freq(rig, RIG_VFO_TX, freq); } static int ft847_set_split_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { return ft847_set_mode(rig, RIG_VFO_TX, mode, width); } static int ft847_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { return ft847_get_mode(rig, RIG_VFO_TX, mode, width); } /* * _set_ptt * */ static int ft847_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; priv->ptt = ptt; } switch (ptt) { case RIG_PTT_ON: cmd_index = FT_847_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: cmd_index = FT_847_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; /* sorry, wrong ptt range */ } /* * phew! now send cmd to rig */ return ft847_send_priv_cmd(rig, cmd_index); } static int ft847_get_status(RIG *rig, int status_ci) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); unsigned char *data; int len; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } switch (status_ci) { case FT_847_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; break; case FT_847_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Internal error!\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); n = write_block(rp, ncmd[status_ci].nseq, YAESU_CMD_LENGTH); if (n < 0) { return n; } n = read_block(rp, data, len); if (n < 0) { return n; } if (n != len) { return -RIG_EPROTO; } return RIG_OK; } static int ft847_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { struct ft847_priv_data *priv = (struct ft847_priv_data *)STATE(rig)->priv; *ptt = priv->ptt; return RIG_OK; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_TX_STATUS); if (n < 0) { return n; } *ptt = (p->tx_status & 0x80) ? RIG_PTT_OFF : RIG_PTT_ON; /* The CAT query above lies when PTT is asserted via the PTT pin on the rear PACKET socket, it always returns Rx status. Given that CAT PTT does not take audio from DATA IN on the rear PACKET socket DTR or RTS PTT on the rear PACKET PTT pin is likely. So we override if we know PTT was asserted via rig_set_ptt for any type of PTT */ if (RIG_PTT_OFF == *ptt && STATE(rig)->transmit) { *ptt = RIG_PTT_ON; } return RIG_OK; } static int ft847_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_RX_STATUS); if (n < 0) { return n; } *dcd = (p->rx_status & 0x80) ? RIG_DCD_OFF : RIG_DCD_ON; return RIG_OK; } /* * Get the 'raw' signal strength * This number corresponds to the number of 'dots' in * the FT-847 display */ static int ft847_get_rawstr_level(RIG *rig, value_t *val) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_RX_STATUS); if (n < 0) { return n; } n = (p->rx_status & 0x1F); val->i = n; return RIG_OK; } /* * Get S-meter reading (in dB) */ static int ft847_get_smeter_level(RIG *rig, value_t *val) { int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_rawstr_level(rig, val); if (n < 0) { return n; } /* * The FT-847 S-meter readings over CAT returns * an integer that corresponds to the number of * 'dots' lit in the display. Use a conversion * function to convert the raw signal strength to dB */ n = val->i; if (n < 4) /* <= S1 */ { val->i = -54 + (n * 2); } else if (n < 20) /* S1 - S9 */ { val->i = -48 + ((n - 3) * 3); } else /* > S9 */ { n -= 19; val->i = (n * 5); } return RIG_OK; } /* * Get the PO/ALC Meter Data */ static int ft847_get_alc_level(RIG *rig, value_t *val) { struct ft847_priv_data *p = (struct ft847_priv_data *) STATE(rig)->priv; int n; if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } n = ft847_get_status(rig, FT_847_NATIVE_CAT_GET_TX_STATUS); if (n < 0) { return n; } n = (p->tx_status & 0x1F); val->f = (float)n / 0x1F; return RIG_OK; } /* * Get "level" data from rig. * The 847 supports S-meter readings in receive mode * and PO/ALC in transmit mode. There is no way * to determine whether it's PO or ALC, unfortunately. */ static int ft847_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } switch (level) { case RIG_LEVEL_STRENGTH: return ft847_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return ft847_get_rawstr_level(rig, val); case RIG_LEVEL_ALC: return ft847_get_alc_level(rig, val); default: return -RIG_EINVAL; } return RIG_OK; } static int ft847_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; ft847_native_cmd_t fcmd; if (!rig) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_TONE: fcmd = status ? FT_847_NATIVE_CAT_SET_CTCSS_ENC_ON_MAIN : FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_MAIN; break; case RIG_FUNC_TSQL: fcmd = status ? FT_847_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON_MAIN : FT_847_NATIVE_CAT_SET_CTCSS_DCS_OFF_MAIN; break; default: return -RIG_EINVAL; } ret = opcode_vfo(rig, p_cmd, fcmd, vfo); if (ret != RIG_OK) { return ret; } return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int i, ret; /* * 39 CTCSS CAT codes corresponding to ft847_ctcss_list */ static const unsigned char ft847_ctcss_cat[] = { 0x3F, 0x39, 0x1F, 0x3E, 0x0F, 0x3D, 0x1E, 0x3C, 0x0E, 0x3B, 0x1D, 0x3A, 0x0D, 0x1C, 0x0C, 0x1B, 0x0B, 0x1A, 0x0A, 0x19, 0x09, 0x18, 0x08, 0x17, 0x07, 0x16, 0x06, 0x15, 0x05, 0x14, 0x04, 0x13, 0x03, 0x12, 0x02, 0x11, 0x01, 0x10, 0x00, }; ret = opcode_vfo(rig, p_cmd, FT_847_NATIVE_CAT_SET_CTCSS_FREQ_MAIN, vfo); if (ret != RIG_OK) { return ret; } #define FT847_CTCSS_NB 39 for (i = 0; i < FT847_CTCSS_NB; i++) { if (ft847_ctcss_list[i] == tone) { break; } } if (i == FT847_CTCSS_NB) { return -RIG_EINVAL; } /* get associated CAT code */ p_cmd[0] = ft847_ctcss_cat[i]; return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { /* same opcode as tone */ return ft847_set_ctcss_tone(rig, vfo, tone); } static int ft847_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ int ret; ret = opcode_vfo(rig, p_cmd, FT_847_NATIVE_CAT_SET_DCS_CODE_MAIN, vfo); if (ret != RIG_OK) { return ret; } /* TODO: FT_847_NATIVE_CAT_SET_DCS_ON_MAIN here or with new RIG_FUNC_DCS? */ /* DCS Code # (i.e. 07, 54=DCS Code 754) */ to_bcd_be(p_cmd, code, 4); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } static int ft847_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { unsigned char cmd_index; /* index of sequence to send */ switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: cmd_index = FT_847_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX; break; case RIG_RPT_SHIFT_MINUS: cmd_index = FT_847_NATIVE_CAT_SET_RPT_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: cmd_index = FT_847_NATIVE_CAT_SET_RPT_SHIFT_PLUS; break; default: return -RIG_EINVAL; /* sorry, wrong shift */ } return ft847_send_priv_cmd(rig, cmd_index); } static int ft847_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { unsigned char p_cmd[YAESU_CMD_LENGTH]; /* sequence to send */ if (UNIDIRECTIONAL) { return -RIG_ENIMPL; } memcpy(p_cmd, &ncmd[FT_847_NATIVE_CAT_SET_RPT_OFFSET].nseq, YAESU_CMD_LENGTH); to_bcd_be(p_cmd, rptr_offs / 10, 8); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } hamlib-4.6.2/rigs/yaesu/ft3000.c0000644000175000017500000003552614752216205013071 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft3000.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * * This shared library provides an API for communicating * via serial interface to an FT-DX3000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "misc.h" #include "newcat.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft5000.h" #include "tones.h" const struct newcat_priv_caps ftdx3000_priv_caps = { .roofing_filter_count = 11, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = '4', .get_value = '7', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = '8', .width = 300, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 7, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 8, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, { .index = 9, .set_value = 0, .get_value = '9', .width = 600, .optional = 0 }, { .index = 10, .set_value = 0, .get_value = 'A', .width = 300, .optional = 0 }, } }; const struct confparams ftdx3000_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "600 Hz", "300 Hz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", "AUTO - 600 Hz", "AUTO - 300 Hz", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx3000_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; int ft3000_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char *cmd; int err; struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; ENTERFUNC; switch (ant) { case 1: cmd = "AN01;"; // R3/1 ANT1/ANT3 break; case 2: cmd = "AN02;"; // RE/2 ANT2/ANT3 break; case 3: cmd = "AN03;"; // TRX ANT3 break; default: rig_debug(RIG_DEBUG_ERR, "%s: expected 1,2,3 got %u\n", __func__, ant); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", cmd); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } RETURNFUNC(RIG_OK); } int ft3000_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { struct newcat_priv_data *priv = (struct newcat_priv_data *)STATE(rig)->priv; int err; ENTERFUNC; option->i = 0; // default to no options // find out what ANT3 setting SNPRINTF(priv->cmd_str, sizeof(priv->cmd_str), "%s", "AN0;"); if (RIG_OK != (err = newcat_get_cmd(rig))) { RETURNFUNC(err); } if (strlen(priv->ret_data) >= 7) { char c = priv->ret_data[3]; switch (c) { case '1': *ant_rx = RIG_ANT_3; *ant_tx = RIG_ANT_1; break; case '2': *ant_rx = RIG_ANT_3; *ant_tx = RIG_ANT_2; break; case '3': *ant_rx = *ant_tx = RIG_ANT_3; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown antenna=%c\n", __func__, c); RETURNFUNC(-RIG_EPROTO); } } *ant_curr = *ant_tx; // current points to tx antenna RETURNFUNC(RIG_OK); } /* * FTDX 3000 rig capabilities * Seems to be largely compatible with the FTDX 5000, * so this is just a copy of the FTDX 5000 caps. * It really needs to be reviewed for accuracy, but it works for WSJT-X. */ struct rig_caps ftdx3000_caps = { RIG_MODEL(RIG_MODEL_FTDX3000), .model_name = "FTDX-3000", .mfg_name = "Yaesu", .version = NEWCAT_VER ".12", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* Assumed since manual makes no mention */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, // write_delay 5ms or less was causing VS1;VS; to answer with VS0 instead of VS1 even though change did occur // see https://github.com/Hamlib/Hamlib/issues/906 .write_delay = 0, // delay of 1 broke rigctl -- all ? responses .post_write_delay = FTDX5000_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX5000_FUNCS, .has_set_func = FTDX5000_FUNCS, .has_get_level = FTDX5000_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX5000_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_NOTCHF #define NO_LVL_MICGAIN #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_NOTCHF #undef NO_LVL_MICGAIN #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 17, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1000), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX5000_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, /* one of the few diffs from the 5000 */ .transceive = RIG_TRN_OFF, /* May enable later as the 5000 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .str_cal = FTDX5000_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m(1, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX5000_ALL_RX_MODES, -1, -1, FTDX5000_VFO_ALL, FTDX5000_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_HF(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX5000_OTHER_TX_MODES, W(5), W(200), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), FRQ_RNG_6m(2, FTDX5000_AM_TX_MODES, W(2), W(75), FTDX5000_VFO_ALL, FTDX5000_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX5000_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX5000_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX5000_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX5000_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX5000_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX5000_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {FTDX5000_AM_RX_MODES, Hz(9000)}, /* Normal AM */ {FTDX5000_AM_RX_MODES, Hz(6000)}, /* Narrow AM */ {FTDX5000_FM_RX_MODES, Hz(16000)}, /* Normal FM */ {FTDX5000_FM_RX_MODES, Hz(9000)}, /* Narrow FM */ {FTDX5000_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx3000_ext_tokens, .extlevels = ftdx3000_ext_levels, .priv = &ftdx3000_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = ft3000_set_ant, .get_ant = ft3000_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft840.h0000644000175000017500000002247514752216205013026 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft840.h - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * (C) Stephane Fillod 2002, 2009 (fillods at users.sourceforge.net) * (C) Nate Bargmann 2002, 2003 (n0nb at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-840 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT840_H #define _FT840_H 1 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #define FT840_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT840_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT840_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB) #define FT840_AM_RX_MODES (RIG_MODE_AM) #define FT840_FM_RX_MODES (RIG_MODE_FM) /* TX caps */ #define FT840_OTHER_TX_MODES (RIG_MODE_CW| RIG_MODE_USB| RIG_MODE_LSB ) /* 100 W class */ #define FT840_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT840_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN) /* fix */ /* * Other features (used by rig_caps) * */ #define FT840_ANTS 0 /* Returned data length in bytes */ #define FT840_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT840_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT840_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT840_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT840_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT840_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ #define FT840_PACING_INTERVAL 5 #define FT840_PACING_DEFAULT_VALUE 0 #define FT840_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT840_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT840_DEFAULT_READ_TIMEOUT 649 * ( 5 + (FT840_PACING_INTERVAL * FT840_PACING_DEFAULT_VALUE)) /* BCD coded frequency length */ #define FT840_BCD_DIAL 8 #define FT840_BCD_RIT 3 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte * rate = 1 byte in 2.2917 msec => 649 bytes in 1487 msec * * delay for 28 bytes = (2.2917 + pace_interval) * 28 * * pace_interval time to read 28 bytes * ------------ ---------------------- * * 0 1487 msec * 1 2136 msec (backend default) * 2 2785 msec * 5 4732 msec * 255 167 sec * */ /* * Internal MODES - when setting modes via FT840_NATIVE_MODE_SET * */ #define MODE_SET_LSB 0x00 #define MODE_SET_USB 0x01 #define MODE_SET_CW_W 0x02 #define MODE_SET_CW_N 0x03 #define MODE_SET_AM_W 0x04 #define MODE_SET_AM_N 0x05 #define MODE_SET_FM 0x06 /* * Internal Clarifier parms - when setting clarifier via * FT840_NATIVE_CLARIFIER_OPS * * The manual seems to be incorrect with regard to P1 and P2 values * P1 = 0x00 clarifier off * P1 = 0x01 clarifier on * P1 = 0xff clarifier set * P2 = 0x00 clarifier up * P2 = 0xff clarifier down */ /* P1 values */ #define CLAR_RX_OFF 0x00 #define CLAR_RX_ON 0x01 #define CLAR_SET_FREQ 0xff /* P2 values */ #define CLAR_OFFSET_PLUS 0x00 #define CLAR_OFFSET_MINUS 0xff /* * Some useful offsets in the status update flags (offset) * SUMO--Status Update Memory Offset? * * SF_ bit tests are now grouped with flag bytes for ease of reference * * FIXME: complete flags and bits * * CAT command 0xFA requests the FT-840 to return its status flags. * These flags consist of 3 bytes (plus 2 filler bytes) and are documented * in the FT-840 manual on page 33. * */ #define FT840_SUMO_DISPLAYED_STATUS_0 0x00 /* Status flag byte 0 */ #define SF_GC (1<<1) /* General Coverage Reception selected */ #define SF_SPLIT (1<<2) /* Split active */ #define SF_MCK (1<<3) /* memory Checking in progress */ #define SF_MT (1<<4) /* Memory Tuning in progress */ #define SF_MR (1<<5) /* Memory Mode selected */ #define SF_A (0<<6) /* bit 6 clear, VFO A */ #define SF_B (1<<6) /* bit 6 set, VFO B */ #define SF_VFO (1<<7) /* bit 7 set, VFO A or B active */ #define SF_VFOA (SF_VFO|SF_A) /* bit 7 set, bit 6 clear, VFO A */ #define SF_VFOB (SF_VFO|SF_B) /* bit 7 set, bit 6 set, VFO B */ #define SF_VFO_MASK (SF_VFOB) /* bits 6 and 7 */ #define SF_MEM_MASK (SF_MCK|SF_MT|SF_MR) /* bits 3, 4 and 5 */ #define FT840_SUMO_DISPLAYED_STATUS_1 0x01 /* Status flag byte 1 */ #define FT840_SUMO_DISPLAYED_STATUS_2 0x02 /* Status flag byte 1 */ #define SF_PTT_OFF (0<<7) /* bit 7 set, PTT open */ #define SF_PTT_ON (1<<7) /* bit 7 set, PTT closed */ #define SF_PTT_MASK (SF_PTT_ON) /* * Offsets for VFO record retrieved via 0x10 P1 = 02, 03, 04 * * The FT-840 returns frequency and mode data via three separate commands. * CAT command 0x10, P1 = 02 returns the current main and sub displays' data (19 bytes) * CAT command 0x10, P1 = 03 returns VFO A & B data (18 bytes) * CAT command 0x10, P1 = 04, P4 = 0x01-0x20 returns memory channel data (19 bytes) * In all cases the format is (from the FT-840 manual page 32): * * Offset Value * 0x00 Band Selection (BPF selection: 0x00 - 0x30 (bit 7 =1 on a blanked memory)) * 0x01 Operating Frequency (Hex value of display--Not BCD!) * 0x04 Clarifier Offset (signed value between -999d (0xfc19) and +999d (0x03e7)) * 0x06 Mode Data * 0x07 CTCSS tone code (0x00 - 0x20) * 0x08 Flags (Operating flags -- manual page 33) * * Memory Channel data has the same layout and offsets as the operating * data record. * When either of the 19 byte records is read (P1 = 02, 04), the offset is * +1 as the leading byte is the memory channel number. * The VFO data command (P1 = 03) returns 18 bytes and the VFO B data has * the same layout, but the offset starts at 0x09 and continues through 0x12 * */ #define FT840_SUMO_MEM_CHANNEL 0x00 /* Memory Channel from 0xfa, P1 = 1 */ #define FT840_SUMO_DISPLAYED_FREQ 0x02 /* Current main display, can be VFO A, Memory data, Memory tune (3 bytes) */ #define FT840_SUMO_DISPLAYED_CLAR 0x05 /* RIT offset -- current display */ #define FT840_SUMO_DISPLAYED_MODE 0x07 /* Current main display mode */ #define FT840_SUMO_DISPLAYED_FLAG 0x09 #define FT840_SUMO_VFO_A_FREQ 0x01 /* VFO A frequency, not necessarily currently displayed! */ #define FT840_SUMO_VFO_A_CLAR 0x04 /* RIT offset -- VFO A */ #define FT840_SUMO_VFO_A_MODE 0x06 /* VFO A mode, not necessarily currently displayed! */ #define FT840_SUMO_VFO_A_FLAG 0x08 #define FT840_SUMO_VFO_B_FREQ 0x0a /* Current sub display && VFO B */ #define FT840_SUMO_VFO_B_CLAR 0x0d /* RIT offset -- VFO B */ #define FT840_SUMO_VFO_B_MODE 0x0f /* Current sub display && VFO B */ #define FT840_SUMO_VFO_B_FLAG 0x11 /* * Read meter offset * * FT-840 returns the level of the S meter when in RX and ALC or PO or SWR * when in TX. The level is replicated in the first four bytes sent by the * rig with the final byte being a constant 0xf7 * * The manual states that the returned value will range between 0x00 and 0xff * while "in practice the highest value returned will be around 0xf0". The * manual is silent when this value is returned as my rig returns 0x00 for * S0, 0x44 for S9 and 0x9D for S9 +60. * */ #define FT840_SUMO_METER 0x00 /* Meter level */ /* * Narrow filter selection flag from offset 0x08 or 0x11 * in VFO/Memory Record * * used when READING modes from FT-840 * */ #define FLAG_AM_N (1<<6) #define FLAG_CW_N (1<<7) #define FLAG_MASK (FLAG_AM_N|FLAG_CW_N) /* * Mode Bitmap from offset 0x06 or 0x0f in VFO/Memory Record. * * used when READING modes from FT-840 * */ #define MODE_LSB 0x00 #define MODE_USB 0x01 #define MODE_CW 0x02 #define MODE_AM 0x03 #define MODE_FM 0x04 /* All relevant bits */ #define MODE_MASK (MODE_LSB|MODE_USB|MODE_CW|MODE_AM|MODE_FM) /* * Command string parameter offsets */ #define P1 3 #define P2 2 #define P3 1 #define P4 0 #endif /* _FT840_H */ hamlib-4.6.2/rigs/yaesu/ft9000.h0000644000175000017500000001205014752216205013067 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft9000.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2009 * * This shared library provides an API for communicating * via serial interface to an FT-9000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT9000_H #define _FT9000_H 1 #if 0 #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE #endif #define FT9000_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* Receiver caps */ #define FT9000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define FT9000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT9000_AM_RX_MODES (RIG_MODE_AM) #define FT9000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TRX caps */ #define FT9000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM) #define FT9000_AM_TX_MODES (RIG_MODE_AM) #define FT9000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) #define FT9000_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT9000_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TBC */ #define FT9000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|RIG_LEVEL_MONITOR_GAIN|\ RIG_LEVEL_BAND_SELECT) /* TBC */ #define FT9000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|\ RIG_FUNC_RIT|RIG_FUNC_XIT) /* TBC */ #define FT9000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) // Borrowed from FLRig -- Thanks to Dave W1HKJ #define FT9000_RFPOWER_METER_CAL \ { \ 11, \ { \ {35, 10.0f}, \ {53, 20.0f}, \ {80, 40.0f}, \ {97, 60.0f}, \ {119, 80.0f}, \ {137, 100.0f}, \ {154, 120.0f}, \ {167, 140.0f}, \ {177, 160.0f}, \ {188, 180.0f}, \ {197, 200.0f}, \ } \ } /* TBC */ #define FT9000_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT9000_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) #define FT9000_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT9000_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT9000_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT9000_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT9000_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT9000_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT9000_PACING_INTERVAL 5 // #define FT9000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-9000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT9000_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT9000_POST_WRITE_DELAY 5 #endif /* _FT9000_H */ hamlib-4.6.2/rigs/yaesu/ft100.h0000644000175000017500000000252414752216205013004 00000000000000/* * hamlib - (C) Frank Singleton 2000-2003 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft100.h - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-100 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT100_H #define _FT100_H 1 #define FT100_WRITE_DELAY 0 #define FT100_POST_WRITE_DELAY 25 /* max is 200ms */ #define FT100_DEFAULT_READ_TIMEOUT 2000 #endif /* _FT100_H */ hamlib-4.6.2/rigs/yaesu/ftdx101mp.c0000644000175000017500000002733114752216205013674 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx101md.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2020 * (C) Michael Black W9MDB 2021 * * This shared library provides an API for communicating * via serial interface to an FTDX101(D) using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ftdx101.h" const struct newcat_priv_caps ftdx101mp_priv_caps = { .roofing_filter_count = 6, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 12000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 }, { .index = 4, .set_value = '4', .get_value = '9', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = 'A', .width = 300, .optional = 1 }, } }; const struct confparams ftdx101mp_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "12 kHz", "3 kHz", "1.2 kHz (optional)", "600 Hz", "300 Hz (optional)", NULL } } } }, { RIG_CONF_END, NULL, } }; int ftdx101mp_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_MAXPOWER_HF, TOK_MAXPOWER_6M, TOK_MAXPOWER_4M, TOK_MAXPOWER_AM, TOK_ROOFING_FILTER, TOK_BACKEND_NONE }; struct rig_caps ftdx101mp_caps = { RIG_MODEL(RIG_MODEL_FTDX101MP), .model_name = "FTDX-101MP", .mfg_name = "Yaesu", .version = NEWCAT_VER ".12", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX101_WRITE_DELAY, .post_write_delay = FTDX101_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX101_FUNCS, .has_set_func = FTDX101_FUNCS, .has_get_level = FTDX101_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX101_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .025 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 200.0f } }, [LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDUNUSED,BANDUNUSED,BANDUNUSED,BAND4M"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = FTDX101_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_COMMON | RIG_TARGETABLE_ANT | RIG_TARGETABLE_ROOFING | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the FTDX101 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX101MP_RFPOWER_METER_WATTS_CAL, .vd_meter_cal = YAESU_DEFAULT_VD_METER_200W_CAL, .str_cal = FTDX101D_STR_CAL, .swr_cal = FTDX101D_SWR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // P1L-P9U PMS channels { 501, 510, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // 5xx 5MHz band { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(1, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(1, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(2, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(2, FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FTDX101_OTHER_TX_MODES, W(5), W(200), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_4m_REGION2(FTDX101_AM_TX_MODES, W(5), W(50), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX101_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX101_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX101_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX101_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FTDX101_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx101mp_ext_tokens, .extlevels = ftdx101mp_ext_levels, .priv = &ftdx101mp_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft1200.c0000644000175000017500000003065514752216205013067 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft1200.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * (C) Terry Embry 2008-2009 * ft1200.c - (C) David Fannin 2015 (kk6df at arrl.net) * * This shared library provides an API for communicating * via serial interface to an FT-1200 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "newcat.h" #include "yaesu.h" #include "ft1200.h" #include "tones.h" const struct newcat_priv_caps ftdx1200_priv_caps = { .roofing_filter_count = 7, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 15000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '1', .width = 15000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '2', .width = 6000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '3', .width = 3000, .optional = 0 }, { .index = 4, .set_value = 0, .get_value = '4', .width = 15000, .optional = 0 }, { .index = 5, .set_value = 0, .get_value = '5', .width = 6000, .optional = 0 }, { .index = 6, .set_value = 0, .get_value = '6', .width = 3000, .optional = 0 }, } }; const struct confparams ftdx1200_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "15 kHz", "6 kHz", "3 kHz", "AUTO - 15 kHz", "AUTO - 6 kHz", "AUTO - 3 kHz", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 100, .max = 4000, .step = 100 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx1200_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_BACKEND_NONE }; /* * FTDX 1200 rig capabilities */ struct rig_caps ftdx1200_caps = { RIG_MODEL(RIG_MODEL_FTDX1200), .model_name = "FTDX-1200", .mfg_name = "Yaesu", .version = NEWCAT_VER ".7", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* Default rate per manual */ .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, /* found by testing with remote serial port */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX1200_WRITE_DELAY, .post_write_delay = FTDX1200_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX1200_FUNCS, .has_set_func = FTDX1200_FUNCS, .has_get_level = FTDX1200_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX1200_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_NOTCHF #define NO_LVL_MICGAIN #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #include "level_gran_yaesu.h" #undef NO_LVL_NOTCHF #undef NO_LVL_MICGAIN #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 4000 }, .step = { .i = 10 } }, [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BANDUNUSED,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX1200_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_OFF, /* May enable later as the 1200 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX1200_RFPOWER_METER_CAL, .str_cal = FTDX1200_STR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_EDGE, NEWCAT_MEM_CAP }, /* two by two */ { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(56), FTDX1200_ALL_RX_MODES, -1, -1, FTDX1200_VFO_ALL, FTDX1200_TX_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_HF(1, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_6m(1, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(56), FTDX1200_ALL_RX_MODES, -1, -1, FTDX1200_VFO_ALL, FTDX1200_TX_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_HF(2, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX1200_OTHER_TX_MODES, W(5), W(100), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), FRQ_RNG_6m(2, FTDX1200_AM_TX_MODES, W(2), W(25), FTDX1200_VFO_ALL, FTDX1200_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX1200_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX1200_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX1200_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX1200_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX1200_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX1200_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(1800)}, /* Normal CW, RTTY, PKT/USER */ {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(500)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX1200_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(4000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AM, Hz(6000)}, /* Narrow AM */ {FTDX1200_FM_WIDE_RX_MODES, Hz(16000)}, /* Normal FM */ {FTDX1200_FM_WIDE_RX_MODES, Hz(9000)}, /* Narrow FM */ {RIG_MODE_FMN, Hz(9000)}, /* Narrow FM */ {FTDX1200_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx1200_ext_tokens, .extlevels = ftdx1200_ext_levels, .priv = &ftdx1200_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft1000d.c0000644000175000017500000034760214752216205013234 00000000000000/* * hamlib - (C) Stephane Fillod 2002-2009 (fillods at users.sourceforge.net) * * ft1000d.c - (C) Berndt Josef Wulf (wulf at ping.net.au) * (C) 2016 Sean Sharkey (g0oan at icloud.com) * * This shared library provides an API for communicating * via serial interface to an FT-1000D using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Code separated out from ft990.c and ft990.h in December 2016. Added several * extra functions to expand level of support for the FT1000/D. Sean G0OAN. * */ #include #include /* String function definitions */ #include "hamlib/rig.h" #include "bandplan.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft1000d.h" // FT1000D native commands enum FT1000D_native_cmd_e { FT1000D_NATIVE_SPLIT_OFF = 0, FT1000D_NATIVE_SPLIT_ON, FT1000D_NATIVE_RECALL_MEM, FT1000D_NATIVE_VFO_TO_MEM, FT1000D_NATIVE_LOCK_OFF, FT1000D_NATIVE_LOCK_ON, FT1000D_NATIVE_VFO_A, FT1000D_NATIVE_VFO_B, FT1000D_NATIVE_MEM_TO_VFO, FT1000D_NATIVE_VFO_STEP_UP, FT1000D_NATIVE_VFO_STEP_UP_FAST, FT1000D_NATIVE_VFO_STEP_DOWN, FT1000D_NATIVE_VFO_STEP_DOWN_FAST, FT1000D_NATIVE_RX_CLARIFIER_OFF, FT1000D_NATIVE_RX_CLARIFIER_ON, FT1000D_NATIVE_TX_CLARIFIER_OFF, FT1000D_NATIVE_TX_CLARIFIER_ON, FT1000D_NATIVE_CLEAR_CLARIFIER_OFFSET, FT1000D_NATIVE_CLARIFIER_OPS, FT1000D_NATIVE_FREQ_SET, FT1000D_NATIVE_MODE_SET_LSB, FT1000D_NATIVE_MODE_SET_USB, FT1000D_NATIVE_MODE_SET_CW_W, FT1000D_NATIVE_MODE_SET_CW_N, FT1000D_NATIVE_MODE_SET_AM_W, FT1000D_NATIVE_MODE_SET_AM_N, FT1000D_NATIVE_MODE_SET_FM, FT1000D_NATIVE_MODE_SET_RTTY_LSB, FT1000D_NATIVE_MODE_SET_RTTY_USB, FT1000D_NATIVE_MODE_SET_PKT_LSB, FT1000D_NATIVE_MODE_SET_PKT_FM, FT1000D_NATIVE_MODE_SUB_VFOB_SET_LSB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_USB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_CW_W, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_CW_N, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_W, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_N, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_FM, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_LSB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_USB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_LSB, /* Added December 2016 */ FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_FM, /* Added December 2016 */ FT1000D_NATIVE_PACING, FT1000D_NATIVE_PTT_OFF, FT1000D_NATIVE_PTT_ON, FT1000D_NATIVE_UPDATE_ALL_DATA, FT1000D_NATIVE_UPDATE_MEM_CHNL, FT1000D_NATIVE_UPDATE_OP_DATA, FT1000D_NATIVE_UPDATE_VFO_DATA, FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA, FT1000D_NATIVE_TUNER_OFF, FT1000D_NATIVE_TUNER_ON, FT1000D_NATIVE_TUNER_START, FT1000D_NATIVE_RPTR_SHIFT_NONE, FT1000D_NATIVE_RPTR_SHIFT_MINUS, FT1000D_NATIVE_RPTR_SHIFT_PLUS, FT1000D_NATIVE_VFO_TO_VFO, FT1000D_NATIVE_SET_SUB_VFO_FREQ, FT1000D_NATIVE_BANDWIDTH, FT1000D_NATIVE_OP_FREQ_STEP_UP, FT1000D_NATIVE_OP_FREQ_STEP_DOWN, FT1000D_NATIVE_READ_METER, FT1000D_NATIVE_DIM_LEVEL, FT1000D_NATIVE_RPTR_OFFSET, FT1000D_NATIVE_READ_FLAGS, FT1000D_NATIVE_SIZE }; static int ft1000d_init(RIG *rig); static int ft1000d_cleanup(RIG *rig); static int ft1000d_open(RIG *rig); static int ft1000d_close(RIG *rig); static int ft1000d_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft1000d_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft1000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft1000d_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft1000d_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft1000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft1000d_set_vfo(RIG *rig, vfo_t vfo); static int ft1000d_get_vfo(RIG *rig, vfo_t *vfo); static int ft1000_get_vfo(RIG *rig, vfo_t *vfo); static int ft1000d_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft1000d_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft1000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft1000d_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift); static int ft1000d_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift); static int ft1000d_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft1000d_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); /* Added December 2016 */ static int ft1000d_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); /* Added December 2016 */ static int ft1000d_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft1000d_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft1000d_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); /* Added December 2016 */ static int ft1000d_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); /* Added December 2016 */ static int ft1000d_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft1000d_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); static int ft1000d_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft1000d_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft1000d_set_parm(RIG *rig, setting_t parm, value_t val); static int ft1000d_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ft1000d_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); static int ft1000d_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value); static int ft1000d_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft1000d_set_mem(RIG *rig, vfo_t vfo, int ch); static int ft1000d_get_mem(RIG *rig, vfo_t vfo, int *ch); static int ft1000d_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int ft1000d_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); /* Private helper function prototypes */ static int ft1000d_get_update_data(RIG *rig, unsigned char ci, unsigned short ch); static int ft1000d_send_static_cmd(RIG *rig, unsigned char ci); static int ft1000d_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4); static int ft1000d_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq); static int ft1000d_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit); static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* Split (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* Split (On) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* Memory Operations */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x04 } }, /* Lock (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x04 } }, /* Lock (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* Select VFO (B) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x06 } }, /* Copy Memory Data to VFO A */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* OP Freq Up 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x07 } }, /* OP Freq Up 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* OP Freq Down 0.1MHz */ { 1, { 0x00, 0x00, 0x01, 0x00, 0x08 } }, /* OP Freq Down 1MHz */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* RX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x09 } }, /* RX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x09 } }, /* TX Clarifier (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x09 } }, /* TX Clarifier (ON) */ { 1, { 0x00, 0x00, 0x00, 0xff, 0x09 } }, /* Clear Clarifier Offset */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x09 } }, /* Clarifier */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW 500Hz */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM 6KHz */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* OP Mode Set AM 2.4KHz */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* OP Mode Set FM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB */ { 1, { 0x00, 0x00, 0x00, 0x0a, 0x0c } }, /* OP Mode Set PKT LSB */ { 1, { 0x00, 0x00, 0x00, 0x0b, 0x0c } }, /* OP Mode Set PKT FM */ { 1, { 0x00, 0x00, 0x00, 0x80, 0x0c } }, /* Sub VFOB OP Mode Set LSB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x81, 0x0c } }, /* Sub VFOB OP Mode Set USB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x82, 0x0c } }, /* Sub VFOB OP Mode Set CW 2.4KHz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x83, 0x0c } }, /* Sub VFOB OP Mode Set CW 500Hz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x84, 0x0c } }, /* Sub VFOB OP Mode Set AM 6KHz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x85, 0x0c } }, /* Sub VFOB OP Mode Set AM 2.4KHz Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x86, 0x0c } }, /* Sub VFOB OP Mode Set FM Added December 2016*/ { 1, { 0x00, 0x00, 0x00, 0x88, 0x0c } }, /* Sub VFOB OP Mode Set RTTY LSB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x89, 0x0c } }, /* Sub VFOB OP Mode Set RTTY USB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x8a, 0x0c } }, /* Sub VFOB OP Mode Set PKT LSB Added December 2016 */ { 1, { 0x00, 0x00, 0x00, 0x8b, 0x0c } }, /* Sub VFOB OP Mode Set PKT FM Added December 2016 */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0e } }, /* Pacing */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* Update All Data (1636 bytes) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 0, { 0x00, 0x00, 0x00, 0x04, 0x10 } }, /* Update Memory Ch Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* Tuner (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x81 } }, /* Tuner (ON) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* Tuner (Start) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* Repeater Mode (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* Repeater Mode (Minus) */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* Repeater Mode (Plus) */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy displayed VFO (A=B || B=A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8A } }, /* Set Sub VFO Frequency Added December 2016 */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8C } }, /* Select Bandwidth */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8E } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8E } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf8 } }, /* DIM Level */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* Set Offset for Repeater Shift */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* * Private data */ struct ft1000d_priv_data { unsigned char pacing; /* pacing value */ vfo_t current_vfo; /* active VFO from last cmd */ vfo_t split_vfo; /* TX VFO in split mode Added on 16 Dec 2016 to include FT1000D function */ split_t split; /* split active or not Added on 16 Dec 2016 to include FT1000D function */ unsigned char p_cmd[YAESU_CMD_LENGTH]; /* private copy of CAT cmd */ ft1000d_update_data_t update_data; /* returned data */ }; /* * FT1000D rigs capabilities. */ #define FT1000D_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .width = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .flags = 1, \ } struct rig_caps ft1000d_caps = { RIG_MODEL(RIG_MODEL_FT1000D), .model_name = "FT-1000D", .mfg_name = "Yaesu", .version = "20240228.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000D_WRITE_DELAY, .post_write_delay = FT1000D_POST_WRITE_DELAY, .timeout = 500, .retry = 2, .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | \ RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_BACKLIGHT, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 13.0f}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {1, 90, RIG_MTYPE_MEM, FT1000D_MEM_CAP}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(1, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(2, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT1000D_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT1000D_AM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_AM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_FM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_FM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft1000d_init, .rig_cleanup = ft1000d_cleanup, .rig_open = ft1000d_open, /* port opened */ .rig_close = ft1000d_close, /* port closed */ .set_freq = ft1000d_set_freq, .get_freq = ft1000d_get_freq, .set_mode = ft1000d_set_mode, .get_mode = ft1000d_get_mode, .set_vfo = ft1000d_set_vfo, .get_vfo = ft1000d_get_vfo, .set_ptt = ft1000d_set_ptt, .get_ptt = ft1000d_get_ptt, .set_rptr_shift = ft1000d_set_rptr_shift, .get_rptr_shift = ft1000d_get_rptr_shift, .set_rptr_offs = ft1000d_set_rptr_offs, .set_split_freq = ft1000d_set_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ .get_split_freq = ft1000d_get_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ .set_split_mode = ft1000d_set_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ .get_split_mode = ft1000d_get_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ .set_split_vfo = ft1000d_set_split_vfo, /* Changed in December 2016 so that vfos toggle back and forth like pressing Split button on rig */ .get_split_vfo = ft1000d_get_split_vfo, .set_rit = ft1000d_set_rit, .get_rit = ft1000d_get_rit, .set_xit = ft1000d_set_xit, .get_xit = ft1000d_get_xit, .set_func = ft1000d_set_func, .get_func = ft1000d_get_func, .set_parm = ft1000d_set_parm, .get_level = ft1000d_get_level, .set_mem = ft1000d_set_mem, .get_mem = ft1000d_get_mem, .vfo_op = ft1000d_vfo_op, .set_channel = ft1000d_set_channel, .get_channel = ft1000d_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft1000_caps = { RIG_MODEL(RIG_MODEL_FT1000), .model_name = "FT-1000", .mfg_name = "Yaesu", .version = "20231124.0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT1000D_WRITE_DELAY, .post_write_delay = FT1000D_POST_WRITE_DELAY, .timeout = 500, .retry = 2, // .has_get_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER | RIG_FUNC_MON, // .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TUNER, // .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_SWR | RIG_LEVEL_ALC | RIG_LEVEL_RFPOWER | RIG_LEVEL_COMP, // .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, // .has_set_parm = RIG_PARM_BACKLIGHT, // .level_gran = // { //#include "level_gran_yaesu.h" // }, // .parm_gran = { // [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 13.0f}}, // }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), // .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | // RIG_OP_UP | RIG_OP_DOWN | RIG_OP_TUNE | RIG_OP_TOGGLE, .targetable_vfo = RIG_TARGETABLE_ALL, .transceive = RIG_TRN_OFF, /* Yaesus have to be polled, sigh */ .bank_qty = 0, .chan_desc_sz = 0, // .chan_list = { // {1, 90, RIG_MTYPE_MEM, FT1000D_MEM_CAP}, // RIG_CHAN_END, // }, .rx_range_list1 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, /* General coverage + ham */ RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(1, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), FT1000D_ALL_RX_MODES, -1, -1, FT1000D_VFO_ALL, FT1000D_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT1000D_OTHER_TX_MODES, W(5), W(100), FT1000D_VFO_ALL, FT1000D_ANTS), FRQ_RNG_HF(2, FT1000D_AM_TX_MODES, W(2), W(25), FT1000D_VFO_ALL, FT1000D_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FT1000D_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FT1000D_AM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_AM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_FM_RX_MODES, Hz(100)}, /* Normal */ {FT1000D_FM_RX_MODES, kHz(1)}, /* Fast */ {FT1000D_RTTY_RX_MODES, Hz(10)}, /* Normal */ {FT1000D_RTTY_RX_MODES, Hz(100)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB, RIG_FLT_ANY}, /* Enable all filters for SSB */ {RIG_MODE_CW, RIG_FLT_ANY}, /* Enable all filters for CW */ {RIG_MODE_RTTY, RIG_FLT_ANY}, /* Enable all filters for RTTY */ {RIG_MODE_RTTYR, RIG_FLT_ANY}, /* Enable all filters for Reverse RTTY */ {RIG_MODE_PKTLSB, RIG_FLT_ANY}, /* Enable all filters for Packet Radio LSB */ {RIG_MODE_AM, kHz(6)}, /* normal AM filter */ {RIG_MODE_AM, kHz(2.4)}, /* narrow AM filter */ {RIG_MODE_FM, kHz(8)}, /* FM standard filter */ {RIG_MODE_PKTFM, kHz(8)}, /* FM standard filter for Packet Radio FM */ RIG_FLT_END, }, .priv = NULL, /* private data FIXME: */ .rig_init = ft1000d_init, .rig_cleanup = ft1000d_cleanup, .rig_open = ft1000d_open, /* port opened */ .rig_close = ft1000d_close, /* port closed */ .set_freq = ft1000d_set_freq, .get_freq = ft1000_get_freq, .set_mode = ft1000d_set_mode, .get_mode = ft1000_get_mode, .set_vfo = ft1000d_set_vfo, .get_vfo = ft1000_get_vfo, .set_ptt = ft1000d_set_ptt, .get_ptt = ft1000_get_ptt, // .set_rptr_shift = ft1000d_set_rptr_shift, // .get_rptr_shift = ft1000d_get_rptr_shift, // .set_rptr_offs = ft1000d_set_rptr_offs, // .set_split_freq = ft1000d_set_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ // .get_split_freq = ft1000d_get_split_freq, /* Added December 2016 to expand range of FT1000D functions. */ // .set_split_mode = ft1000d_set_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ // .get_split_mode = ft1000d_get_split_mode, /* Added December 2016 to expand range of FT1000D functions. */ // .set_split_vfo = ft1000d_set_split_vfo, /* Changed in December 2016 so that vfos toggle back and forth like pressing Split button on rig */ // .get_split_vfo = ft1000d_get_split_vfo, // .set_rit = ft1000d_set_rit, // .get_rit = ft1000d_get_rit, // .set_xit = ft1000d_set_xit, // .get_xit = ft1000d_get_xit, // .set_func = ft1000d_set_func, // .get_func = ft1000d_get_func, // .set_parm = ft1000d_set_parm, // .get_level = ft1000d_get_level, // .set_mem = ft1000d_set_mem, // .get_mem = ft1000d_get_mem, // .vfo_op = ft1000d_vfo_op, // .set_channel = ft1000d_set_channel, // .get_channel = ft1000d_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ************************************ * * Hamlib API functions * * ************************************ */ /* * rig_init */ static int ft1000d_init(RIG *rig) { struct ft1000d_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft1000d_priv_data *) calloc(1, sizeof(struct ft1000d_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; // Set default pacing value priv->pacing = FT1000D_PACING_DEFAULT_VALUE; // Set operating vfo mode to current VFO changed from RIG_VFO_MAIN to RIG_VFO_A December 2016 priv->current_vfo = RIG_VFO_A; return RIG_OK; } /* * rig_cleanup */ static int ft1000d_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * rig_open */ static int ft1000d_open(RIG *rig) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: write_delay = %i msec\n", __func__, RIGPORT(rig)->write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay = %i msec\n", __func__, RIGPORT(rig)->post_write_delay); rig_debug(RIG_DEBUG_TRACE, "%s: read pacing = %i\n", __func__, priv->pacing); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_PACING, priv->pacing, 0, 0, 0); if (err != RIG_OK) { return err; } // Get current rig settings and status if (rig->caps->rig_model != RIG_MODEL_FT1000) { err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_close */ static int ft1000d_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_freq* * * Set frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); // Frequency range sanity check if (freq < 100000 || freq > 30000000) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft1000d_send_dial_freq(rig, FT1000D_NATIVE_FREQ_SET, freq); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_freq* * * Get frequency for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * freq * | output | 100000 - 30000000 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft1000d_priv_data *priv; unsigned char *p; freq_t f; int err; int ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = priv->update_data.vfoa.basefreq; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = priv->update_data.vfob.basefreq; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = priv->update_data.current_front.basefreq; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update data structure to obtain get frequency err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } /* big endian integer */ f = ((((p[0] << 8) + p[1]) << 8) + p[2]) * 10; rig_debug(RIG_DEBUG_TRACE, "%s: p0=0x%02x p1=0x%02x p2=0x%02x\n", __func__, p[0], p[1], p[2]); rig_debug(RIG_DEBUG_TRACE, "%s: freq = %"PRIfreq" Hz for vfo 0x%02x\n", __func__, f, vfo); // Frequency sanity check if (f < 100000 || f > 30000000) { return -RIG_EINVAL; } *freq = f; return RIG_OK; } /* * rig_set_ptt* * * Control PTT for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ptt | input | 0 = off, 1 = off * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { struct ft1000d_priv_data *priv; int err; unsigned char ci; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed ptt = 0x%02x\n", __func__, ptt); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (ptt) { case RIG_PTT_ON: ci = FT1000D_NATIVE_PTT_ON; break; case RIG_PTT_OFF: ci = FT1000D_NATIVE_PTT_OFF; break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_ptt* * * Get PTT line status * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * ptt * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the PTT status * is independent from the VFO selection. */ static int ft1000d_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } *ptt = ((priv->update_data.flag1 & FT1000D_SF_XMIT) != 0); rig_debug(RIG_DEBUG_TRACE, "%s: set ptt = 0x%02x\n", __func__, *ptt); return RIG_OK; } /* * rig_set_rptr_shift* * * Set repeater shift for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * freq | input | - = negative repeater shift, * | | + = positive repeater shift, * | | any other character = simplex (is this a bug?) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be set when in FM mode. */ static int ft1000d_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { struct ft1000d_priv_data *priv; unsigned char ci; char *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed rptr_shift = 0x%02x\n", __func__, rptr_shift); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Construct update query switch (vfo) { case RIG_VFO_A: p = (char *) &priv->update_data.vfoa.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (char *) &priv->update_data.vfob.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: p = (char *) &priv->update_data.current_front.mode; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, *p); // Shift mode settings are only valid in FM mode if ((*p & FT1000D_MODE_FM) == 0) { return -RIG_EINVAL; } // Construct repeater shift command switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: ci = FT1000D_NATIVE_RPTR_SHIFT_NONE; break; case RIG_RPT_SHIFT_MINUS: ci = FT1000D_NATIVE_RPTR_SHIFT_MINUS; break; case RIG_RPT_SHIFT_PLUS: ci = FT1000D_NATIVE_RPTR_SHIFT_PLUS; break; default: return -RIG_EINVAL; } // Set repeater shift err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_rptr_shift* * * Get repeater shift setting for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * shift * | output | 0 = simplex * | | 1 = negative repeater shift * | | 2 = positive repeater shift * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * Repeater shift can only be obtained when in FM mode. */ static int ft1000d_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { struct ft1000d_priv_data *priv; ft1000d_op_data_t *p; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: p = &priv->update_data.vfoa; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = &priv->update_data.vfob; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set mode = 0x%02x\n", __func__, p->mode); // Shift mode settings are only valid in FM mode if (p->mode & FT1000D_MODE_FM) { *rptr_shift = (p->status & FT1000D_RPT_MASK) >> 2; } else { rig_debug(RIG_DEBUG_TRACE, "%s: Rig not in FM mode = 0x%02x\n", __func__, *rptr_shift); } return -RIG_EINVAL; rig_debug(RIG_DEBUG_TRACE, "%s: set rptr shift = 0x%02x\n", __func__, *rptr_shift); return RIG_OK; } /* * rig_set_rptr_offs* * * Set repeater frequency offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * off | input | 0 - 199999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * repeater frequency offset is independent from the VFO selection. */ static int ft1000d_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char bcd[(int) FT1000D_BCD_RPTR_OFFSET / 2]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed offs = %d\n", __func__, (int)offs); // Check for valid offset if (offs < 0 || offs > 199999) { return -RIG_EINVAL; } to_bcd(bcd, offs / 10, FT1000D_BCD_RPTR_OFFSET); rig_debug(RIG_DEBUG_TRACE, "%s: set bcd[0] = 0x%02x, bcd[1] = 0x%02x, bcd[2] = 0x%02x\n", __func__, bcd[0], bcd[1], bcd[2]); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_RPTR_OFFSET, 0, bcd[2], bcd[1], bcd[0]); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_split_vfo* * * Set split operation for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * split | input | 0 = off, 1 = on * tx_vfo | input | currVFO, VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo or tx_vfo will use the currently * selected VFO obtained from the priv->current_vfo data structure. * Only VFOA and VFOB are valid assignments for the tx_vfo. * The tx_vfo is loaded first when assigning MEM to vfo to ensure * the correct TX VFO is selected by the rig in split mode. * An error is returned if vfo and tx_vfo are the same. */ static int ft1000d_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { struct ft1000d_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed split = 0x%02x\n", __func__, split); rig_debug(RIG_DEBUG_TRACE, "%s: passed tx_vfo = 0x%02x\n", __func__, tx_vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: vfo = priv->current.vfo = 0x%02x\n", __func__, vfo); } if (tx_vfo == RIG_VFO_CURR) { tx_vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo = priv->current.vfo = 0x%02x\n", __func__, tx_vfo); } // RX VFO and TX VFO cannot be the same, no support for MEM as TX VFO if (vfo == tx_vfo || tx_vfo == RIG_VFO_MEM) { return -RIG_ENTARGET; } // Set TX VFO first if RIG_VFO_MEM selected for RX VFO if (vfo == RIG_VFO_MEM) { err = ft1000d_set_vfo(rig, tx_vfo); if (err != RIG_OK) { return err; } } // Set RX VFO err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } switch (split) { case RIG_SPLIT_ON: ci = FT1000D_NATIVE_SPLIT_ON; break; case RIG_SPLIT_OFF: ci = FT1000D_NATIVE_SPLIT_OFF; /* added below line to force VFOA in simplex operation */ // priv->current_vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) /* ; */ { return err; } return RIG_OK; } /* * rig_get_split_vfo* * * Get split mode status for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * split * | output | 0 = on, 1 = off * tx_vfo * | output | VFOA, VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored in order to * preserve the current split vfo system settings. */ static int ft1000d_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Read status flags err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } // Get split mode status *split = priv->update_data.flag1 & FT1000D_SF_SPLIT; rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: set split = 0x%02x\n", __func__, *split); // Added in December 2016 to ensure get split vfo only works if Spilt function is active. // FT1000D_SF_VFOB which is data bit 4 of flag byte 1 on the FT1000D does not work. Added the code below // to check that the Split function is active on the FT1000D. if (priv->update_data.flag1 & FT1000D_SF_SPLIT) // Added 15 Dec 2016. // Get transmit vfo switch (priv->current_vfo) { case RIG_VFO_A: *tx_vfo = RIG_VFO_B; break; case RIG_VFO_B: *tx_vfo = RIG_VFO_A; break; case RIG_VFO_MEM: if (priv->update_data.flag1 & FT1000D_SF_SPLIT) { *tx_vfo = RIG_VFO_B; } else { *tx_vfo = RIG_VFO_A; } break; default: return -RIG_EINVAL; rig_debug(RIG_DEBUG_TRACE, "%s: set tx_vfo = 0x%02x\n", __func__, *tx_vfo); } else { rig_debug(RIG_DEBUG_TRACE, "%s: Split not set on rig = 0x%02x\n", __func__, *tx_vfo); } return RIG_OK; } /* * rig_set_rit* * * Set receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * rit = 0 && xit enabled -> disable rit * rit = 0 && xit disabled -> disable rit and set frequency = 0 */ static int ft1000d_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)rit); // Check for valid clarifier offset frequency if (rit < -9999 || rit > 9999) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // If rit = 0 disable RX clarifier if (rit == 0) { err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT1000D_CLAR_TX_EN) == 0) { err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } // Disable RX Clarifier err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_RX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable RX Clarifier err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_RX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set RX clarifier offset err = ft1000d_send_rit_freq(rig, FT1000D_NATIVE_CLARIFIER_OPS, rit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_rit* * * Get receiver clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * rit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { struct ft1000d_priv_data *priv; unsigned char ci; ft1000d_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } // Construct update query switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT1000D_NATIVE_UPDATE_OP_DATA; p = (ft1000d_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } // Get update for selected VFO/MEM err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT1000D_CLAR_RX_EN) { *rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *rit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: rit freq = %li Hz\n", __func__, *rit); return RIG_OK; } /* * rig_set_xit* * * Set transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit | input | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * * The following conditions are checked: * * xit = 0 && rit enabled -> disable xit * xit = 0 && rit disabled -> disable xit and set frequency = 0 */ static int ft1000d_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %d\n", __func__, (int)xit); if (xit < -9999 || xit > 9999) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } // Disable TX clarifier and return if xit = 0 if (xit == 0) { err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } if ((priv->update_data.current_front.status & FT1000D_CLAR_RX_EN) == 0) { err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_CLEAR_CLARIFIER_OFFSET); if (err != RIG_OK) { return err; } } err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_TX_CLARIFIER_OFF); if (err != RIG_OK) { return err; } } else { // Enable TX Clarifier err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_TX_CLARIFIER_ON); if (err != RIG_OK) { return err; } // Set TX clarifier offset err = ft1000d_send_rit_freq(rig, FT1000D_NATIVE_CLARIFIER_OPS, xit); if (err != RIG_OK) { return err; } } return RIG_OK; } /* * rig_get_xit* * * Get transmitter clarifier offset for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * xit * | output | -9999 - 9999 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { struct ft1000d_priv_data *priv; unsigned char ci; ft1000d_op_data_t *p; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfoa; break; case RIG_VFO_B: ci = FT1000D_NATIVE_UPDATE_VFO_DATA; p = (ft1000d_op_data_t *) &priv->update_data.vfob; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: ci = FT1000D_NATIVE_UPDATE_OP_DATA; p = (ft1000d_op_data_t *) &priv->update_data.current_front; break; default: return -RIG_EINVAL; } err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } // Clarifier offset is only returned when enabled if (p->status & FT1000D_CLAR_TX_EN) { *xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } else { *xit = 0; } rig_debug(RIG_DEBUG_TRACE, "%s: read freq = %li Hz\n", __func__, *xit); return RIG_OK; } /* * rig_set_func* * * Set rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER * status | input | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig functions are vfo independent. */ static int ft1000d_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); rig_debug(RIG_DEBUG_TRACE, "%s: passed status = %d\n", __func__, status); switch (func) { case RIG_FUNC_LOCK: if (status) { ci = FT1000D_NATIVE_LOCK_ON; } else { ci = FT1000D_NATIVE_LOCK_OFF; } break; case RIG_FUNC_TUNER: if (status) { ci = FT1000D_NATIVE_TUNER_ON; } else { ci = FT1000D_NATIVE_TUNER_OFF; } break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_func* * * Get status of a rig function * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * func | input | LOCK, TUNER, MON * status * | output | 0 = off, 1 = on * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the status of rig function are vfo independent. */ static int ft1000d_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed func = %s\n", __func__, rig_strfunc(func)); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } switch (func) { case RIG_FUNC_LOCK: *status = ((priv->update_data.flag2 & FT1000D_SF_LOCKED) != 0); break; case RIG_FUNC_TUNER: *status = ((priv->update_data.flag3 & FT1000D_SF_TUNER_ON) != 0); break; case RIG_FUNC_MON: *status = ((priv->update_data.flag3 & FT1000D_SF_XMIT_MON) != 0); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_parm* * * Set rig parameters that are not VFO specific * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * parm | input | BACKLIGHT * val | input | 0.0..1.0 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: */ static int ft1000d_set_parm(RIG *rig, setting_t parm, value_t val) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed parm = %s\n", __func__, rig_strparm(parm)); rig_debug(RIG_DEBUG_TRACE, "%s: passed val = %f\n", __func__, val.f); switch (parm) { case RIG_PARM_BACKLIGHT: err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_DIM_LEVEL, (unsigned char)(0x0d * val.f), 0, 0, 0); break; default: return -RIG_EINVAL; } if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_set_mode* * * Set operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width | input | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct ft1000d_priv_data *priv; unsigned char bw; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)width); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; // Set to selected VFO if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current.vfo = 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (mode) { case RIG_MODE_AM: if (width == rig_passband_narrow(rig, mode)) { ci = FT1000D_NATIVE_MODE_SET_AM_N; } else if (width == rig_passband_normal(rig, mode)) { ci = FT1000D_NATIVE_MODE_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT1000D_NATIVE_MODE_SET_CW_W; break; case RIG_MODE_USB: ci = FT1000D_NATIVE_MODE_SET_USB; break; case RIG_MODE_LSB: ci = FT1000D_NATIVE_MODE_SET_LSB; break; case RIG_MODE_RTTY: ci = FT1000D_NATIVE_MODE_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT1000D_NATIVE_MODE_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT1000D_NATIVE_MODE_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT1000D_NATIVE_MODE_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT1000D_NATIVE_MODE_SET_PKT_FM; break; default: return -RIG_EINVAL; } err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT1000D_NATIVE_MODE_SET_AM_N || ci == FT1000D_NATIVE_MODE_SET_AM_W || ci == FT1000D_NATIVE_MODE_SET_FM || ci == FT1000D_NATIVE_MODE_SET_PKT_FM) { return RIG_OK; } if (width <= 250) { bw = FT1000D_BW_F250; } else if (width <= 500) { bw = FT1000D_BW_F500; } else if (width <= 2000) { bw = FT1000D_BW_F2000; } else { bw = FT1000D_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_mode* * * Get operating mode and passband for a given VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * mode | input | USB, LSB, CW, AM, FM, RTTY, RTTYR, PKTLSB, PKTFM * width * | output | 2400, 2000, 500, 250 (USB) * | | 2400, 2000, 500, 250 (LSB) * | | 2400, 2000, 500, 250 (CW) * | | 2400, 2000, 500, 250 (RTTY) * | | 2400, 2000, 500, 250 (RTTYR) * | | 2400, 2000, 500, 250 (PKTLSB) * | | 6000, 2400 (AM) * | | 8000 (FM) * | | 8000 (PKTFM) * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft1000d_priv_data *priv; unsigned char *p; unsigned char *fl; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, RIG_VFO_CURR); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: p = &priv->update_data.vfoa.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_VFO: p = &priv->update_data.vfoa.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfoa.filter; break; case RIG_VFO_B: p = &priv->update_data.vfob.mode; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; fl = &priv->update_data.vfob.filter; break; case RIG_VFO_MEM: case RIG_VFO_MAIN: p = &priv->update_data.current_front.mode; ci = FT1000D_NATIVE_UPDATE_OP_DATA; fl = &priv->update_data.current_front.filter; break; default: return -RIG_EINVAL; } // Get update for selected VFO err = ft1000d_get_update_data(rig, ci, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: fl = 0x%02x\n", __func__, *fl); rig_debug(RIG_DEBUG_TRACE, "%s: current mode = 0x%02x\n", __func__, *p); switch (*p) { case FT1000D_MODE_LSB: *mode = RIG_MODE_LSB; break; case FT1000D_MODE_USB: *mode = RIG_MODE_USB; break; case FT1000D_MODE_CW: *mode = RIG_MODE_CW; break; case FT1000D_MODE_AM: *mode = RIG_MODE_AM; break; case FT1000D_MODE_FM: *mode = RIG_MODE_FM; break; case FT1000D_MODE_RTTY: if (*fl & FT1000D_BW_FMPKTRTTY) { *mode = RIG_MODE_RTTYR; } else { *mode = RIG_MODE_RTTY; } break; case FT1000D_MODE_PKT: if (*fl & FT1000D_BW_FMPKTRTTY) { *mode = RIG_MODE_PKTFM; } else { *mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get mode = %s\n", __func__, rig_strrmode(*mode)); // The FT1000D firmware appears to have a bug since the // AM bandwidth for 2400Hz and 6000Hz are interchanged. switch (*fl & (~FT1000D_BW_FMPKTRTTY)) { case FT1000D_BW_F2400: if (*mode == RIG_MODE_FM || *mode == RIG_MODE_PKTFM) { *width = 8000; } else if (*mode == RIG_MODE_AM) // <- FT1000D firmware bug? { *width = 6000; } else { *width = 2400; } break; case FT1000D_BW_F2000: *width = 2000; break; case FT1000D_BW_F500: *width = 500; break; case FT1000D_BW_F250: *width = 250; break; case FT1000D_BW_F6000: *width = 2400; // <- FT1000D firmware bug? break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: get width = %li Hz\n", __func__, *width); return RIG_OK; } /* * rig_set_vfo* * * Set operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_set_vfo(RIG *rig, vfo_t vfo) { struct ft1000d_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: MADE IT TO STATE(rig)->priv = 0x%02x\n", __func__, RIG_VFO_CURR); // if (vfo == RIG_VFO_CURR) { if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } switch (vfo) { case RIG_VFO_A: ci = FT1000D_NATIVE_VFO_A; rig_debug(RIG_DEBUG_TRACE, "%s: MADE IT TO VFO A = 0x%02x\n", __func__, RIG_VFO_CURR); break; case RIG_VFO_B: ci = FT1000D_NATIVE_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: MADE IT TO VFO B = 0x%02x\n", __func__, RIG_VFO_CURR); break; case RIG_VFO_MEM: ci = FT1000D_NATIVE_RECALL_MEM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set ci = %i\n", __func__, ci); if (vfo == RIG_VFO_MEM) { err = ft1000d_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); rig_debug(RIG_DEBUG_TRACE, "%s: set mem channel = 0x%02x\n", __func__, priv->update_data.channelnumber + 1); } else { err = ft1000d_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } priv->current_vfo = vfo; return RIG_OK; } /* * rig_get_vfo* * * Get operational VFO * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo * | output | VFOA, VFOB, MEM * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. * The result is stored in the priv->current_vfo data structure * for later retrieval. */ static int ft1000d_get_vfo(RIG *rig, vfo_t *vfo) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); *vfo = RIG_VFO_CURR; if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; /* Get flags for VFO status */ err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } if (priv->update_data.flag2 & FT1000D_SF_MEM || priv->update_data.flag2 & FT1000D_SF_MTUNE) { priv->current_vfo = RIG_VFO_MEM; } else if (priv->update_data.flag1 & FT1000D_SF_VFOB_INUSE) { priv->current_vfo = RIG_VFO_B; } else { priv->current_vfo = RIG_VFO_A; } rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_1 = 0x%02x\n", __func__, priv->update_data.flag1); rig_debug(RIG_DEBUG_TRACE, "%s: vfo status_2 = 0x%02x\n", __func__, priv->update_data.flag2); rig_debug(RIG_DEBUG_TRACE, "%s: stat_vfo = 0x%02x\n", __func__, priv->current_vfo); *vfo = priv->current_vfo; return RIG_OK; } /* * rig_get_level * * This function will read the meter level.The data * is processed depending upon selection of the level * parameter. The following are the currently supported * levels and returned value range: * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, Main, VFO, VFOA, VFOB, MEM * level | input | STRENGTH, ALC, COMP, RFPOWER, SWR * value * | output | see table below * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * ---------------------------------------------------------- * level | Description | Returned Value | Units | * ---------------------------------------------------------- * STRENGTH | Signal Strength | -54 .. +60 | db | * COMP | Compression | 0.0 .. 1.0 | %/100 | * RFPOWER | RF Power Output | 0.0 .. 1.0 | %/100 | * SWR | Standing Wave Ratio | 0.0 .. 1.0 | %/100 | * ---------------------------------------------------------- * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *value) { struct ft1000d_priv_data *priv; unsigned char mdata[YAESU_CMD_LENGTH]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed level %s\n", __func__, rig_strlevel(level)); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } err = ft1000d_send_static_cmd(rig, FT1000D_NATIVE_READ_METER); if (err != RIG_OK) { return err; } err = read_block(RIGPORT(rig), mdata, FT1000D_READ_METER_LENGTH); if (err < 0) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: meter data %d\n", __func__, mdata[0]); switch (level) { case RIG_LEVEL_STRENGTH: value->i = mdata[0] / 2.246 - 54; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %d\n", __func__, value->i); break; case RIG_LEVEL_ALC: case RIG_LEVEL_COMP: case RIG_LEVEL_RFPOWER: case RIG_LEVEL_SWR: value->f = (float) mdata[0] / 255; rig_debug(RIG_DEBUG_TRACE, "%s: meter level %f\n", __func__, value->f); break; default: return -RIG_EINVAL; } return RIG_OK; } /* * rig_vfo_op* * * Perform vfo operations * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | VFOA, VFOB, MEM * op | input | CPY = copy from VFO to VFO * | | FROM_VFO = copy from VFO to MEM * | | TO_VFO = copy from MEM to VFO * | | UP = step dial frequency up * | | DOWN = step dial frequency down * | | TUNE = start antenna tuner * | | TOGGLE = toggle between VFOA and VFOB * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing currVFO to vfo will use the currently selected VFO * obtained from the priv->current_vfo data structure. * In all other cases the passed vfo is selected if it differs * from the currently selected VFO. */ static int ft1000d_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { struct ft1000d_priv_data *priv; unsigned char ci; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed op %sn", __func__, rig_strvfop(op)); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo 0x%02x\n", __func__, vfo); } else { if (vfo != priv->current_vfo) { err = ft1000d_set_vfo(rig, vfo); if (err != RIG_OK) { return err; } } } switch (op) { case RIG_OP_CPY: ci = FT1000D_NATIVE_VFO_TO_VFO; break; case RIG_OP_FROM_VFO: ci = FT1000D_NATIVE_VFO_TO_MEM; break; case RIG_OP_TO_VFO: ci = FT1000D_NATIVE_MEM_TO_VFO; break; case RIG_OP_UP: ci = FT1000D_NATIVE_OP_FREQ_STEP_UP; break; case RIG_OP_DOWN: ci = FT1000D_NATIVE_OP_FREQ_STEP_DOWN; break; case RIG_OP_TUNE: ci = FT1000D_NATIVE_TUNER_START; break; case RIG_OP_TOGGLE: switch (vfo) { case RIG_VFO_A: ci = FT1000D_NATIVE_VFO_B; vfo = RIG_VFO_B; break; case RIG_VFO_B: ci = FT1000D_NATIVE_VFO_A; vfo = RIG_VFO_A; break; default: return -RIG_EINVAL; } break; default: return -RIG_EINVAL; } if (op == RIG_OP_TO_VFO || op == RIG_OP_FROM_VFO) err = ft1000d_send_dynamic_cmd(rig, ci, priv->update_data.channelnumber + 1, 0, 0, 0); else { err = ft1000d_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } if (op == RIG_OP_TOGGLE) { priv->current_vfo = vfo; } return RIG_OK; } /* * rig_set_mem* * * Set main vfo to selected memory channel number * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch | input | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since the * the channel selection is vfo independent. */ static int ft1000d_set_mem(RIG *rig, vfo_t vfo, int ch) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ch = %i\n", __func__, ch); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; // Check for valid channel number if (ch < 1 || ch > 90) { return -RIG_EINVAL; } // Recall selected memory channel err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (err != RIG_OK) { return err; } priv->current_vfo = RIG_VFO_MEM; priv->update_data.channelnumber = ch - 1; return RIG_OK; } /* * rig_get_mem* * * Get memory channel number used by main vfo * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * ch * | output | 1 - 90 * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: The passed value for the vfo is ignored since * the channel selection is vfo independent. */ static int ft1000d_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (vfo == RIG_VFO_CURR) { vfo = priv->current_vfo; rig_debug(RIG_DEBUG_TRACE, "%s: priv->current_vfo = 0x%02x\n", __func__, vfo); } err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: channel number %i\n", __func__, priv->update_data.channelnumber + 1); *ch = priv->update_data.channelnumber + 1; // Check for valid channel number if (*ch < 1 || *ch > 90) { return -RIG_EINVAL; } return RIG_OK; } /* * rig_set_channel* * * Set memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | channel attribute data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure */ static int ft1000d_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } return -RIG_ENIMPL; } /* * rig_get_channel* * * Get memory channel parameters and attributes * * Parameter | Type | Accepted/Expected Values * ------------------------------------------------------------------------- * RIG * | input | pointer to private data * chan * | input | (chan->vfo) currVFO, VFOA, VFOB, MEM * | | (chan->channel_num) 0 - 90 * chan * | output | channel attributes data structure * ------------------------------------------------------------------------- * Returns RIG_OK on success or an error code on failure * * Comments: Passing a memory channel number of 0 returns information on * the current channel or channel last in use. * * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ static int ft1000d_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { struct ft1000d_priv_data *priv; ft1000d_op_data_t *p; char ci; int err; channel_t _chan; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->vfo = %i\n", __func__, chan->vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed chan->channel_num = %i\n", __func__, chan->channel_num); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (chan->channel_num < 0 || chan->channel_num > 90) { return -RIG_EINVAL; } /* * Get a clean slate so we don't have to assign value to * variables that are not relevant to this equipment */ _chan.channel_num = chan->channel_num; _chan.vfo = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = _chan.channel_num; chan->vfo = _chan.vfo; if (chan->channel_num == 0) { switch (chan->vfo) { // Current or last selected memory channel case RIG_VFO_MEM: err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_MEM_CHNL, 0); if (err != RIG_OK) { return err; } chan->channel_num = priv->update_data.channelnumber + 1; p = (ft1000d_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA; break; case RIG_VFO_A: p = (ft1000d_op_data_t *) &priv->update_data.vfoa; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_B: p = (ft1000d_op_data_t *) &priv->update_data.vfob; ci = FT1000D_NATIVE_UPDATE_VFO_DATA; break; case RIG_VFO_CURR: p = (ft1000d_op_data_t *) &priv->update_data.current_front; ci = FT1000D_NATIVE_UPDATE_OP_DATA; break; default: return -RIG_EINVAL; } } else { p = (ft1000d_op_data_t *) &priv->update_data.channel[chan->channel_num]; ci = FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA; chan->vfo = RIG_VFO_MEM; } /* * Get data for selected VFO/MEM */ err = ft1000d_get_update_data(rig, ci, chan->channel_num); if (err != RIG_OK) { return err; } // Blanked memory, nothing to report if (p->bpf & FT1000D_EMPTY_MEM) { return RIG_OK; } /* * Get RX frequency */ chan->freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT1000D_MODE_LSB: chan->mode = RIG_MODE_LSB; break; case FT1000D_MODE_USB: chan->mode = RIG_MODE_USB; break; case FT1000D_MODE_CW: chan->mode = RIG_MODE_CW; break; case FT1000D_MODE_AM: chan->mode = RIG_MODE_AM; break; case FT1000D_MODE_FM: chan->mode = RIG_MODE_FM; break; case FT1000D_MODE_RTTY: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->mode = RIG_MODE_RTTYR; } else { chan->mode = RIG_MODE_RTTY; } break; case FT1000D_MODE_PKT: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->mode = RIG_MODE_PKTFM; } else { chan->mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s\n", __func__, rig_strrmode(p->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT1000D firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT1000D_BW_FMPKTRTTY)) { case FT1000D_BW_F2400: if (chan->mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->width = 8000; } else if (chan->mode == RIG_MODE_AM) // <- FT1000D firmware bug? { chan->width = 6000; } else { chan->width = 2400; } break; case FT1000D_BW_F2000: chan->width = 2000; break; case FT1000D_BW_F500: chan->width = 500; break; case FT1000D_BW_F250: chan->width = 250; break; case FT1000D_BW_F6000: chan->width = 2400; // <- FT1000D firmware bug? break; default: return -RIG_EINVAL; } err = ft1000d_get_update_data(rig, FT1000D_NATIVE_READ_FLAGS, 0); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, priv->update_data.flag1); /* * Status for split operation, active rig functions and tuning steps * are only relevant for currVFO */ if (chan->vfo & RIG_VFO_CURR) { chan->split = (priv->update_data.flag1 & FT1000D_SF_SPLIT); if (priv->update_data.flag1 & FT1000D_SF_XMIT_MON) { chan->funcs |= RIG_FUNC_MON; } if (priv->update_data.flag1 & FT1000D_SF_TUNER_ON) { chan->funcs |= RIG_FUNC_TUNER; } if (priv->update_data.flag1 & FT1000D_SF_ANT_TUNER_ACTIVE) { if (chan->mode & (FT1000D_AM_RX_MODES | FT1000D_FM_RX_MODES)) { chan->tuning_step = 1000; } else { chan->tuning_step = 100; } } else { if (chan->mode & (FT1000D_AM_RX_MODES | FT1000D_FM_RX_MODES)) { chan->tuning_step = 100; } else { chan->tuning_step = 10; } } } /* * Get RIT frequencies */ if (p->status & FT1000D_CLAR_RX_EN) { chan->rit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } if (chan->split & RIG_SPLIT_ON) { // Get data for the transmit VFO p = (ft1000d_op_data_t *) &priv->update_data.current_rear; /* FT1000D */ if (RIG_MODEL_FT1000D == rig->caps->rig_model) { p = (ft1000d_op_data_t *) &priv->update_data.vfob; } chan->tx_freq = ((((p->basefreq[0] << 8) + p->basefreq[1]) << 8) + p->basefreq[2]) * 10; /* * Get RX operating mode */ switch (p->mode) { case FT1000D_MODE_LSB: chan->tx_mode = RIG_MODE_LSB; break; case FT1000D_MODE_USB: chan->tx_mode = RIG_MODE_USB; break; case FT1000D_MODE_CW: chan->tx_mode = RIG_MODE_CW; break; case FT1000D_MODE_AM: chan->tx_mode = RIG_MODE_AM; break; case FT1000D_MODE_FM: chan->tx_mode = RIG_MODE_FM; break; case FT1000D_MODE_RTTY: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_RTTYR; } else { chan->tx_mode = RIG_MODE_RTTY; } break; case FT1000D_MODE_PKT: if (p->filter & FT1000D_BW_FMPKTRTTY) { chan->tx_mode = RIG_MODE_PKTFM; } else { chan->tx_mode = RIG_MODE_PKTLSB; } break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: set tx mode = %s\n", __func__, rig_strrmode(chan->mode)); rig_debug(RIG_DEBUG_TRACE, "%s: tx filter = 0x%02x\n", __func__, p->filter); /* * Get RX bandwidth selection * * The FT1000D firmware appears to have a bug since the * AM bandwidth for 2400Hz and 6000Hz are interchanged. */ switch (p->filter & (~FT1000D_BW_FMPKTRTTY)) { case FT1000D_BW_F2400: if (chan->tx_mode == RIG_MODE_FM || chan->mode == RIG_MODE_PKTFM) { chan->tx_width = 8000; } else if (chan->tx_mode == RIG_MODE_AM) // <- FT1000D firmware bug? { chan->tx_width = 6000; } else { chan->tx_width = 2400; } break; case FT1000D_BW_F2000: chan->tx_width = 2000; break; case FT1000D_BW_F500: chan->tx_width = 500; break; case FT1000D_BW_F250: chan->tx_width = 250; break; case FT1000D_BW_F6000: chan->tx_width = 2400; // <- FT1000D firmware bug? break; default: return -RIG_EINVAL; } /* For now commented this out to better understand what's going on */ if (priv->update_data.flag1 & FT1000D_SF_DUAL) { if (chan->tx_vfo & (RIG_VFO_A | RIG_VFO_MEM)) { chan->tx_vfo = RIG_VFO_B; } else if (chan->vfo & RIG_VFO_MEM) { chan->tx_vfo = RIG_VFO_A; } else { chan->tx_vfo = RIG_VFO_MEM; } } else { if (chan->vfo & RIG_VFO_A) { chan->tx_vfo = RIG_VFO_MEM; } else { chan->tx_vfo = RIG_VFO_A; } } /* * Get XIT frequencies */ if (p->status & FT1000D_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } else { /* * RX/TX frequency, mode, bandwidth and vfo are identical in simplex mode */ chan->tx_freq = chan->freq; chan->tx_mode = chan->mode; chan->tx_width = chan->width; chan->tx_vfo = chan->vfo; /* * Get XIT frequencies */ if (p->status & FT1000D_CLAR_TX_EN) { chan->xit = (short)((p->coffset[0] << 8) | p->coffset[1]) * 10; } } rig_debug(RIG_DEBUG_TRACE, "%s: set status = %i\n", __func__, p->status); /* * Repeater shift only possible if transmit mode is FM */ if (chan->tx_mode & RIG_MODE_FM) { chan->rptr_shift = (p->status & FT1000D_RPT_MASK) >> 2; } /* * Check for skip channel for memory channels */ if (chan->vfo & RIG_VFO_MEM) { chan->flags |= RIG_CHFLAG_SKIP; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* * Private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * Extended to be command agnostic as 990 has several ways to * get data and several ways to return it. * * Need to use this when doing FT1000D_get_* stuff * * Arguments: *rig Valid RIG instance * ci command index * rl expected length of returned data in octets * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_get_update_data(RIG *rig, unsigned char ci, unsigned short ch) { hamlib_port_t *rp = RIGPORT(rig); struct ft1000d_priv_data *priv; int n; int err; int rl; int retry; unsigned char temp[5]; unsigned char *p; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: passed ci 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed ch 0x%02x\n", __func__, ch); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; retry = rp->retry; do { if (ci == FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA) // P4 = 0x01 to 0x5a for channel 1 - 90 { err = ft1000d_send_dynamic_cmd(rig, ci, 4, 0, 0, ch); } else { err = ft1000d_send_static_cmd(rig, ci); } if (err != RIG_OK) { return err; } switch (ci) { case FT1000D_NATIVE_UPDATE_ALL_DATA: p = (unsigned char *) &priv->update_data; rl = FT1000D_ALL_DATA_LENGTH; /* FT1000D */ if (RIG_MODEL_FT1000D == rig->caps->rig_model) { return RIG_OK; } break; case FT1000D_NATIVE_UPDATE_MEM_CHNL: p = (unsigned char *) &priv->update_data.channelnumber; rl = FT1000D_MEM_CHNL_LENGTH; break; case FT1000D_NATIVE_UPDATE_OP_DATA: p = (unsigned char *) &priv->update_data.current_front; rl = FT1000D_OP_DATA_LENGTH; /* FT1000D */ if (RIG_MODEL_FT1000D == rig->caps->rig_model) { rl = FT1000D_OP_DATA_LENGTH; } break; case FT1000D_NATIVE_UPDATE_VFO_DATA: p = (unsigned char *) &priv->update_data.vfoa; rl = FT1000D_VFO_DATA_LENGTH; break; case FT1000D_NATIVE_UPDATE_MEM_CHNL_DATA: p = (unsigned char *) &priv->update_data.channel[ch]; rl = FT1000D_MEM_CHNL_DATA_LENGTH; break; case FT1000D_NATIVE_READ_FLAGS: p = temp; rl = FT1000D_STATUS_FLAGS_LENGTH; break; default: return -RIG_EINVAL; } n = read_block(rp, p, rl); } while (n < 0 && retry-- >= 0); if (n < 0) { return n; /* die returning read_block error */ } rig_debug(RIG_DEBUG_TRACE, "%s: read %i bytes\n", __func__, n); if (ci == FT1000D_NATIVE_READ_FLAGS) { memcpy(&priv->update_data, p, FT1000D_STATUS_FLAGS_LENGTH - 2); } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_static_cmd(RIG *rig, unsigned char ci) { int err; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: ci = 0x%02x\n", __func__, ci); if (!rig) { return -RIG_EINVAL; } if (!ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } err = write_block(rp, ncmd[ci].nseq, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { struct ft1000d_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed p1 = 0x%02x, p2 = 0x%02x, p3 = 0x%02x, p4 = 0x%02x,\n", __func__, p1, p2, p3, p4); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); priv->p_cmd[3] = p1; priv->p_cmd[2] = p2; priv->p_cmd[1] = p3; priv->p_cmd[0] = p4; err = write_block(rp, (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* * Private helper function to build and send a complete command to * change the display frequency. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * freq freq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_dial_freq(RIG *rig, unsigned char ci, freq_t freq) { struct ft1000d_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int err; // cppcheck-suppress * char *fmt = "%s: requested freq after conversion = %"PRIll" Hz\n"; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, freq); priv = (struct ft1000d_priv_data *)STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } /* Copy native cmd freq_set to private cmd storage area */ memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); /* store bcd format in in p_cmd */ to_bcd(priv->p_cmd, freq / 10, FT1000D_BCD_DIAL); rig_debug(RIG_DEBUG_TRACE, fmt, __func__, (int64_t)from_bcd(priv->p_cmd, FT1000D_BCD_DIAL) * 10); err = write_block(rp, (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* * Private helper function to build and send a complete command to * change the rit frequency. * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * rit shortfreq_t frequency value * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int ft1000d_send_rit_freq(RIG *rig, unsigned char ci, shortfreq_t rit) { struct ft1000d_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed ci = 0x%02x\n", __func__, ci); rig_debug(RIG_DEBUG_TRACE, "%s: passed rit = %li Hz\n", __func__, rit); priv = (struct ft1000d_priv_data *) STATE(rig)->priv; if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } // Copy native command into privat command storage area memcpy(&priv->p_cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); // Reset current clarifier offset priv->p_cmd[3] = FT1000D_CLAR_CLEAR; // Check and set tuning direction - up or down if (rit < 0) { priv->p_cmd[2] = FT1000D_CLAR_TUNE_DOWN; } else { priv->p_cmd[2] = FT1000D_CLAR_TUNE_UP; } // Store bcd format into privat command storage area to_bcd(priv->p_cmd, labs(rit) / 10, FT1000D_BCD_RIT); err = write_block(rp, (unsigned char *) &priv->p_cmd, YAESU_CMD_LENGTH); if (err != RIG_OK) { return err; } hl_usleep(rp->write_delay * 1000); return RIG_OK; } /* COMMANDS ADDED IN DECEMBER 2016 TO INCLUDE EXTRA FUNCTIONS OF THE FT1000D */ /* rig_set_split_freq* * * Set the FT1000D split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_freq | input | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: The FT1000D is capable of setting the Sub VFO's frequency * regardless of whether or not the rig is in Split or Dual mode. * */ static int ft1000d_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int err; // struct ft1000d_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = 0x%02x\n", __func__, vfo); rig_debug(RIG_DEBUG_TRACE, "%s: passed freq = %"PRIfreq" Hz\n", __func__, tx_freq); err = rig_set_split_vfo(rig, vfo, RIG_SPLIT_ON, RIG_VFO_B); if (err != RIG_OK) { return err; } // priv = (struct ft1000d_priv_data *)STATE(rig)->priv; err = ft1000d_send_dial_freq(rig, FT1000D_NATIVE_SET_SUB_VFO_FREQ, tx_freq); if (err != RIG_OK) { return err; } // Get current rig settings and status err = ft1000d_get_update_data(rig, FT1000D_NATIVE_UPDATE_OP_DATA, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_freq* * * Get the 'FT1000D split TX freq * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_freq | output | split transmit frequency * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the FT1000D is in split mode, if so it * checks which VFO is set for TX and then gets the * frequency of that VFO and stores it into *tx_freq. * If not in split mode returns 0 Hz. * */ static int ft1000d_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *) STATE(rig)->priv; err = ft1000d_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* FT1000D is in split mode */ err = ft1000d_get_freq(rig, priv->split_vfo, tx_freq); if (err != RIG_OK) { return err; } break; default: *tx_freq = 0; break; } return RIG_OK; } /* * rig_set_split_mode * * Set the FT1000D split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * tx_mode | input | supported modes * tx_width | input | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Sends mode commands directly to Sub VFOB whether or not radio is in * Split or Dual modes. * */ static int ft1000d_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int err; unsigned char bw; unsigned char ci; // struct ft1000d_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: passed vfo = %s\n", __func__, rig_strvfo(vfo)); rig_debug(RIG_DEBUG_TRACE, "%s: passed mode = %s\n", __func__, rig_strrmode(tx_mode)); rig_debug(RIG_DEBUG_TRACE, "%s: passed width = %d Hz\n", __func__, (int)tx_width); // priv = (struct ft1000d_priv_data *)STATE(rig)->priv; switch (tx_mode) { case RIG_MODE_AM: if (tx_width == rig_passband_narrow(rig, tx_mode)) { ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_N; } else if (tx_width == rig_passband_normal(rig, tx_mode)) { ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_W; } else { return -RIG_EINVAL; } break; case RIG_MODE_CW: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_CW_W; break; case RIG_MODE_USB: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_USB; break; case RIG_MODE_LSB: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_LSB; break; case RIG_MODE_RTTY: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_LSB; break; case RIG_MODE_RTTYR: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_RTTY_USB; break; case RIG_MODE_FM: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_FM; break; case RIG_MODE_PKTLSB: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_LSB; break; case RIG_MODE_PKTFM: ci = FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_FM; break; default: return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: ci = 0x%02x\n", __func__, ci); err = ft1000d_send_static_cmd(rig, ci); if (err != RIG_OK) { return err; } if (ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_N || ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_AM_W || ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_FM || ci == FT1000D_NATIVE_MODE_SUB_VFOB_SET_PKT_FM) { return RIG_OK; } if (tx_width <= 250) { bw = FT1000D_BW_F250; } else if (tx_width <= 500) { bw = FT1000D_BW_F500; } else if (tx_width <= 2000) { bw = FT1000D_BW_F2000; } else { bw = FT1000D_BW_F2400; } rig_debug(RIG_DEBUG_TRACE, "%s: set bw = 0x%02x\n", __func__, bw); err = ft1000d_send_dynamic_cmd(rig, FT1000D_NATIVE_BANDWIDTH, bw, 0, 0, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * rig_get_split_mode* * * Get the '920 split TX mode * * Parameter | Type | Accepted/expected values * ------------------------------------------------------------------ * *rig | input | pointer to private data * vfo | input | currVFO, VFOA, VFOB, MEM * *tx_mode | output | supported modes * *tx_width | output | supported widths * ------------------------------------------------------------------ * Returns RIG_OK on success or an error code on failure * * Comments: Checks to see if the 920 is in split mode, if so it * checks which VFO is set for TX and then gets the * mode and passband of that VFO and stores it into *tx_mode * and tx_width respectively. If not in split mode returns * RIG_MODE_NONE and 0 Hz. * */ static int ft1000d_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { struct ft1000d_priv_data *priv; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } priv = (struct ft1000d_priv_data *)STATE(rig)->priv; err = ft1000d_get_split_vfo(rig, vfo, &priv->split, &priv->split_vfo); if (err != RIG_OK) { return err; } switch ((int)priv->split) { case TRUE: /* FT1000D is in split mode */ err = ft1000d_get_mode(rig, priv->split_vfo, tx_mode, tx_width); if (err != RIG_OK) { return err; } break; default: *tx_mode = RIG_MODE_NONE; *tx_width = 0; break; } return RIG_OK; } static int ft1000_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { if (vfo == RIG_VFO_CURR) { rig_debug(RIG_DEBUG_TRACE, "%s: current_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); vfo = STATE(rig)->current_vfo; } if (vfo == RIG_VFO_A) { *freq = CACHE(rig)->freqMainA; } else { *freq = CACHE(rig)->freqMainB; } return RIG_OK; } static int ft1000_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { if (vfo == RIG_VFO_A) { *mode = CACHE(rig)->modeMainA; } else { *mode = CACHE(rig)->modeMainB; } return RIG_OK; } static int ft1000_get_vfo(RIG *rig, vfo_t *vfo) { *vfo = STATE(rig)->current_vfo; return RIG_OK; } static int ft1000_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { *ptt = CACHE(rig)->ptt; return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft100.c0000644000175000017500000010365014752216205013001 00000000000000/* * hamlib - (C) Frank Singleton 2000-2003 * (C) Stephane Fillod 2000-2010 * * ft100.c - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-100 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft100.h" #include "misc.h" #include "bandplan.h" enum ft100_native_cmd_e { FT100_NATIVE_CAT_LOCK_ON = 0, FT100_NATIVE_CAT_LOCK_OFF, FT100_NATIVE_CAT_PTT_ON, FT100_NATIVE_CAT_PTT_OFF, FT100_NATIVE_CAT_SET_FREQ, FT100_NATIVE_CAT_SET_MODE_LSB, FT100_NATIVE_CAT_SET_MODE_USB, FT100_NATIVE_CAT_SET_MODE_CW, FT100_NATIVE_CAT_SET_MODE_CWR, FT100_NATIVE_CAT_SET_MODE_AM, FT100_NATIVE_CAT_SET_MODE_FM, FT100_NATIVE_CAT_SET_MODE_DIG, FT100_NATIVE_CAT_SET_MODE_WFM, FT100_NATIVE_CAT_CLAR_ON, FT100_NATIVE_CAT_CLAR_OFF, FT100_NATIVE_CAT_SET_CLAR_FREQ, FT100_NATIVE_CAT_SET_VFOAB, FT100_NATIVE_CAT_SET_VFOA, FT100_NATIVE_CAT_SET_VFOB, FT100_NATIVE_CAT_SPLIT_ON, FT100_NATIVE_CAT_SPLIT_OFF, FT100_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT100_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT100_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT100_NATIVE_CAT_SET_RPT_OFFSET, /* fix me */ FT100_NATIVE_CAT_SET_DCS_ON, FT100_NATIVE_CAT_SET_CTCSS_ENC_ON, FT100_NATIVE_CAT_SET_CTCSS_ENC_DEC_ON, FT100_NATIVE_CAT_SET_CTCSS_DCS_OFF, /* em xif */ FT100_NATIVE_CAT_SET_CTCSS_FREQ, FT100_NATIVE_CAT_SET_DCS_CODE, FT100_NATIVE_CAT_GET_RX_STATUS, FT100_NATIVE_CAT_GET_TX_STATUS, FT100_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT100_NATIVE_CAT_PWR_WAKE, FT100_NATIVE_CAT_PWR_ON, FT100_NATIVE_CAT_PWR_OFF, FT100_NATIVE_CAT_READ_STATUS, FT100_NATIVE_CAT_READ_METERS, FT100_NATIVE_CAT_READ_FLAGS, FT100_NATIVE_SIZE /* end marker */ }; /* * we are able to get way more info * than we can set * */ typedef struct { unsigned char band_no; unsigned char freq[4]; unsigned char mode; unsigned char ctcss; unsigned char dcs; unsigned char flag1; unsigned char flag2; unsigned char clarifier[2]; unsigned char not_used; unsigned char step1; unsigned char step2; unsigned char filter; unsigned char stuffing[16]; } FT100_STATUS_INFO; typedef struct { unsigned char mic_switch_1; unsigned char tx_fwd_power; unsigned char tx_rev_power; unsigned char s_meter; unsigned char mic_level; unsigned char squelch_level; unsigned char mic_switch_2; unsigned char final_temp; unsigned char alc_level; } FT100_METER_INFO; typedef struct { unsigned char byte[8]; } FT100_FLAG_INFO; static int ft100_init(RIG *rig); static int ft100_open(RIG *rig); static int ft100_cleanup(RIG *rig); static int ft100_close(RIG *rig); static int ft100_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft100_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft100_set_vfo(RIG *rig, vfo_t vfo); static int ft100_get_vfo(RIG *rig, vfo_t *vfo); static int ft100_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft100_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); #if 0 static int ft100_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int ft100_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft100_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int ft100_set_parm(RIG *rig, setting_t parm, value_t val); static int ft100_get_parm(RIG *rig, setting_t parm, value_t *val); #endif static int ft100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft100_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft100_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft100_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift); static int ft100_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft100_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code); static int ft100_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft100_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); //static int ft100_get_info(RIG *rig, FT100_STATUS_INFO *ft100_status, FT100_METER_INFO *ft100_meter, FT100_FLAG_INFO *ft100_flags); struct ft100_priv_data { /* TODO: make use of cached data */ FT100_STATUS_INFO status; FT100_FLAG_INFO flags; }; /* prototypes */ static int ft100_send_priv_cmd(RIG *rig, unsigned char cmd_index); /* Native ft100 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ /* kc2ivl - what works on a ft100 as of 02/27/2002 */ /* ptt on/off */ /* set mode AM,CW,USB,LSB,FM use PKTUSB for DIG mode*/ /* set split on/off */ /* set repeater +, - splx */ /* set frequency of current vfo */ static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* mode set main LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* mode set main USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* mode set main CW */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* mode set main CWR */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* mode set main AM */ { 1, { 0x00, 0x00, 0x00, 0x06, 0x0c } }, /* mode set main FM */ { 1, { 0x00, 0x00, 0x00, 0x05, 0x0c } }, /* mode set main DIG */ { 1, { 0x00, 0x00, 0x00, 0x07, 0x0c } }, /* mode set main WFM */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set clar freq */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* select vfo a */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x05 } }, /* select vfo b */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x01 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* split off */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x84 } }, /* set RPT shift MINUS */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x84 } }, /* set RPT shift PLUS */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x84 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* set RPT offset freq */ /* fix me */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x92 } }, /* set DCS on */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x92 } }, /* set CTCSS/DCS enc/dec on */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x92 } }, /* set CTCSS/DCS enc on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x92 } }, /* set CTCSS/DCS off */ /* em xif */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x90 } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x91 } }, /* set DCS code */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get RX status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* get TX status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* get FREQ and MODE status */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr wakeup sequence */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr on */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* pwr off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x10 } }, /* read status block */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* read meter block */ { 1, { 0x00, 0x00, 0x00, 0x01, 0xfa } } /* read flags block */ }; static tone_t ft100_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, \ 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, \ 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, \ 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, \ 2503, 0 }; static tone_t ft100_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, \ 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, \ 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, \ 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, \ 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, \ 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, \ 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, \ 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, \ 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, \ 0, }; #define FT100_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_FM) #define FT100_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB) #define FT100_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM) #define FT100_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_FM) #define FT100_AM_TX_MODES (RIG_MODE_AM) #define FT100_GET_RIG_LEVELS (RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER|\ RIG_LEVEL_SWR|RIG_LEVEL_ALC|RIG_LEVEL_MICGAIN|RIG_LEVEL_SQL) #define FT100_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL) #define FT100_VFO_ALL (RIG_VFO_A|RIG_VFO_B) /* S-meter calibration, ascending order of RAW values */ #define FT100_STR_CAL { 9, \ { \ { 90, 60 }, /* +60 */ \ { 105, 40 }, /* +40 */ \ { 115, 20 }, /* +20 */ \ { 120, 0 }, /* S9 */ \ { 130, -6 }, /* S8 */ \ { 140, -12 }, /* S7 */ \ { 160, -18 }, /* S6 */ \ { 180, -24 }, /* S5 */ \ { 200, -54 } /* S0 */ \ } } struct rig_caps ft100_caps = { RIG_MODEL(RIG_MODEL_FT100), .model_name = "FT-100", .mfg_name = "Yaesu", .version = "20240910.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, /* ft100/d 4800 only */ .serial_rate_max = 4800, /* no others allowed */ .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT100_WRITE_DELAY, .post_write_delay = FT100_POST_WRITE_DELAY, .timeout = 100, .retry = 0, .has_get_func = RIG_FUNC_NONE, .has_set_func = FT100_FUNC_ALL, .has_get_level = FT100_GET_RIG_LEVELS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = ft100_ctcss_list, .dcs_list = ft100_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory chan .list = 78 */ .rx_range_list1 = { {kHz(100), MHz(56), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(108), MHz(154), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(420), MHz(470), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_HF(1, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(1, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(1, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(1, FT100_OTHER_TX_MODES, W(0.5), W(50), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(1, FT100_AM_TX_MODES, W(0.5), W(12.5), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(1, FT100_OTHER_TX_MODES, W(0.5), W(20), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(1, FT100_AM_TX_MODES, W(0.5), W(5), FT100_VFO_ALL, RIG_ANT_CURR), }, .rx_range_list2 = { {kHz(100), MHz(56), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(108), MHz(154), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, {MHz(420), MHz(470), FT100_ALL_RX_MODES, -1, -1, FT100_VFO_ALL, RIG_ANT_CURR}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_HF(2, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(2, FT100_OTHER_TX_MODES, W(0.5), W(100), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_6m(2, FT100_AM_TX_MODES, W(0.5), W(25), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(2, FT100_OTHER_TX_MODES, W(0.5), W(50), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_2m(2, FT100_AM_TX_MODES, W(0.5), W(12.5), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(2, FT100_OTHER_TX_MODES, W(0.5), W(20), FT100_VFO_ALL, RIG_ANT_CURR), FRQ_RNG_70cm(2, FT100_AM_TX_MODES, W(0.5), W(5), FT100_VFO_ALL, RIG_ANT_CURR), RIG_FRNG_END, }, .tuning_steps = { /* FIXME */ {FT100_SSB_CW_RX_MODES, 10}, {FT100_SSB_CW_RX_MODES, 100}, {FT100_AM_FM_RX_MODES, 10}, {FT100_AM_FM_RX_MODES, 100}, {RIG_MODE_WFM, kHz(5)}, {RIG_MODE_WFM, kHz(50)}, RIG_TS_END, }, .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PKTUSB, Hz(300)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR | RIG_MODE_PKTUSB, Hz(500)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6)}, {RIG_MODE_WFM, kHz(230)}, RIG_FLT_END, }, .str_cal = FT100_STR_CAL, .priv = NULL, .rig_init = ft100_init, .rig_cleanup = ft100_cleanup, .rig_open = ft100_open, .rig_close = ft100_close, .set_freq = ft100_set_freq, .get_freq = ft100_get_freq, .set_mode = ft100_set_mode, .get_mode = ft100_get_mode, .set_vfo = ft100_set_vfo, .get_vfo = ft100_get_vfo, .set_ptt = ft100_set_ptt, .get_ptt = ft100_get_ptt, .get_dcd = NULL, .set_rptr_shift = ft100_set_rptr_shift, .get_rptr_shift = ft100_get_rptr_shift, .set_rptr_offs = NULL, .get_rptr_offs = NULL, .set_split_freq = NULL, .get_split_freq = NULL, .set_split_mode = NULL, .get_split_mode = NULL, .set_split_vfo = ft100_set_split_vfo, .get_split_vfo = ft100_get_split_vfo, .set_rit = NULL, .get_rit = NULL, .set_xit = NULL, .get_xit = NULL, .set_ts = NULL, .get_ts = NULL, .set_dcs_code = ft100_set_dcs_code, .get_dcs_code = ft100_get_dcs_code, .set_ctcss_tone = ft100_set_ctcss_tone, .get_ctcss_tone = ft100_get_ctcss_tone, .set_dcs_sql = NULL, .get_dcs_sql = NULL, .set_ctcss_sql = NULL, .get_ctcss_sql = NULL, .set_powerstat = NULL, .get_powerstat = NULL, .reset = NULL, .set_ant = NULL, .get_ant = NULL, .set_level = NULL, .get_level = ft100_get_level, .set_func = NULL, .get_func = NULL, .set_parm = NULL, .get_parm = NULL, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int ft100_init(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); STATE(rig)->priv = (struct ft100_priv_data *) calloc(1, sizeof(struct ft100_priv_data)); if (!STATE(rig)->priv) { return -RIG_ENOMEM; } return RIG_OK; } int ft100_cleanup(RIG *rig) { if (!rig) { return -RIG_EINVAL; } if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft100_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } int ft100_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return RIG_OK; } /* * private helper function to send a private command * sequence . Must only be complete sequences. * */ static int ft100_send_priv_cmd(RIG *rig, unsigned char cmd_index) { rig_debug(RIG_DEBUG_VERBOSE, "%s called (%d)\n", __func__, cmd_index); if (!rig) { return -RIG_EINVAL; } return write_block(RIGPORT(rig), (unsigned char *) &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); } static int ft100_read_status(RIG *rig) { struct ft100_priv_data *priv; hamlib_port_t *rp = RIGPORT(rig); int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct ft100_priv_data *)STATE(rig)->priv; rig_flush(rp); ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_READ_STATUS); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &priv->status, sizeof(FT100_STATUS_INFO)); rig_debug(RIG_DEBUG_VERBOSE, "%s: read status=%i \n", __func__, ret); if (ret < 0) { return ret; } return RIG_OK; } static int ft100_read_flags(RIG *rig) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); rig_flush(rp); ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_READ_FLAGS); if (ret != RIG_OK) { return ret; } ret = read_block(rp, (unsigned char *) &priv->flags, sizeof(FT100_FLAG_INFO)); rig_debug(RIG_DEBUG_VERBOSE, "%s: read flags=%i \n", __func__, ret); if (ret < 0) { return ret; } return RIG_OK; } int ft100_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "ft100: requested freq = %"PRIfreq" Hz \n", freq); cmd_index = FT100_NATIVE_CAT_SET_FREQ; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); /* fixed 10Hz bug by OH2MMY */ freq = (int) freq / 10; to_bcd(p_cmd, freq, 8); /* store bcd format in in p_cmd */ return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } int ft100_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; freq_t d1, d2; char freq_str[10]; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s:\n", __func__); if (!freq) { return -RIG_EINVAL; } ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "%s: Freq= %3i %3i %3i %3i \n", __func__, (int)priv->status.freq[0], (int)priv->status.freq[1], (int)priv->status.freq[2], (int)priv->status.freq[3]); /* now convert it .... */ SNPRINTF(freq_str, sizeof(freq_str), "%02X%02X%02X%02X", priv->status.freq[0], priv->status.freq[1], priv->status.freq[2], priv->status.freq[3]); d1 = strtol(freq_str, NULL, 16); d2 = (d1 * 1.25); /* fixed 10Hz bug by OH2MMY */ rig_debug(RIG_DEBUG_VERBOSE, "ft100: d1=%"PRIfreq" d2=%"PRIfreq"\n", d1, d2); // cppcheck-suppress * rig_debug(RIG_DEBUG_VERBOSE, "ft100: get_freq= %8"PRIll" \n", (int64_t)d2); *freq = d2; return RIG_OK; } int ft100_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd_index; /* index of sequence to send */ int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s, width %d\n", __func__, rig_strrmode(mode), (int)width); switch (mode) { case RIG_MODE_AM: cmd_index = FT100_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: cmd_index = FT100_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_CWR: cmd_index = FT100_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_USB: cmd_index = FT100_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: cmd_index = FT100_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_FM: cmd_index = FT100_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_PKTUSB: cmd_index = FT100_NATIVE_CAT_SET_MODE_DIG; break; case RIG_MODE_WFM: cmd_index = FT100_NATIVE_CAT_SET_MODE_WFM; break; default: return -RIG_EINVAL; } ret = ft100_send_priv_cmd(rig, cmd_index); if (ret != RIG_OK) { return ret; } if (RIG_PASSBAND_NOCHANGE == width) { return ret; } #if 1 if (mode != RIG_MODE_FM && mode != RIG_MODE_WFM && width <= kHz(6)) { unsigned char p_cmd[YAESU_CMD_LENGTH]; p_cmd[0] = 0x00; p_cmd[1] = 0x00; p_cmd[2] = 0x00; p_cmd[3] = 0x00; /* to be filled in */ p_cmd[4] = 0x8C; /* Op: filter selection */ if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if (width <= 300) { p_cmd[3] = 0x03; } else if (width <= 500) { p_cmd[3] = 0x02; } else if (width <= 2400) { p_cmd[3] = 0x00; } else { p_cmd[3] = 0x01; } ret = write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); if (ret != RIG_OK) { return ret; } } #endif return RIG_OK; } /* ft100_get_mode fixed by OH2MMY * Still answers wrong if on AM. Bug in rig's firmware? * The rig answers something weird then, not what the manual says * and the answer is different every time. Other modes do work. */ int ft100_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; if (!mode || !width) { return -RIG_EINVAL; } ret = ft100_read_status(rig); if (ret < 0) { return ret; } switch (priv->status.mode & 0x0f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x05: *mode = RIG_MODE_PKTUSB; break; case 0x06: *mode = RIG_MODE_FM; break; case 0x07: *mode = RIG_MODE_WFM; break; default: *mode = RIG_MODE_NONE; }; switch (priv->status.mode >> 4) { case 0x00: *width = Hz(6000); break; case 0x01: *width = Hz(2400); break; case 0x02: *width = Hz(500); break; case 0x03: *width = Hz(300); break; default: *width = RIG_PASSBAND_NORMAL; }; return RIG_OK; } /* Function ft100_set_vfo fixed by OH2MMY */ int ft100_set_vfo(RIG *rig, vfo_t vfo) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_SET_VFOA); if (ret != RIG_OK) { return ret; } break; case RIG_VFO_B: ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_SET_VFOB); if (ret != RIG_OK) { return ret; } break; default: return -RIG_EINVAL; } return RIG_OK; } /* Function ft100_get_vfo written again by OH2MMY * Tells the right answer if in VFO mode. * TODO: handle memory modes. */ int ft100_get_vfo(RIG *rig, vfo_t *vfo) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } ret = ft100_read_flags(rig); if (ret < 0) { return ret; } if ((priv->flags.byte[1] & 0x04) == 0x04) { *vfo = RIG_VFO_B; } else { *vfo = RIG_VFO_A; } return RIG_OK; } int ft100_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { unsigned char cmd_index; int split = CACHE(rig)->split; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: cmd_index = FT100_NATIVE_CAT_PTT_ON; // This was causing WSJT-X to assume reverse split //if (split) { rig_set_vfo(rig, RIG_VFO_B); } break; case RIG_PTT_OFF: cmd_index = FT100_NATIVE_CAT_PTT_OFF; if (split) { rig_set_vfo(rig, RIG_VFO_A); } hl_usleep(100 * 1000); // give ptt some time to do its thing -- fake it was not resetting freq after tx break; default: return -RIG_EINVAL; } return ft100_send_priv_cmd(rig, cmd_index); } int ft100_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; if (!ptt) { return -RIG_EINVAL; } ret = ft100_read_flags(rig); if (ret < 0) { return ret; } *ptt = (priv->flags.byte[0] & 0x80) == 0x80 ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * Rem: The FT-100(D) has no set_level ability */ int ft100_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret; int split = CACHE(rig)->split; int ptt = CACHE(rig)->ptt; FT100_METER_INFO ft100_meter; if (!rig) { return -RIG_EINVAL; } if (!val) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s: %s\n", __func__, rig_strlevel(level)); // if in split have to switch to VFOB to read power and back to VFOA if (split && ptt) { rig_set_vfo(rig, RIG_VFO_B); } ret = ft100_send_priv_cmd(rig, FT100_NATIVE_CAT_READ_METERS); if (split && ptt) { rig_set_vfo(rig, RIG_VFO_A); } if (ret != RIG_OK) { return ret; } ret = read_block(RIGPORT(rig), (unsigned char *) &ft100_meter, sizeof(FT100_METER_INFO)); rig_debug(RIG_DEBUG_VERBOSE, "%s: read meters=%d\n", __func__, ret); if (ret < 0) { return ret; } switch (level) { case RIG_LEVEL_RAWSTR: val->i = ft100_meter.s_meter; break; case RIG_LEVEL_RFPOWER: val->f = (float)ft100_meter.tx_fwd_power / 0xff; break; case RIG_LEVEL_SWR: if (ft100_meter.tx_fwd_power == 0) { val->f = 0; } else { float f; f = sqrt((float)ft100_meter.tx_rev_power / (float)ft100_meter.tx_fwd_power); val->f = (1 + f) / (1 - f); } break; case RIG_LEVEL_ALC: /* need conversion ? */ val->f = (float)ft100_meter.alc_level / 0xff; break; case RIG_LEVEL_MICGAIN: val->f = (float)ft100_meter.mic_level / 0xff; break; case RIG_LEVEL_SQL: val->f = (float)ft100_meter.squelch_level / 0xff; break; default: return -RIG_EINVAL; } return RIG_OK; } #if 0 /* TODO: all of this */ int ft100_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { return -RIG_ENIMPL; } int ft100_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { return -RIG_ENIMPL; } int ft100_set_parm(RIG *rig, setting_t parm, value_t val) { return -RIG_ENIMPL; } int ft100_get_parm(RIG *rig, setting_t parm, value_t *val) { return -RIG_ENIMPL; } #endif /* kc2ivl */ int ft100_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { unsigned char cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (split) { case RIG_SPLIT_ON: cmd_index = FT100_NATIVE_CAT_SPLIT_ON; break; case RIG_SPLIT_OFF: cmd_index = FT100_NATIVE_CAT_SPLIT_OFF; break; default: return -RIG_EINVAL; } return ft100_send_priv_cmd(rig, cmd_index); } int ft100_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!split) { return -RIG_EINVAL; } ret = ft100_read_flags(rig); if (ret < 0) { return ret; } *split = (priv->flags.byte[0] & 0x01) == 0x01 ? RIG_SPLIT_ON : RIG_SPLIT_OFF; return RIG_OK; } int ft100_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { unsigned char cmd_index; rig_debug(RIG_DEBUG_VERBOSE, "%s:ft100_set_rptr_shift called\n", __func__); rig_debug(RIG_DEBUG_VERBOSE, "%s: + - 0 %3i %3i %3i %3i %c\n", __func__, RIG_RPT_SHIFT_PLUS, RIG_RPT_SHIFT_MINUS, RIG_RPT_SHIFT_NONE, shift, (char)shift); switch (shift) { case RIG_RPT_SHIFT_PLUS: cmd_index = FT100_NATIVE_CAT_SET_RPT_SHIFT_PLUS; break; case RIG_RPT_SHIFT_MINUS: cmd_index = FT100_NATIVE_CAT_SET_RPT_SHIFT_MINUS; break; case RIG_RPT_SHIFT_NONE: cmd_index = FT100_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX; break; default: return -RIG_EINVAL; } return ft100_send_priv_cmd(rig, cmd_index); } int ft100_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift) { int ret; struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } *shift = RIG_RPT_SHIFT_NONE; if (priv->status.flag1 & (1 << 2)) { *shift = RIG_RPT_SHIFT_MINUS; } else if (priv->status.flag1 & (1 << 3)) { *shift = RIG_RPT_SHIFT_PLUS; } rig_debug(RIG_DEBUG_VERBOSE, "%s: flag1=0x%02x\n", __func__, priv->status.flag1); return RIG_OK; } /* * TODO: enable/disable encoding/decoding */ int ft100_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ int pcode; for (pcode = 0; pcode < 104 && ft100_dcs_list[pcode] != 0; pcode++) { if (ft100_dcs_list[pcode] == code) { break; } } /* there are 104 dcs codes available */ if (pcode >= 104 || ft100_dcs_list[pcode] == 0) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s = %03i, n=%d\n", __func__, code, pcode); cmd_index = FT100_NATIVE_CAT_SET_DCS_CODE; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); p_cmd[3] = (char)pcode; return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } int ft100_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int ret; struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } *code = ft100_dcs_list[priv->status.dcs]; rig_debug(RIG_DEBUG_VERBOSE, "%s: P1=0x%02x, code=%d\n", __func__, priv->status.dcs, *code); return RIG_OK; } /* * TODO: enable/disable encoding/decoding */ int ft100_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char p_cmd[YAESU_CMD_LENGTH]; unsigned char cmd_index; /* index of sequence to send */ int ptone; for (ptone = 0; ptone < 39 && ft100_ctcss_list[ptone] != 0; ptone++) { if (ft100_ctcss_list[ptone] == tone) { break; } } /* there are 39 ctcss tones available */ if (ptone >= 39 || ft100_ctcss_list[ptone] == 0) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_VERBOSE, "%s = %.1f Hz, n=%d\n", __func__, (float)tone / 10, ptone); cmd_index = FT100_NATIVE_CAT_SET_CTCSS_FREQ; memcpy(p_cmd, &ncmd[cmd_index].nseq, YAESU_CMD_LENGTH); p_cmd[3] = (char)ptone; return write_block(RIGPORT(rig), p_cmd, YAESU_CMD_LENGTH); } int ft100_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int ret; struct ft100_priv_data *priv = (struct ft100_priv_data *)STATE(rig)->priv; ret = ft100_read_status(rig); if (ret != RIG_OK) { return ret; } *tone = ft100_ctcss_list[priv->status.ctcss]; rig_debug(RIG_DEBUG_VERBOSE, "%s: P1=0x%02x, tone=%.1f\n", __func__, priv->status.ctcss, *tone / 10.0); return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft847.h0000644000175000017500000000263314752216205013027 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft847.h - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * This shared library provides an API for communicating * via serial interface to an FT-847 using the "CAT" interface. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT847_H #define _FT847_H 1 #define FT847_WRITE_DELAY 50 /* Sequential fast writes may confuse FT847 without this delay */ #define FT847_POST_WRITE_DELAY 50 /* Rough safe value for default timeout */ #define FT847_DEFAULT_READ_TIMEOUT 2000 #endif /* _FT847_H */ hamlib-4.6.2/rigs/yaesu/ft757gx.c0000644000175000017500000006112714752216205013364 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) * * ft757gx.c - (C) Stephane Fillod 2004 * (C) Nate Bargmann 2008 * * This shared library provides an API for communicating * via serial interface to an FT-757GX/FT-757GXII using the * "CAT" interface box (FIF-232C) or similar. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * TODO * * 1. Allow cached reads * 2. set_mem/get_mem, vfo_op, get_channel, set_split/get_split, * set_func/get_func * */ #include #include /* String function definitions */ #include #include "serial.h" #include "misc.h" #include "yaesu.h" #include "ft757gx.h" #define FT757GX_VFOS (RIG_VFO_A|RIG_VFO_B) /* Backend function prototypes. These map to frontend functions. */ static int ft757_init(RIG *rig); static int ft757_cleanup(RIG *rig); static int ft757_open(RIG *rig); static int ft757gx_get_conf(RIG *rig, hamlib_token_t token, char *val); static int ft757gx_set_conf(RIG *rig, hamlib_token_t token, const char *val); static int ft757_set_freq(RIG *rig, vfo_t vfo, freq_t freq); //static int ft757_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft757gx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft757_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); /* select mode */ static int ft757_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); /* get mode */ static int ft757_set_vfo(RIG *rig, vfo_t vfo); /* select vfo */ static int ft757_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft757gx_get_vfo(RIG *rig, vfo_t *vfo); /* get vfo */ static int ft757_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft757_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* Private helper function prototypes */ static int ft757_get_update_data(RIG *rig); static int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width); static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width); /* * future - private data * */ struct ft757_priv_data { unsigned char pacing; /* pacing value */ unsigned char current_vfo; /* active VFO from last cmd , can be either RIG_VFO_A or RIG_VFO_B only */ unsigned char update_data[FT757GX_STATUS_UPDATE_DATA_LENGTH]; /* returned data */ double curfreq; /* for fake get_freq on 757G */ char fakefreq; /* 0=no fake, 1=fake get freq */ }; #define TOKEN_BACKEND(t) (t) #define TOK_FAKEFREQ TOKEN_BACKEND(1) const struct confparams ft757gx_cfg_params[] = { { TOK_FAKEFREQ, "fakefreq", "Fake get-freq", "Fake getting freq", "0", RIG_CONF_CHECKBUTTON }, { RIG_CONF_END, NULL, } }; /* * ft757gx rig capabilities. * Also this struct is READONLY! */ struct rig_caps ft757gx_caps = { RIG_MODEL(RIG_MODEL_FT757), .model_name = "FT-757GX", .mfg_name = "Yaesu", .version = "20220429.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT757GX_WRITE_DELAY, .post_write_delay = FT757GX_POST_WRITE_DELAY, .timeout = FT757GX_DEFAULT_READ_TIMEOUT, .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, /* FIXME: memory channel list:20 */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(500), .endf = 29999990, .modes = FT757GX_ALL_RX_MODES, .low_power = -1, .high_power = -1 }, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1500), 1999900, FT757GX_ALL_TX_MODES, .low_power = 5000, .high_power = 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(3500), 3999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(7000), 7499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(10), 10499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(14), 14499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(18), 18499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(21), 21499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(24500), 24999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(28), 29999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {FT757GX_ALL_RX_MODES, 10}, {FT757GX_ALL_RX_MODES, 100}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = NULL, /* private data */ .rig_init = ft757_init, .rig_cleanup = ft757_cleanup, .rig_open = ft757_open, /* port opened */ .rig_close = NULL, /* port closed */ .set_freq = ft757_set_freq, /* set freq */ .get_freq = ft757gx_get_freq, /* get freq */ .set_mode = NULL, /* set mode */ .get_mode = NULL, /* get mode */ .get_vfo = ft757gx_get_vfo, /* set vfo */ .set_vfo = ft757_set_vfo, /* set vfo */ .set_ptt = NULL, /* set ptt */ .get_ptt = NULL, /* get ptt */ .cfgparams = ft757gx_cfg_params, .set_conf = ft757gx_set_conf, .get_conf = ft757gx_get_conf, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ft757gx2 rig capabilities. * Also this struct is READONLY! */ struct rig_caps ft757gx2_caps = { RIG_MODEL(RIG_MODEL_FT757GXII), .model_name = "FT-757GXII", .mfg_name = "Yaesu", .version = "20240927.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_SERIAL_DTR, /* CAT port pin 4 per manual */ .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT757GX_WRITE_DELAY, .post_write_delay = FT757GX_POST_WRITE_DELAY, .timeout = FT757GX_DEFAULT_READ_TIMEOUT, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_RAWSTR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .vfo_ops = RIG_OP_CPY | RIG_OP_FROM_VFO | RIG_OP_TO_VFO | RIG_OP_UP | RIG_OP_DOWN, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 9, RIG_MTYPE_MEM, FT757_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { { .startf = kHz(150), .endf = 29999990, .modes = FT757GX_ALL_RX_MODES, .low_power = -1, .high_power = -1 }, RIG_FRNG_END, }, /* rx range */ /* FIXME: 10m is "less" and AM is 25W carrier */ .tx_range_list2 = { {kHz(1500), 1999900, FT757GX_ALL_TX_MODES, .low_power = 5000, .high_power = 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(3500), 3999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(7000), 7499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(10), 10499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(14), 14499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(18), 18499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(21), 21499900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = kHz(24500), 24999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, {.startf = MHz(28), 29999900, FT757GX_ALL_TX_MODES, 5000, 100000, FT757GX_VFOS, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {FT757GX_ALL_RX_MODES, 10}, RIG_TS_END, }, /* mode/filter list, .remember = order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.7)}, {RIG_MODE_CW, Hz(600)}, /* narrow */ {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT757GXII_STR_CAL, .priv = NULL, /* private data */ .rig_init = ft757_init, .rig_cleanup = ft757_cleanup, .rig_open = ft757_open, /* port opened */ .rig_close = NULL, /* port closed */ .set_freq = ft757_set_freq, /* set freq */ .get_freq = ft757gx_get_freq, /* get freq */ .set_mode = ft757_set_mode, /* set mode */ .get_mode = ft757_get_mode, /* get mode */ .set_vfo = ft757_set_vfo, /* set vfo */ .get_vfo = ft757_get_vfo, /* get vfo */ .get_level = ft757_get_level, .get_ptt = ft757_get_ptt, /* get ptt */ .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * _init * */ static int ft757_init(RIG *rig) { struct ft757_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } STATE(rig)->priv = (struct ft757_priv_data *) calloc(1, sizeof(struct ft757_priv_data)); if (!STATE(rig)->priv) /* whoops! memory shortage! */ { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->curfreq = 1e6; /* TODO: read pacing from preferences */ priv->pacing = FT757GX_PACING_DEFAULT_VALUE; /* set pacing to minimum for now */ priv->current_vfo = RIG_VFO_A; /* default to VFO_A ? */ return RIG_OK; } /* * ft757_cleanup routine * the serial port is closed by the frontend */ static int ft757_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (STATE(rig)->priv) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } /* * ft757_open routine * */ static int ft757_open(RIG *rig) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); priv->fakefreq = 1; // turn this on by default /* FT757GX has a write-only serial port: don't try to read status data */ if (rig->caps->rig_model == RIG_MODEL_FT757) { int retval; memset(priv->update_data, 0, FT757GX_STATUS_UPDATE_DATA_LENGTH); retval = rig_set_vfo(rig, RIG_VFO_A); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: rig_set_vfo error: %s\n", __func__, rigerror(retval)); } } else { /* read back the 75 status bytes from FT757GXII */ int retval = ft757_get_update_data(rig); if (retval < 0) { memset(priv->update_data, 0, FT757GX_STATUS_UPDATE_DATA_LENGTH); return retval; } } return RIG_OK; } /* * This command only functions when operating on a vfo. * TODO: test Status Update Byte 1 * */ static int ft757_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0a}; rig_debug(RIG_DEBUG_VERBOSE, "%s called. Freq=%"PRIfreq"\n", __func__, freq); /* fill in first four bytes */ to_bcd(cmd, freq / 10, BCD_LEN); priv->curfreq = freq; return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } static int ft757_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x0c}; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } rig_debug(RIG_DEBUG_TRACE, "%s: mode = %s, width = %d\n", __func__, rig_strrmode(mode), (int)width); if (mode == RIG_MODE_NONE) { return -RIG_EINVAL; } /* fill in p1 */ cmd[3] = mode2rig(rig, mode, width); return write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); } static int ft757gx_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called. fakefreq=%d\n", __func__, priv->fakefreq); if (priv->fakefreq) // only return last freq set when fakeit is turned on { *freq = priv->curfreq; return RIG_OK; } return RIG_ENAVAIL; } /* * Return Freq */ #if 0 static int ft757_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } /* grab freq (little endian format) and convert */ switch (vfo) { case RIG_VFO_CURR: *freq = 10 * from_bcd(priv->update_data + STATUS_CURR_FREQ, BCD_LEN); break; case RIG_VFO_A: *freq = 10 * from_bcd(priv->update_data + STATUS_VFOA_FREQ, BCD_LEN); break; case RIG_VFO_B: *freq = 10 * from_bcd(priv->update_data + STATUS_VFOB_FREQ, BCD_LEN); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } rig_debug(RIG_DEBUG_VERBOSE, "%s returning: Freq=%"PRIfreq"\n", __func__, *freq); return RIG_OK; } #endif static int ft757_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } switch (vfo) { case RIG_VFO_CURR: retval = rig2mode(rig, priv->update_data[STATUS_CURR_MODE], mode, width); break; case RIG_VFO_A: retval = rig2mode(rig, priv->update_data[STATUS_VFOA_MODE], mode, width); break; case RIG_VFO_B: retval = rig2mode(rig, priv->update_data[STATUS_VFOB_MODE], mode, width); break; default: return -RIG_EINVAL; /* sorry, wrong VFO */ } return retval; } /* * set vfo and store requested vfo for later RIG_VFO_CURR * requests. * */ static int ft757_set_vfo(RIG *rig, vfo_t vfo) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x05}; struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; ENTERFUNC; switch (vfo) { case RIG_VFO_CURR: RETURNFUNC(RIG_OK); case RIG_VFO_A: cmd[3] = 0x00; /* VFO A */ break; case RIG_VFO_B: cmd[3] = 0x01; /* VFO B */ break; default: RETURNFUNC(-RIG_EINVAL); /* sorry, wrong VFO */ } priv->current_vfo = vfo; RETURNFUNC(write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH)); } static int ft757gx_get_vfo(RIG *rig, vfo_t *vfo) { const struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; // we'll just use the cached vfo for the 757GX since we can't read it *vfo = priv->current_vfo; return RIG_OK; } static int ft757_get_vfo(RIG *rig, vfo_t *vfo) { const struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } if (priv->update_data[0] & 0x10) { (*vfo) = RIG_VFO_MEM; } else if (priv->update_data[0] & 0x08) { (*vfo) = RIG_VFO_B; } else { (*vfo) = RIG_VFO_A; } return RIG_OK; } static int ft757_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); retval = ft757_get_update_data(rig); /* get whole shebang from rig */ if (retval < 0) { return retval; } *ptt = (priv->update_data[0] & 0x20) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } static int ft757_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x01, 0x10}; int retval; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } if (level != RIG_LEVEL_RAWSTR) { return -RIG_EINVAL; } rig_flush(rp); /* send READ STATUS(Meter only) cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 1 byte */ retval = read_block(rp, cmd, 1); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: read meter failed %d.\n", __func__, retval); return retval < 0 ? retval : -RIG_EIO; } val->i = cmd[0]; return RIG_OK; } /* * private helper function. Retrieves update data from rig. * using pacing value and buffer indicated in *priv struct. * * need to use this when doing ft757_get_* stuff */ static int ft757_get_update_data(RIG *rig) { const unsigned char cmd[YAESU_CMD_LENGTH] = { 0x00, 0x00, 0x00, 0x00, 0x10}; struct ft757_priv_data *priv = (struct ft757_priv_data *)STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); int retval = 0; long nbtries; /* Maximum number of attempts to ask/read the data. */ int maxtries = rp->retry ; rig_debug(RIG_DEBUG_VERBOSE, "%s called Timeout=%d ms, Retry=%d\n", __func__, rp->timeout, maxtries); /* At least on one model, returns erraticaly a timeout. Increasing the timeout does not fix things. So we restart the read from scratch, it works most of times. */ for (nbtries = 0 ; nbtries < maxtries ; nbtries++) { rig_flush(rp); /* send READ STATUS cmd to rig */ retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval < 0) { return retval; } /* read back the 75 status bytes */ retval = read_block(rp, priv->update_data, FT757GX_STATUS_UPDATE_DATA_LENGTH); if (retval == FT757GX_STATUS_UPDATE_DATA_LENGTH) { break ; } rig_debug(RIG_DEBUG_ERR, "%s: read update_data failed, %d octets of %d read, retry %ld out of %d\n", __func__, retval, FT757GX_STATUS_UPDATE_DATA_LENGTH, nbtries, maxtries); /* The delay is quadratic. */ hl_usleep(nbtries * nbtries * 1000000); } if (retval != FT757GX_STATUS_UPDATE_DATA_LENGTH) { rig_debug(RIG_DEBUG_ERR, "%s: read update_data failed, %d octets of %d read.\n", __func__, retval, FT757GX_STATUS_UPDATE_DATA_LENGTH); return retval < 0 ? retval : -RIG_EIO; } return RIG_OK; } static int mode2rig(RIG *rig, rmode_t mode, pbwidth_t width) { int md; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } /* * translate mode from generic to ft757 specific */ switch (mode) { case RIG_MODE_AM: md = MODE_AM; break; case RIG_MODE_USB: md = MODE_USB; break; case RIG_MODE_LSB: md = MODE_LSB; break; case RIG_MODE_FM: md = MODE_FM; break; case RIG_MODE_CW: if (RIG_PASSBAND_NOCHANGE == width || width == RIG_PASSBAND_NORMAL || width >= rig_passband_normal(rig, mode)) { md = MODE_CWW; } else { md = MODE_CWN; } break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } return md; } static int rig2mode(RIG *rig, int md, rmode_t *mode, pbwidth_t *width) { rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); if (!rig) { return -RIG_EINVAL; } /* * translate mode from ft757 specific to generic */ switch (md) { case MODE_AM: *mode = RIG_MODE_AM; break; case MODE_USB: *mode = RIG_MODE_USB; break; case MODE_LSB: *mode = RIG_MODE_LSB; break; case MODE_FM: *mode = RIG_MODE_FM; break; case MODE_CWW: case MODE_CWN: *mode = RIG_MODE_CW; break; default: return -RIG_EINVAL; /* sorry, wrong MODE */ } if (md == MODE_CWN) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ft757gx_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len) { struct ft757_priv_data *priv; struct rig_state *rs; rig_debug(RIG_DEBUG_VERBOSE, "%s called.\n", __func__); rs = STATE(rig); priv = (struct ft757_priv_data *)rs->priv; switch (token) { case TOK_FAKEFREQ: SNPRINTF(val, val_len, "%d", priv->fakefreq); break; default: *val = 0; return -RIG_EINVAL; } return RIG_OK; } static int ft757gx_get_conf(RIG *rig, hamlib_token_t token, char *val) { return ft757gx_get_conf2(rig, token, val, 128); } /* * Assumes rig!=NULL, STATE(rig)->priv!=NULL */ static int ft757gx_set_conf(RIG *rig, hamlib_token_t token, const char *val) { struct ft757_priv_data *priv; struct rig_state *rs; rig_debug(RIG_DEBUG_VERBOSE, "%s called. val=%s\n", __func__, val); rs = STATE(rig); priv = (struct ft757_priv_data *)rs->priv; switch (token) { case TOK_FAKEFREQ: priv->fakefreq = 0; // should only be 0 or 1 -- default to 0 if (val[0] != '0') { priv->fakefreq = 1; } rig_debug(RIG_DEBUG_VERBOSE, "%s: fakefreq=%d\n", __func__, priv->fakefreq); break; default: return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.2/rigs/yaesu/ft600.h0000644000175000017500000000263414752216205013013 00000000000000/* * hamlib - (C) Frank Singleton 2000-2003 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft600.h -(C) KÄrlis Millers YL3ALK 2019 * * This shared library provides an API for communicating * via serial interface to an FT-600 using the "CAT" interface. * The starting point for this code was Chris Karpinsky's ft100 implementation. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT600_H #define _FT600_H 1 #define FT600_STATUS_UPDATE_DATA_LENGTH 19 #define FT600_METER_INFO_LENGTH 5 #define FT600_WRITE_DELAY 5 #define FT600_POST_WRITE_DELAY 200 #define FT600_DEFAULT_READ_TIMEOUT 2000 #endif /* _FT600_H */ hamlib-4.6.2/rigs/yaesu/vx1700.c0000644000175000017500000011431714752216205013116 00000000000000/* * Copyright (c) 2010-2011 by Mikhail Kshevetskiy (mikhail.kshevetskiy@gmail.com) * * Code based on VX-1700 CAT manual: * http://www.vertexstandard.com/downloadFile.cfm?FileID=3397&FileCatID=135&FileName=VX-1700_CAT_MANUAL_10_14_2008.pdf&FileContentType=application%2Fpdf * * WARNING: this manual has two errors * 1) Status Update Command (10h), U=01 returns 0..199 for channels 1..200 * 2) Frequency Data (bytes 1--4 of 9-Byte VFO Data Assignment, Status Update * Command (10h), U=02 and U=03) uses bytes 1--3 for frequency, byte 4 is * not used and always zero. Thus bytes 0x15,0xBE,0x68,0x00 means * frequency = 10 * 0x15BE68 = 10 * 1425000 = 14.25 MHz * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "yaesu.h" #include "vx1700.h" // VX-1700 native commands typedef enum vx1700_native_cmd_e { VX1700_NATIVE_RECALL_MEM = 0, /* 0x02, p1=ch */ VX1700_NATIVE_VFO_TO_MEM, /* 0x03, p1=ch, p2=0 */ VX1700_NATIVE_MEM_HIDE, /* 0x03, p1=ch, p2=1 */ VX1700_NATIVE_VFO_A, /* 0x05 */ VX1700_NATIVE_FREQ_SET, /* 0x0a, p1:4=freq */ VX1700_NATIVE_MODE_SET_LSB, /* 0x0c, p1=0x00 */ VX1700_NATIVE_MODE_SET_USB, /* 0x0c, p1=0x01 */ VX1700_NATIVE_MODE_SET_CW_W, /* 0x0c, p1=0x02 */ VX1700_NATIVE_MODE_SET_CW_N, /* 0x0c, p1=0x03 */ VX1700_NATIVE_MODE_SET_AM, /* 0x0c, p1=0x04 */ VX1700_NATIVE_MODE_SET_RTTY_LSB_W, /* 0x0c, p1=0x08 */ VX1700_NATIVE_MODE_SET_RTTY_USB_W, /* 0x0c, p1=0x09 */ VX1700_NATIVE_MODE_SET_H3E, /* 0x0c, p1=0x0d */ VX1700_NATIVE_MODE_SET_RTTY_LSB_N, /* 0x0c, p1=0x0e */ VX1700_NATIVE_MODE_SET_RTTY_USB_N, /* 0x0c, p1=0x0f */ VX1700_NATIVE_PTT_OFF, /* 0x0f, p1=0 */ VX1700_NATIVE_PTT_ON, /* 0x0f, p1=1 */ VX1700_NATIVE_UPDATE_MEM_CHNL, /* 0x10, p1=1 */ VX1700_NATIVE_UPDATE_OP_DATA, /* 0x10, p1=2 */ VX1700_NATIVE_UPDATE_VFO_DATA, /* 0x10, p1=3 */ VX1700_NATIVE_TX_POWER_LOW, /* 0x18 */ VX1700_NATIVE_TX_POWER_MID, /* 0x28 */ VX1700_NATIVE_TX_POWER_HI, /* 0x48 */ VX1700_NATIVE_CPY_RX_TO_TX, /* 0x85 */ VX1700_NATIVE_TX_FREQ_SET, /* 0x8a, p1:4=freq */ VX1700_NATIVE_OP_FREQ_STEP_UP, /* 0x8e, p1=0 */ VX1700_NATIVE_OP_FREQ_STEP_DOWN, /* 0x8e, p1=1 */ VX1700_NATIVE_READ_METER, /* 0xf7 */ VX1700_NATIVE_READ_FLAGS, /* 0xfa */ VX1700_NATIVE_SIZE } vx1700_native_cmd_t; // OpCode Declarations #define VX1700_CMD_RECALLMEM 0x02 #define VX1700_CMD_VFO2MEM 0x03 #define VX1700_CMD_SEL_VFOA 0x05 #define VX1700_CMD_SET_VFOA 0x0a #define VX1700_CMD_SEL_OP_MODE 0x0c #define VX1700_CMD_PTT 0x0f #define VX1700_CMD_UPDATE 0x10 #define VX1700_CMD_RX2TX 0x85 #define VX1700_CMD_STEP_VFO 0x8e #define VX1700_CMD_RD_METER 0xf7 #define VX1700_CMD_RD_FLAGS 0xfa // Return codes #define VX1700_CMD_RETCODE_OK 0x00 #define VX1700_CMD_RETCODE_ERROR 0xF0 // Operating Mode Status #define VX1700_MODE_LSB 0x00 #define VX1700_MODE_USB 0x01 #define VX1700_MODE_CW_W 0x02 #define VX1700_MODE_CW_N 0x03 #define VX1700_MODE_AM 0x04 #define VX1700_MODE_RTTY 0x05 // Operation Mode Selection #define VX1700_OP_MODE_LSB 0x00 #define VX1700_OP_MODE_USB 0x01 #define VX1700_OP_MODE_CW_W 0x02 #define VX1700_OP_MODE_CW_N 0x03 #define VX1700_OP_MODE_AM 0x04 #define VX1700_OP_MODE_RTTY_LSB_W 0x08 #define VX1700_OP_MODE_RTTY_USB_W 0x09 #define VX1700_OP_MODE_H3E 0x0d #define VX1700_OP_MODE_RTTY_LSB_N 0x0e #define VX1700_OP_MODE_RTTY_USB_N 0x0f // Status Flag 1 Masks #define VX1700_SF_LOCKED 0x01 /* LOCK is activated */ #define VX1700_SF_MEM 0x20 /* Memory Mode */ #define VX1700_SF_VFO 0x80 /* VFO Mode */ // Status Flag 2 Masks #define VX1700_SF_PTT_BY_CAT 0x01 /* PTT closed by CAT */ #define VX1700_SF_MEM_SCAN_PAUSE 0x02 /* Scanning paused */ #define VX1700_SF_MEM_SCAN 0x04 /* Scanning enabled */ #define VX1700_SF_RTTY_FILTER_NARROW 0x08 /* Narrow RTTY filter selected */ #define VX1700_SF_CW_FILTER_NARROW 0x10 /* Narrow CW filter selected */ #define VX1700_SF_RTTY_USB 0x20 /* USB selected for RTTY */ // Status Flag 3 Masks #define VX1700_SF_10W_TX 0x20 /* 10 Watt TX output selected */ #define VX1700_SF_TUNER_ON 0x20 /* Antenna Tuner working */ #define VX1700_SF_TRANSMISSION_ON 0x80 /* Transmission in progress */ /* HAMLIB API implementation */ static int vx1700_init(RIG *rig); static int vx1700_open(RIG *rig); static int vx1700_cleanup(RIG *rig); static const char *vx1700_get_info(RIG *rig); static int vx1700_set_vfo(RIG *rig, vfo_t vfo); static int vx1700_get_vfo(RIG *rig, vfo_t *vfo); static int vx1700_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int vx1700_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int vx1700_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); static int vx1700_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); static int vx1700_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int vx1700_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int vx1700_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int vx1700_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int vx1700_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int vx1700_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int vx1700_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int vx1700_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int vx1700_set_mem(RIG *rig, vfo_t vfo, int ch); static int vx1700_get_mem(RIG *rig, vfo_t vfo, int *ch); static int vx1700_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static const yaesu_cmd_set_t ncmd[] = { { 0, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* Recall Memory */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* VFO to MEM */ { 0, { 0x00, 0x00, 0x01, 0x00, 0x03 } }, /* Hide Memory Channel */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* Select VFO (A) */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0a } }, /* Set Op Freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* OP Mode Set LSB */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0c } }, /* OP Mode Set USB */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x0c } }, /* OP Mode Set CW-W */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x0c } }, /* OP Mode Set CW-N */ { 1, { 0x00, 0x00, 0x00, 0x04, 0x0c } }, /* OP Mode Set AM */ { 1, { 0x00, 0x00, 0x00, 0x08, 0x0c } }, /* OP Mode Set RTTY LSB-W */ { 1, { 0x00, 0x00, 0x00, 0x09, 0x0c } }, /* OP Mode Set RTTY USB-W */ { 1, { 0x00, 0x00, 0x00, 0x0d, 0x0c } }, /* OP Mode Set H3E */ { 1, { 0x00, 0x00, 0x00, 0x0e, 0x0c } }, /* OP Mode Set RTTY LSB-N */ { 1, { 0x00, 0x00, 0x00, 0x0f, 0x0c } }, /* OP Mode Set RTTY USB-N */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* PTT (OFF) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x0f } }, /* PTT (ON) */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x10 } }, /* Update Memory Ch Number */ { 1, { 0x00, 0x00, 0x00, 0x02, 0x10 } }, /* Update Op Data */ { 1, { 0x00, 0x00, 0x00, 0x03, 0x10 } }, /* Update VFO Data */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x18 } }, /* Set TX power low */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x28 } }, /* Set TX power mid */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x48 } }, /* Set TX power hi */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* Copy RX to TX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x8a } }, /* Set TX Freq only */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8e } }, /* Step Operating Frequency Up */ { 1, { 0x00, 0x00, 0x00, 0x01, 0x8e } }, /* Step Operating Frequency Down */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* Read Meter */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xfa } }, /* Read Status Flags */ }; /* * Private data */ struct vx1700_priv_data { unsigned char ch; /* memory channel */ }; /* * vx1700 rigs capabilities. */ #define VX1700_MEM_CAP { \ .freq = 1, \ .tx_freq = 1, \ .mode = 1, \ .width = 1, \ } struct rig_caps vx1700_caps = { RIG_MODEL(RIG_MODEL_VX1700), .model_name = "VX-1700", .mfg_name = "Vertex Standard", .version = "20210221.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_NONE, /* we have DCD pin in DATA Jack, but get_dcd() is unavailable (yet?) */ .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 600, .retry = 3, .has_get_func = (RIG_FUNC_LOCK | RIG_FUNC_TUNER), .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_BAND_SELECT, .has_set_level = RIG_LEVEL_RFPOWER, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RFPOWER] = { .min = { .i = 0 }, .max = { .i = 2 } }, }, .parm_gran = {}, .preamp = { RIG_DBLST_END }, .attenuator = { RIG_DBLST_END }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = VX1700_VFO_OPS, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { VX1700_MIN_CHANNEL, VX1700_MAX_CHANNEL, RIG_MTYPE_MEM, VX1700_MEM_CAP }, RIG_CHAN_END }, .rx_range_list1 = { { kHz(30), MHz(30), VX1700_MODES, -1, -1, VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .tx_range_list1 = { { kHz(1600), MHz(4) - 1, VX1700_MODES, W(31), W(125), VX1700_VFO_ALL, VX1700_ANTS }, { kHz(4000), MHz(30), VX1700_MODES, W(25), W(100), VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .rx_range_list2 = { { kHz(30), MHz(30), VX1700_MODES, -1, -1, VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .tx_range_list2 = { { kHz(1600), MHz(4) - 1, VX1700_MODES, W(31), W(125), VX1700_VFO_ALL, VX1700_ANTS }, { kHz(4000), MHz(30), VX1700_MODES, W(25), W(100), VX1700_VFO_ALL, VX1700_ANTS }, RIG_FRNG_END, }, .tuning_steps = { { VX1700_MODES, 100 }, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { { RIG_MODE_AM, VX1700_FILTER_WIDTH_AM }, { RIG_MODE_SSB, VX1700_FILTER_WIDTH_SSB }, { RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_RTTYR, VX1700_FILTER_WIDTH_WIDE }, { RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_RTTYR, VX1700_FILTER_WIDTH_NARROW }, RIG_FLT_END, }, .priv = NULL, .rig_init = vx1700_init, .rig_open = vx1700_open, .rig_cleanup = vx1700_cleanup, .set_vfo = vx1700_set_vfo, .get_vfo = vx1700_get_vfo, .set_freq = vx1700_set_freq, .get_freq = vx1700_get_freq, .set_split_freq = vx1700_set_split_freq, .get_split_freq = vx1700_get_split_freq, .set_mode = vx1700_set_mode, .get_mode = vx1700_get_mode, .get_ptt = vx1700_get_ptt, .set_ptt = vx1700_set_ptt, .get_info = vx1700_get_info, .set_func = vx1700_set_func, .get_func = vx1700_get_func, .set_level = vx1700_set_level, .get_level = vx1700_get_level, .set_mem = vx1700_set_mem, .get_mem = vx1700_get_mem, .vfo_op = vx1700_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; static inline freq_t vx1700_read_freq_from_buf(const unsigned char p[]) { /* WARNING: documentation bug, actually frequency stored in bytes 0..2 only, byte 3 is not used and contain zero */ return ((((((unsigned)p[0]) << 8) + p[1]) << 8) + p[2]) * 10.0; } static inline int vx1700_channel_is_ok(unsigned char channel) { return ((channel >= VX1700_MIN_CHANNEL) && (channel <= VX1700_MAX_CHANNEL)) ? 1 : 0; } /* * Function definitions below */ static int vx1700_do_transaction(RIG *rig, const unsigned char cmd[YAESU_CMD_LENGTH], unsigned char *retbuf, size_t retbuf_len) { hamlib_port_t *rp = RIGPORT(rig); unsigned char default_retbuf[1]; int retval; if (retbuf == NULL) { retbuf = default_retbuf; retbuf_len = sizeof(default_retbuf); } memset(retbuf, 0, retbuf_len); rig_flush(rp); retval = write_block(rp, cmd, YAESU_CMD_LENGTH); if (retval != RIG_OK) { return retval; } retval = read_block(rp, retbuf, retbuf_len); if (retval != retbuf_len) { if ((retval == 1) && (retbuf[0] == VX1700_CMD_RETCODE_ERROR)) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retval == 1) { if ((cmd[4] == VX1700_CMD_UPDATE) && (cmd[3] == 0x01)) { /* read memory channel number */ if (vx1700_channel_is_ok(retbuf[0] + 1)) { /* WARNING: Documentation bug, actually we got 0--199 for channels 1--200 */ return RIG_OK; } if (retbuf[0] == VX1700_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } if (retbuf[0] == VX1700_CMD_RETCODE_OK) { return RIG_OK; } if (retbuf[0] == VX1700_CMD_RETCODE_ERROR) { return -RIG_ERJCTED; } return -RIG_EIO; } return RIG_OK; } /* * Private helper function to send a complete command sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the ncmd table * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int vx1700_do_static_cmd(RIG *rig, unsigned char ci) { if (rig == NULL) { return -RIG_EINVAL; } if (! ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to send incomplete sequence\n", __func__); return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[ci].nseq, NULL, 0); } /* * Private helper function to build and then send a complete command * sequence. * * TODO: place variant of this in yaesu.c * * Arguments: *rig Valid RIG instance * ci Command index of the cmd struct * p1-p4 Command parameters * * Returns: RIG_OK if all called functions are successful, * otherwise returns error from called function */ static int vx1700_do_dynamic_cmd(RIG *rig, unsigned char ci, unsigned char p1, unsigned char p2, unsigned char p3, unsigned char p4) { unsigned char cmd[YAESU_CMD_LENGTH]; if (rig == NULL) { return -RIG_EINVAL; } if (ncmd[ci].ncomp) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to modify complete sequence\n", __func__); return -RIG_EINVAL; } memcpy(&cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); cmd[3] = p1; cmd[2] = p2; cmd[1] = p3; cmd[0] = p4; return vx1700_do_transaction(rig, cmd, NULL, 0); } static int vx1700_do_freq_cmd(RIG *rig, unsigned char ci, freq_t freq) { unsigned char cmd[YAESU_CMD_LENGTH]; if (rig == NULL) { return -RIG_EINVAL; } if ((ci != VX1700_NATIVE_FREQ_SET) && (ci != VX1700_NATIVE_TX_FREQ_SET)) { rig_debug(RIG_DEBUG_TRACE, "%s: Attempt to use non frequency sequence\n", __func__); return -RIG_EINVAL; } memcpy(&cmd, &ncmd[ci].nseq, YAESU_CMD_LENGTH); to_bcd(cmd, freq / 10, VX1700_BCD_DIAL); return vx1700_do_transaction(rig, cmd, NULL, 0); } static inline int vx1700_read_mem_channel_number(RIG *rig, unsigned char *channel) { int ret; unsigned char reply[VX1700_MEM_CHNL_LENGTH]; ret = vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_MEM_CHNL].nseq, reply, VX1700_MEM_CHNL_LENGTH); if (ret == -RIG_ERJCTED) { /* we are on VFO mode, so memory channel is not available at the moment */ *channel = VX1700_MIN_CHANNEL - 1; return RIG_OK; } if (ret != RIG_OK) { return ret; } /* WARNING: Documentation bug, actually we got 0--199 for channels 1--200 */ *channel = VX1700_MIN_CHANNEL + reply[0]; return RIG_OK; } static inline int vx1700_read_status_flags(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_READ_FLAGS].nseq, reply, VX1700_STATUS_FLAGS_LENGTH); } static inline int vx1700_read_meter(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_READ_METER].nseq, reply, VX1700_READ_METER_LENGTH); } static inline int vx1700_read_vfo_data_raw(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_VFO_DATA].nseq, reply, VX1700_VFO_DATA_LENGTH); } static inline int vx1700_read_op_data_raw(RIG *rig, unsigned char reply[]) { if (rig == NULL) { return -RIG_EINVAL; } return vx1700_do_transaction(rig, ncmd[VX1700_NATIVE_UPDATE_OP_DATA].nseq, reply, VX1700_OP_DATA_LENGTH); } #if 0 /* unused; re-enabled as needed. */ static int vx1700_read_vfo_data(RIG *rig, unsigned char *hwmode, freq_t *rx_freq, freq_t *tx_freq) { int ret; unsigned char reply[VX1700_VFO_DATA_LENGTH]; if ((ret = vx1700_read_vfo_data_raw(rig, reply)) != RIG_OK) { return ret; } if (hwmode != NULL) { *hwmode = reply[6]; } if (rx_freq != NULL) { *rx_freq = vx1700_read_freq_from_buf(reply + 1); } if (tx_freq != NULL) { *tx_freq = vx1700_read_freq_from_buf(reply + 10); } return RIG_OK; } #endif /* unused */ static int vx1700_read_op_data(RIG *rig, unsigned char *hwmode, freq_t *rx_freq, freq_t *tx_freq) { int ret; unsigned char reply[VX1700_OP_DATA_LENGTH]; if ((ret = vx1700_read_op_data_raw(rig, reply)) != RIG_OK) { return ret; } if (hwmode != NULL) { *hwmode = reply[7]; } if (rx_freq != NULL) { *rx_freq = vx1700_read_freq_from_buf(reply + 2); } if (tx_freq != NULL) { *tx_freq = vx1700_read_freq_from_buf(reply + 11); } return RIG_OK; } static const char *vx1700_get_hwmode_str(unsigned char hwmode) { switch (hwmode) { case VX1700_MODE_AM: return "AM (A3E)"; case VX1700_MODE_LSB: return "LSB (J3E)"; case VX1700_MODE_USB: return "USB (J3E)"; case VX1700_MODE_CW_W: return "CW (A1A-W)"; case VX1700_MODE_CW_N: return "CW (A1A-N)"; case VX1700_MODE_RTTY: return "RTTY[R] (J2B)"; default: return "unknown"; } } static void vx1700_parse_vfo_data(const char *func, const unsigned char buf[VX1700_VFO_DATA_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.band_data=0x%02d\n", func, buf[0]); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 1)); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: rx.mode=0x%02d, %s\n", func, buf[6], vx1700_get_hwmode_str(buf[6])); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.band_data=0x%02d\n", func, buf[9]); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 10)); rig_debug(RIG_DEBUG_TRACE, "%s: vfo-data: tx.mode=0x%02d, %s\n", func, buf[15], vx1700_get_hwmode_str(buf[15])); } static void vx1700_parse_op_data(const char *func, const unsigned char buf[VX1700_OP_DATA_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Semi Duplex Memory Channel: %s\n", func, (buf[0] & 0x20) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Alpha Numeric Channel: %s\n", func, (buf[0] & 0x40) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: Erased Memory Channel: %s\n", func, (buf[0] & 0x80) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.band_data=0x%02d\n", func, buf[1]); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 2)); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: rx.mode=0x%02d, %s\n", func, buf[7], vx1700_get_hwmode_str(buf[7])); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.band_data=0x%02d\n", func, buf[10]); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.freq=%f\n", func, vx1700_read_freq_from_buf(buf + 11)); rig_debug(RIG_DEBUG_TRACE, "%s: op-data: tx.mode=0x%02d, %s\n", func, buf[16], vx1700_get_hwmode_str(buf[16])); } static void vx1700_parse_status_flags(const char *func, const unsigned char buf[VX1700_STATUS_FLAGS_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: flags: Lock: %s\n", func, (buf[0] & VX1700_SF_LOCKED) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Memory Mode: %s\n", func, (buf[0] & VX1700_SF_MEM) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: VFO Mode: %s\n", func, (buf[0] & VX1700_SF_VFO) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: PTT closed by CAT: %s\n", func, (buf[1] & VX1700_SF_PTT_BY_CAT) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Scanning paused: %s\n", func, (buf[1] & VX1700_SF_MEM_SCAN_PAUSE) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Scanning enabled: %s\n", func, (buf[1] & VX1700_SF_MEM_SCAN) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Narrow RTTY filter: %s\n", func, (buf[1] & VX1700_SF_RTTY_FILTER_NARROW) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Narrow CW filter: %s\n", func, (buf[1] & VX1700_SF_CW_FILTER_NARROW) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: USB for RTTY: %s\n", func, (buf[1] & VX1700_SF_RTTY_USB) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: 10 Watt TX output: %s\n", func, (buf[2] & VX1700_SF_10W_TX) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Antenna Tuner: %s\n", func, (buf[2] & VX1700_SF_TUNER_ON) ? "on" : "off"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: Transmission: %s\n", func, (buf[2] & VX1700_SF_TRANSMISSION_ON) ? "yes" : "no"); rig_debug(RIG_DEBUG_TRACE, "%s: flags: end bytes (0x06, 0x04): 0x%02x, 0x%02x\n", func, buf[3], buf[4]); } static void vx1700_parse_meter(const char *func, const unsigned char buf[VX1700_READ_METER_LENGTH]) { rig_debug(RIG_DEBUG_TRACE, "%s: meter: data: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", __func__, buf[0], buf[1], buf[2], buf[3]); rig_debug(RIG_DEBUG_TRACE, "%s: meter: end byte (0xF7): 0x%02x\n", __func__, buf[4]); } static void dump_radio_state(RIG *rig) { unsigned char channel = 0; unsigned char reply[VX1700_OP_DATA_LENGTH]; if (rig == NULL) { return; } if (vx1700_read_mem_channel_number(rig, &channel) != RIG_OK) { return; } if (vx1700_channel_is_ok(channel)) { rig_debug(RIG_DEBUG_TRACE, "%s: Current Memory Channel %d\n", __func__, (int)channel); } else { rig_debug(RIG_DEBUG_TRACE, "%s: Memory Channel number is not available at the moment\n", __func__); } if (vx1700_read_op_data_raw(rig, reply) != RIG_OK) { return; } vx1700_parse_op_data(__func__, reply); if (vx1700_read_vfo_data_raw(rig, reply) != RIG_OK) { return; } vx1700_parse_vfo_data(__func__, reply); if (vx1700_read_status_flags(rig, reply) != RIG_OK) { return; } vx1700_parse_status_flags(__func__, reply); if (vx1700_read_meter(rig, reply) != RIG_OK) { return; } vx1700_parse_meter(__func__, reply); } static int vx1700_init(RIG *rig) { struct vx1700_priv_data *priv; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); STATE(rig)->priv = calloc(1, sizeof(struct vx1700_priv_data)); if (STATE(rig)->priv == NULL) { return -RIG_ENOMEM; } priv = STATE(rig)->priv; priv->ch = 1; return RIG_OK; } static int vx1700_open(RIG *rig) { struct vx1700_priv_data *priv = (struct vx1700_priv_data *)STATE(rig)->priv; struct rig_state *state = STATE(rig); int ret; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_get_vfo(rig, &state->current_vfo)) != RIG_OK) { return ret; } if ((ret = vx1700_get_mode(rig, RIG_VFO_CURR, &state->current_mode, &state->current_width)) != RIG_OK) { return ret; } if ((ret = vx1700_read_op_data(rig, NULL, &state->current_freq, NULL)) != RIG_OK) { return ret; } if ((ret = vx1700_read_mem_channel_number(rig, &priv->ch)) != RIG_OK) { return ret; } return RIG_OK; } static int vx1700_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if (STATE(rig)->priv != NULL) { free(STATE(rig)->priv); } STATE(rig)->priv = NULL; return RIG_OK; } static const char *vx1700_get_info(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); dump_radio_state(rig); return "NO_INFO"; } static int vx1700_set_vfo(RIG *rig, vfo_t vfo) { const struct vx1700_priv_data *priv = (struct vx1700_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s, vfo=%s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_CURR: return RIG_OK; case RIG_VFO_VFO: case RIG_VFO_A: return vx1700_do_static_cmd(rig, VX1700_NATIVE_VFO_A); case RIG_VFO_MEM: return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, priv->ch, 0, 0, 0); default: return -RIG_EINVAL; } } static int vx1700_get_vfo(RIG *rig, vfo_t *vfo) { int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *vfo = (reply[0] & VX1700_SF_MEM) ? RIG_VFO_MEM : RIG_VFO_A; return RIG_OK; } static int vx1700_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: freq=%f\n", __func__, freq); return vx1700_do_freq_cmd(rig, VX1700_NATIVE_FREQ_SET, freq); } static int vx1700_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { (void) vfo; return vx1700_read_op_data(rig, NULL, freq, NULL); } static int vx1700_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: freq=%f\n", __func__, tx_freq); int err = rig_set_split_vfo(rig, RIG_VFO_A, RIG_SPLIT_ON, RIG_VFO_B); if (err != RIG_OK) { return err; } return vx1700_do_freq_cmd(rig, VX1700_NATIVE_TX_FREQ_SET, tx_freq); } static int vx1700_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); return vx1700_read_op_data(rig, NULL, NULL, tx_freq); } static int vx1700_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: mode=0x%04x, width=%d\n", __func__, (int) mode, (int) width); if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } switch (mode) { case RIG_MODE_AM: return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_AM); case RIG_MODE_LSB: return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_LSB); case RIG_MODE_USB: return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_USB); case RIG_MODE_CW: if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_CW_W); } else { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_CW_N); } case RIG_MODE_RTTY: if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_LSB_W); } else { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_LSB_N); } case RIG_MODE_RTTYR: if (width > (VX1700_FILTER_WIDTH_NARROW + VX1700_FILTER_WIDTH_WIDE) / 2) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_USB_W); } else { return vx1700_do_static_cmd(rig, VX1700_NATIVE_MODE_SET_RTTY_USB_N); } default: return -RIG_EINVAL; } } static int vx1700_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret; unsigned char hwmode; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_read_op_data(rig, &hwmode, NULL, NULL)) != RIG_OK) { return ret; } switch (hwmode) { case VX1700_MODE_AM: *mode = RIG_MODE_AM; *width = VX1700_FILTER_WIDTH_AM; return RIG_OK; case VX1700_MODE_LSB: *mode = RIG_MODE_LSB; *width = VX1700_FILTER_WIDTH_SSB; return RIG_OK; case VX1700_MODE_USB: *mode = RIG_MODE_USB; *width = VX1700_FILTER_WIDTH_SSB; return RIG_OK; case VX1700_MODE_CW_W: *mode = RIG_MODE_CW; *width = VX1700_FILTER_WIDTH_WIDE; return RIG_OK; case VX1700_MODE_CW_N: *mode = RIG_MODE_CW; *width = VX1700_FILTER_WIDTH_NARROW; return RIG_OK; case VX1700_MODE_RTTY: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *mode = (reply[1] & VX1700_SF_RTTY_USB) ? RIG_MODE_RTTYR : RIG_MODE_RTTY; *width = (reply[1] & VX1700_SF_RTTY_FILTER_NARROW) ? VX1700_FILTER_WIDTH_NARROW : VX1700_FILTER_WIDTH_WIDE; return RIG_OK; default: return -RIG_EPROTO; } } static int vx1700_set_ptt_gps_jack(ptt_t ptt) { (void) ptt; /* * FIXME * * We are using GPIO to manage PTT pin in GPS/Data jack. * This highly binded to our specific device, so it makes * no sense to put our code here. * On regular PC this should be managed in another way, * probably via DTR/RTS. */ return -RIG_EINVAL; } static int vx1700_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { rmode_t mode; pbwidth_t width; int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; rig_debug(RIG_DEBUG_TRACE, "%s, ptt=%d\n", __func__, ptt); /* * We have 3 PTT source on Vertex Standard VX-1700: * 1) ptt on radio garniture (not checked, FIXME) * 2) PTT commands inside CAT operation protocol * - select radio garniture as audio input/output source * - does not work in RTTY/RTTYR modes * 3) PTT pin in GPS/Data jack * - select GPS/Data jack as input/output source * - does not work in CW/AM modes */ if ((ret = vx1700_get_mode(rig, vfo, &mode, &width)) != RIG_OK) { return ret; } switch (mode) { case RIG_MODE_AM: case RIG_MODE_CW: switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_MIC: return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_ON); case RIG_PTT_OFF: return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_OFF); default: return -RIG_EINVAL; } case RIG_MODE_LSB: case RIG_MODE_USB: switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_MIC: return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_ON); case RIG_PTT_ON_DATA: return vx1700_set_ptt_gps_jack(RIG_PTT_ON); case RIG_PTT_OFF: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } if (reply[1] & VX1700_SF_PTT_BY_CAT) { /* PTT was turned on by CAT command, turn it off accordingly */ return vx1700_do_static_cmd(rig, VX1700_NATIVE_PTT_OFF); } /* PTT was turned on via special pin on GPS/DATA jack */ return vx1700_set_ptt_gps_jack(RIG_PTT_OFF); default: return -RIG_EINVAL; } case RIG_MODE_RTTY: case RIG_MODE_RTTYR: switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_DATA: return vx1700_set_ptt_gps_jack(RIG_PTT_ON); case RIG_PTT_OFF: return vx1700_set_ptt_gps_jack(RIG_PTT_OFF); default: return -RIG_EINVAL; } default: return -RIG_EINVAL; } } static int vx1700_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *ptt = (reply[2] & VX1700_SF_TRANSMISSION_ON) ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } static int vx1700_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: func=%s, status=%d\n", __func__, rig_strfunc(func), status); return -RIG_EINVAL; } static int vx1700_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret; unsigned char reply[VX1700_STATUS_FLAGS_LENGTH]; (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: func=%s\n", __func__, rig_strfunc(func)); switch (func) { case RIG_FUNC_LOCK: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *status = (reply[0] & VX1700_SF_LOCKED) ? 1 : 0; return RIG_OK; case RIG_FUNC_TUNER: if ((ret = vx1700_read_status_flags(rig, reply)) != RIG_OK) { return ret; } *status = (reply[2] & VX1700_SF_TUNER_ON) ? 1 : 0; return RIG_OK; default: return -RIG_EINVAL; } } static int vx1700_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: level=%s, val=???\n", __func__, rig_strlevel(level)); switch (level) { case RIG_LEVEL_RFPOWER: if ((val.f < 0.0) || (val.f > 1.0)) { return -RIG_EINVAL; } if (val.f < (1.0 / 3.0)) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_LOW); } if (val.f < (2.0 / 3.0)) { return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_MID); } return vx1700_do_static_cmd(rig, VX1700_NATIVE_TX_POWER_HI); default: return -RIG_EINVAL; } } static int vx1700_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: level=%s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } static int vx1700_set_mem(RIG *rig, vfo_t vfo, int ch) { struct vx1700_priv_data *priv = (struct vx1700_priv_data *)STATE(rig)->priv; const struct rig_state *state = STATE(rig); if (! vx1700_channel_is_ok(ch)) { return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { vfo = state->current_vfo; } if (vfo == RIG_VFO_MEM) { int ret; ret = vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, ch, 0, 0, 0); if (ret == RIG_OK) { priv->ch = ch; } return ret; } priv->ch = ch; return RIG_OK; } static int vx1700_get_mem(RIG *rig, vfo_t vfo, int *ch) { struct vx1700_priv_data *priv = (struct vx1700_priv_data *)STATE(rig)->priv; const struct rig_state *state = STATE(rig); unsigned char channel = 0; if (vfo == RIG_VFO_CURR) { vfo = state->current_vfo; } if (vfo == RIG_VFO_MEM) { int ret; ret = vx1700_read_mem_channel_number(rig, &channel); if (ret != RIG_OK) { return ret; } if (vx1700_channel_is_ok(channel)) { *ch = priv->ch = channel; return RIG_OK; } return -RIG_ERJCTED; } if (! vx1700_channel_is_ok(priv->ch)) { return -RIG_ERJCTED; } *ch = priv->ch; return RIG_OK; } static int vx1700_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { const struct vx1700_priv_data *priv = (struct vx1700_priv_data *) STATE(rig)->priv; (void) rig; (void) vfo; rig_debug(RIG_DEBUG_TRACE, "%s: op=0x%04x\n", __func__, (int) op); switch (op) { case RIG_OP_TO_VFO: return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_RECALL_MEM, priv->ch, 0, 0, 0); case RIG_OP_FROM_VFO: return vx1700_do_dynamic_cmd(rig, VX1700_NATIVE_VFO_TO_MEM, priv->ch, 0, 0, 0); case RIG_OP_UP: return vx1700_do_static_cmd(rig, VX1700_NATIVE_OP_FREQ_STEP_UP); case RIG_OP_DOWN: return vx1700_do_static_cmd(rig, VX1700_NATIVE_OP_FREQ_STEP_DOWN); default: return -RIG_EINVAL; } } hamlib-4.6.2/rigs/yaesu/ft817.c0000644000175000017500000020262514752216205013022 00000000000000/* * hamlib - (C) Frank Singleton 2000,2001 (vk3fcs@ix.netcom.com) * (C) Stephane Fillod 2000-2009 * * ft817.c - (C) Chris Karpinsky 2001 (aa1vl@arrl.net) * This shared library provides an API for communicating * via serial interface to an FT-817 using the "CAT" interface. * The starting point for this code was Frank's ft847 implementation. * * Then, Tommi OH2BNS improved the code a lot in the framework of the * FT-857 backend. These improvements have now (August 2005) been * copied back and adopted for the FT-817. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* * Unimplemented features supported by the FT-817: * * - RX status command returns info that is not used: * - discriminator centered (yes/no flag) * - received ctcss/dcs matched (yes/no flag) TBC * * - TX status command returns info that is not used: * - high swr flag * * Todo / tocheck list (oz9aec): * - test get_dcd; rigctl does not support it? * - squelch * - the many "fixme" stuff around */ #include #include /* String function definitions */ #include #ifdef HAVE_SYS_TIME_H #include #endif #include "hamlib/rig.h" #include "serial.h" #include "yaesu.h" #include "ft817.h" #include "misc.h" #include "tones.h" #include "bandplan.h" #include "cal.h" enum ft817_native_cmd_e { FT817_NATIVE_CAT_LOCK_ON = 0, FT817_NATIVE_CAT_LOCK_OFF, FT817_NATIVE_CAT_PTT_ON, FT817_NATIVE_CAT_PTT_OFF, FT817_NATIVE_CAT_SET_FREQ, FT817_NATIVE_CAT_SET_MODE_LSB, FT817_NATIVE_CAT_SET_MODE_USB, FT817_NATIVE_CAT_SET_MODE_CW, FT817_NATIVE_CAT_SET_MODE_CWR, FT817_NATIVE_CAT_SET_MODE_AM, FT817_NATIVE_CAT_SET_MODE_FM, FT817_NATIVE_CAT_SET_MODE_FM_N, FT817_NATIVE_CAT_SET_MODE_DIG, FT817_NATIVE_CAT_SET_MODE_PKT, FT817_NATIVE_CAT_CLAR_ON, FT817_NATIVE_CAT_CLAR_OFF, FT817_NATIVE_CAT_SET_CLAR_FREQ, FT817_NATIVE_CAT_SET_VFOAB, FT817_NATIVE_CAT_SPLIT_ON, FT817_NATIVE_CAT_SPLIT_OFF, FT817_NATIVE_CAT_SET_RPT_SHIFT_MINUS, FT817_NATIVE_CAT_SET_RPT_SHIFT_PLUS, FT817_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX, FT817_NATIVE_CAT_SET_RPT_OFFSET, FT817_NATIVE_CAT_SET_DCS_ON, FT817_NATIVE_CAT_SET_CTCSS_ON, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF, FT817_NATIVE_CAT_SET_CTCSS_FREQ, FT817_NATIVE_CAT_SET_DCS_CODE, FT817_NATIVE_CAT_GET_RX_STATUS, FT817_NATIVE_CAT_GET_TX_STATUS, FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS, FT817_NATIVE_CAT_PWR_WAKE, FT817_NATIVE_CAT_PWR_ON, FT817_NATIVE_CAT_PWR_OFF, FT817_NATIVE_CAT_EEPROM_READ, FT817_NATIVE_CAT_EEPROM_WRITE, FT817_NATIVE_CAT_GET_TX_METERING, FT817_NATIVE_SIZE /* end marker */ }; struct ft817_priv_data { /* rx status */ struct timeval rx_status_tv; unsigned char rx_status; /* tx status */ struct timeval tx_status_tv; unsigned char tx_status; /* Raw data from rig. Highest bit 0 = PTT */ /* tx levels */ struct timeval tx_level_tv; unsigned char swr_level; unsigned char alc_level; unsigned char mod_level; unsigned char pwr_level; /* TX power level */ /* freq & mode status */ struct timeval fm_status_tv; unsigned char fm_status[5]; /* 5 bytes, NOT related to YAESU_CMD_LENGTH */ /* Digi mode is not part of regular fm_status response. * So keep track of it in a separate variable. */ unsigned char dig_mode; float swr; }; static int ft817_init(RIG *rig); static int ft817_open(RIG *rig); static int ft817_cleanup(RIG *rig); static int ft817_close(RIG *rig); static int ft817_get_vfo(RIG *rig, vfo_t *vfo); static int ft817_set_vfo(RIG *rig, vfo_t vfo); static int ft817_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int ft817_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int ft817_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int ft817_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int ft817_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int ft817_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int ft817_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ft817_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int ft817_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code); static int ft817_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int ft817_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int ft817_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int ft817_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int ft817_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); static int ft817_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ft817_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int ft817_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int ft817_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); static int ft817_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); static int ft817_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); static int ft817_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); static int ft817_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); static int ft818_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); /* Native ft817 cmd set prototypes. These are READ ONLY as each */ /* rig instance will copy from these and modify if required . */ /* Complete sequences (1) can be read and used directly as a cmd sequence . */ /* Incomplete sequences (0) must be completed with extra parameters */ /* eg: mem number, or freq etc.. */ static const yaesu_cmd_set_t ncmd[] = { { 1, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, /* lock on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x80 } }, /* lock off */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x08 } }, /* ptt on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x88 } }, /* ptt off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* set freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main LSB */ { 1, { 0x01, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main USB */ { 1, { 0x02, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CW */ { 1, { 0x03, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main CWR */ { 1, { 0x04, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main AM */ { 1, { 0x08, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM */ { 1, { 0x88, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main FM-N */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main DIG */ { 1, { 0x0c, 0x00, 0x00, 0x00, 0x07 } }, /* mode set main PKT */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x05 } }, /* clar on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x85 } }, /* clar off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf5 } }, /* set clar freq */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x81 } }, /* toggle vfo a/b */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x02 } }, /* split on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x82 } }, /* split off */ { 1, { 0x09, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift MINUS */ { 1, { 0x49, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift PLUS */ { 1, { 0x89, 0x00, 0x00, 0x00, 0x09 } }, /* set RPT shift SIMPLEX */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xf9 } }, /* set RPT offset freq */ { 1, { 0x0a, 0x00, 0x00, 0x00, 0x0a } }, /* set DCS on */ { 1, { 0x2a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS on */ { 1, { 0x4a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS encoder on */ { 1, { 0x8a, 0x00, 0x00, 0x00, 0x0a } }, /* set CTCSS/DCS off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0b } }, /* set CTCSS tone */ { 0, { 0x00, 0x00, 0x00, 0x00, 0x0c } }, /* set DCS code */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xe7 } }, /* get RX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xf7 } }, /* get TX status */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x03 } }, /* get FREQ and MODE status */ { 1, { 0xff, 0xff, 0xff, 0xff, 0xff } }, /* pwr wakeup sequence */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x0f } }, /* pwr on */ { 1, { 0x00, 0x00, 0x00, 0x00, 0x8f } }, /* pwr off */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbb } }, /* eeprom read */ { 0, { 0x00, 0x00, 0x00, 0x00, 0xbc } }, /* eeprom write */ { 1, { 0x00, 0x00, 0x00, 0x00, 0xbd } }, /* get TX metering levels (PWR, SWR, MOD, ALC) */ }; enum ft817_digi { FT817_DIGI_RTTY = 0, FT817_DIGI_PSK_L, FT817_DIGI_PSK_U, FT817_DIGI_USER_L, FT817_DIGI_USER_U, }; #define FT817_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PKTFM|\ RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY) #define FT817_CWN_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_RTTY) #define FT817_AM_FM_RX_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTFM) #define FT817_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_USB|\ RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_FM|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_PSK|RIG_MODE_PSKR) #define FT817_AM_TX_MODES (RIG_MODE_AM) #define FT817_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT817_ANT_FRONT (RIG_ANT_1) #define FT817_ANT_REAR (RIG_ANT_2) #define FT817_ANTS (FT817_ANT_FRONT | FT817_ANT_REAR) #define FT817_STR_CAL { 16, \ { \ { 0x00, -54 }, /* S0 */ \ { 0x01, -48 }, \ { 0x02, -42 }, \ { 0x03, -36 }, \ { 0x04, -30 }, \ { 0x05, -24 }, \ { 0x06, -18 }, \ { 0x07, -12 }, \ { 0x08, -6 }, \ { 0x09, 0 }, /* S9 */ \ { 0x0A, 10 }, /* +10 */ \ { 0x0B, 20 }, /* +20 */ \ { 0x0C, 30 }, /* +30 */ \ { 0x0D, 40 }, /* +40 */ \ { 0x0E, 50 }, /* +50 */ \ { 0x0F, 60 } /* +60 */ \ } } // Thanks to Olivier Schmitt sc.olivier@gmail.com for these tables #define FT817_PWR_CAL { 9, \ { \ { 0x00, 0.0f }, \ { 0x01, 0.5f }, \ { 0x02, 0.75f }, \ { 0x03, 1.0f }, \ { 0x04, 1.7f }, \ { 0x05, 2.5f }, \ { 0x06, 3.3f }, \ { 0x07, 4.1f }, \ { 0x08, 5.0f } \ } } #define FT817_ALC_CAL { 6, \ { \ { 0x00, 0 }, \ { 0x01, 20 }, \ { 0x02, 40 }, \ { 0x03, 60 }, \ { 0x04, 80 }, \ { 0x05, 100 } \ } } // SWR values from Christian WA4YA, DL4YA #define FT817_SWR_CAL { 16, \ { \ { 0, 1.0f }, \ { 1, 1.4f }, \ { 2, 1.8f }, \ { 3, 2.13f }, \ { 4, 2.25f }, \ { 5, 3.7f }, \ { 6, 6.0f }, \ { 7, 7.0f }, \ { 8, 8.0f }, \ { 9, 9.0f }, \ { 10, 10.0f }, \ { 11, 10.0f }, \ { 12, 10.0f }, \ { 13, 10.0f }, \ { 14, 10.0f }, \ { 15, 10.0f } \ } } struct rig_caps ft817_caps = { RIG_MODEL(RIG_MODEL_FT817), .model_name = "FT-817", .mfg_name = "Yaesu", .version = "20241117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT817_WRITE_DELAY, .post_write_delay = FT817_POST_WRITE_DELAY, .timeout = FT817_TIMEOUT, .retry = 5, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | RIG_LEVEL_ALC | RIG_LEVEL_SWR | RIG_LEVEL_RFPOWER_METER_WATTS, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* FIXME: 60 meters in US version */ FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = ft817_init, .rig_cleanup = ft817_cleanup, .rig_open = ft817_open, .rig_close = ft817_close, .get_vfo = ft817_get_vfo, .set_vfo = ft817_set_vfo, .set_freq = ft817_set_freq, .get_freq = ft817_get_freq, .set_mode = ft817_set_mode, .get_mode = ft817_get_mode, .set_ptt = ft817_set_ptt, .get_ptt = ft817_get_ptt, .get_dcd = ft817_get_dcd, .set_rptr_shift = ft817_set_rptr_shift, .set_rptr_offs = ft817_set_rptr_offs, .set_split_vfo = ft817_set_split_vfo, .get_split_vfo = ft817_get_split_vfo, .set_rit = ft817_set_rit, .set_dcs_code = ft817_set_dcs_code, .set_ctcss_tone = ft817_set_ctcss_tone, .set_dcs_sql = ft817_set_dcs_sql, .set_ctcss_sql = ft817_set_ctcss_sql, .power2mW = ft817_power2mW, .mW2power = ft817_mW2power, .set_powerstat = ft817_set_powerstat, .get_ant = ft817_get_ant, .get_level = ft817_get_level, .set_func = ft817_set_func, .vfo_op = ft817_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps q900_caps = { RIG_MODEL(RIG_MODEL_Q900), .model_name = "Q900", .mfg_name = "Guohe", .version = "20241117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT817_WRITE_DELAY, .post_write_delay = FT817_POST_WRITE_DELAY, .timeout = FT817_TIMEOUT, .retry = 5, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_CSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | RIG_LEVEL_ALC | RIG_LEVEL_SWR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* FIXME: 60 meters in US version */ FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = ft817_init, .rig_cleanup = ft817_cleanup, .rig_open = ft817_open, .rig_close = ft817_close, .get_vfo = ft817_get_vfo, .set_vfo = ft817_set_vfo, .set_freq = ft817_set_freq, .get_freq = ft817_get_freq, .set_mode = ft817_set_mode, .get_mode = ft817_get_mode, .set_ptt = ft817_set_ptt, .get_ptt = ft817_get_ptt, .get_dcd = ft817_get_dcd, .set_rptr_shift = ft817_set_rptr_shift, .set_rptr_offs = ft817_set_rptr_offs, .set_split_vfo = ft817_set_split_vfo, .get_split_vfo = ft817_get_split_vfo, .set_rit = ft817_set_rit, .set_dcs_code = ft817_set_dcs_code, .set_ctcss_tone = ft817_set_ctcss_tone, .set_dcs_sql = ft817_set_dcs_sql, .set_ctcss_sql = ft817_set_ctcss_sql, .power2mW = ft817_power2mW, .mW2power = ft817_mW2power, .set_powerstat = ft817_set_powerstat, .get_ant = ft817_get_ant, .get_level = ft817_get_level, .set_func = ft817_set_func, .vfo_op = ft817_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ft818_caps = { RIG_MODEL(RIG_MODEL_FT818), .model_name = "FT-818", .mfg_name = "Yaesu", .version = "20221117.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = FT817_WRITE_DELAY, .post_write_delay = FT817_POST_WRITE_DELAY, .timeout = FT817_TIMEOUT, .retry = 5, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_LOCK | RIG_FUNC_TONE | RIG_FUNC_TSQL | RIG_FUNC_RIT, .has_get_level = RIG_LEVEL_STRENGTH | RIG_LEVEL_RAWSTR | RIG_LEVEL_RFPOWER | RIG_LEVEL_ALC | RIG_LEVEL_SWR, .has_set_level = RIG_LEVEL_BAND_SELECT, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_yaesu.h" }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, /* only 104 out of 106 supported */ .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_TOGGLE, .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list1 = { FRQ_RNG_HF(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* One of the key differences between 817 and 818: the 818 has 60m! */ FRQ_RNG_60m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_60m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(1, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(56), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(76), MHz(108), RIG_MODE_WFM, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(118), MHz(164), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, {MHz(420), MHz(470), FT817_ALL_RX_MODES, -1, -1, FT817_VFO_ALL, FT817_ANTS}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_HF(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), /* One of the key differences between 817 and 818: the 818 has 60m! */ FRQ_RNG_60m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_60m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_6m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_2m(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_OTHER_TX_MODES, W(0.5), W(5), FT817_VFO_ALL, FT817_ANTS), FRQ_RNG_70cm(2, FT817_AM_TX_MODES, W(0.5), W(1.5), FT817_VFO_ALL, FT817_ANTS), RIG_FRNG_END, }, .tuning_steps = { {FT817_SSB_CW_RX_MODES, Hz(10)}, {FT817_AM_FM_RX_MODES | RIG_MODE_WFM, Hz(100)}, RIG_TS_END, }, .filters = { {FT817_SSB_CW_RX_MODES, kHz(2.2)}, /* normal passband */ {FT817_CWN_RX_MODES, 500}, /* CW and RTTY narrow */ {RIG_MODE_AM, kHz(6)}, /* AM normal */ {RIG_MODE_FM | RIG_MODE_PKTFM, kHz(9)}, {RIG_MODE_WFM, kHz(15)}, RIG_FLT_END, }, .str_cal = FT817_STR_CAL, .swr_cal = FT817_SWR_CAL, .alc_cal = FT817_ALC_CAL, .rfpower_meter_cal = FT817_PWR_CAL, .rig_init = ft817_init, .rig_cleanup = ft817_cleanup, .rig_open = ft817_open, .rig_close = ft817_close, .get_vfo = ft817_get_vfo, .set_vfo = ft817_set_vfo, .set_freq = ft817_set_freq, .get_freq = ft817_get_freq, .set_mode = ft817_set_mode, .get_mode = ft817_get_mode, .set_ptt = ft817_set_ptt, .get_ptt = ft817_get_ptt, .get_dcd = ft817_get_dcd, .set_rptr_shift = ft817_set_rptr_shift, .set_rptr_offs = ft817_set_rptr_offs, .set_split_vfo = ft817_set_split_vfo, .get_split_vfo = ft817_get_split_vfo, .set_rit = ft817_set_rit, .set_dcs_code = ft817_set_dcs_code, .set_ctcss_tone = ft817_set_ctcss_tone, .set_dcs_sql = ft817_set_dcs_sql, .set_ctcss_sql = ft817_set_ctcss_sql, .power2mW = ft817_power2mW, .mW2power = ft817_mW2power, .set_powerstat = ft817_set_powerstat, .get_ant = ft818_get_ant, .get_level = ft817_get_level, .set_func = ft817_set_func, .vfo_op = ft817_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* ---------------------------------------------------------------------- */ static int ft817_init(RIG *rig) { struct ft817_priv_data *p; rig_debug(RIG_DEBUG_VERBOSE, "%s: called, version %s\n", __func__, rig->caps->version); if ((STATE(rig)->priv = calloc(1, sizeof(struct ft817_priv_data))) == NULL) { return -RIG_ENOMEM; } p = (struct ft817_priv_data *) STATE(rig)->priv; p->swr = 10; return RIG_OK; } static int ft817_cleanup(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); free(STATE(rig)->priv); STATE(rig)->priv = NULL; return RIG_OK; } static int ft817_open(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); hl_usleep(1500 * 1000); // rig needs a bit to allow commands to come through on startup return RIG_OK; } static int ft817_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); return RIG_OK; } /* ---------------------------------------------------------------------- */ static inline long timediff(const struct timeval *tv1, const struct timeval *tv2) { struct timeval tv; tv.tv_usec = tv1->tv_usec - tv2->tv_usec; tv.tv_sec = tv1->tv_sec - tv2->tv_sec; return ((tv.tv_sec * 1000L) + (tv.tv_usec / 1000L)); } static int check_cache_timeout(struct timeval *tv) { struct timeval curr; long t; if (tv->tv_sec == 0 && tv->tv_usec == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cache invalid\n", __func__); return 1; } gettimeofday(&curr, NULL); if ((t = timediff(&curr, tv)) < FT817_CACHE_TIMEOUT) { rig_debug(RIG_DEBUG_VERBOSE, "ft817: using cache (%ld ms)\n", t); return 0; } else { rig_debug(RIG_DEBUG_VERBOSE, "ft817: cache timed out (%ld ms)\n", t); return 1; } } static int ft817_read_eeprom(RIG *rig, unsigned short addr, unsigned char *out) { unsigned char data[YAESU_CMD_LENGTH]; hamlib_port_t *rp = RIGPORT(rig); int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); memcpy(data, ncmd[FT817_NATIVE_CAT_EEPROM_READ].nseq, YAESU_CMD_LENGTH); data[0] = addr >> 8; data[1] = addr & 0xff; write_block(rp, data, YAESU_CMD_LENGTH); if ((n = read_block(rp, data, 2)) < 0) { return n; } if (n != 2) { return -RIG_EIO; } if (addr == 0x55) // for some reason VFO returns high byte { *out = data[0]; } else { *out = data[addr % 2]; } rig_debug(RIG_DEBUG_VERBOSE, "%s: data[0]=%02x, data[1]=%02x, out=%02x\n", __func__, data[0], data[1], *out); memcpy(out, data, 2); return RIG_OK; } static int ft817_get_status(RIG *rig, int status) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; hamlib_port_t *rp = RIGPORT(rig); struct timeval *tv; unsigned char *data; int len; int n; int retries = rp->retry; unsigned char result[2]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS: data = p->fm_status; /* Answer is 5 long; 4 bytes BCD freq, 1 byte status */ len = 5; tv = &p->fm_status_tv; break; case FT817_NATIVE_CAT_GET_RX_STATUS: data = &p->rx_status; len = 1; tv = &p->rx_status_tv; break; case FT817_NATIVE_CAT_GET_TX_METERING: data = result; len = sizeof(result) / sizeof(result[0]); /* We expect two bytes */ tv = &p->tx_level_tv; break; case FT817_NATIVE_CAT_GET_TX_STATUS: data = &p->tx_status; len = 1; tv = &p->tx_status_tv; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Internal error!\n", __func__); return -RIG_EINTERNAL; } do { rig_flush(rp); write_block(rp, ncmd[status].nseq, YAESU_CMD_LENGTH); n = read_block(rp, data, len); } while (retries-- && n < 0); if (n < 0) { return n; } if (n != len) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Length mismatch exp %d got %d!\n", __func__, len, n); return -RIG_EIO; } switch (status) { case FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS: { /* Only in digimode we need fetch to extra bits from EEPROM. * This save communication cycle for all other modes. * Because mode and frequency are shared this saves also when * getting the frequency. */ switch (p->fm_status[4] & 0x7f) { unsigned char dig_mode[2]; case 0x0a: if ((n = ft817_read_eeprom(rig, 0x0065, dig_mode)) < 0) { return n; } /* Top 3 bit define the digi mode */ p->dig_mode = dig_mode[0] >> 5; default: break; } } break; case FT817_NATIVE_CAT_GET_TX_METERING: /* FT-817 returns 2 bytes with 4 nibbles. * Extract raw values here; * convert to float when they are requested. */ p->swr_level = (result[1] & 0xF0) >> 4; p->pwr_level = (result[0] & 0xF0) >> 4; p->alc_level = result[0] & 0x0F; p->mod_level = result[1] >> 4; rig_debug(RIG_DEBUG_TRACE, "%s: swr: %d, pwr %d, alc %d, mod %d\n", __func__, p->swr_level, p->pwr_level, p->alc_level, p->mod_level); break; } gettimeofday(tv, NULL); return RIG_OK; } /* ---------------------------------------------------------------------- */ static int ft817_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; freq_t f1 = 0, f2 = 0; struct rig_cache *cachep = CACHE(rig); int retries = RIGPORT(rig)->retry + 1; // +1 because, because 2 steps are needed even in best scenario rig_debug(RIG_DEBUG_VERBOSE, "%s: called, vfo=%s, ptt=%d, split=%d\n", __func__, rig_strvfo(vfo), cachep->ptt, cachep->split); // we can't query VFOB while in transmit and split mode if (cachep->ptt && vfo == RIG_VFO_B && cachep->split) { *freq = cachep->freqMainB; return RIG_OK; } while ((f1 == 0 || f1 != f2) && retries-- > 0) { int n; rig_debug(RIG_DEBUG_TRACE, "%s: retries=%d\n", __func__, retries); if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } f1 = f2; f2 = from_bcd_be(p->fm_status, 8); dump_hex(p->fm_status, sizeof(p->fm_status) / sizeof(p->fm_status[0])); } #if 1 // user must be twiddling the VFO // usually get_freq is OK but we have to allow that f1 != f2 when knob is moving *freq = f2 * 10; return RIG_OK; #else // remove this if no complaints if (retries >= 0) { *freq = f1 * 10; return RIG_OK; } else { return -RIG_EIO; } #endif } static int ft817_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->fm_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_FREQ_MODE_STATUS)) < 0) { return n; } } switch (p->fm_status[4] & 0x7f) { case 0x00: *mode = RIG_MODE_LSB; break; case 0x01: *mode = RIG_MODE_USB; break; case 0x02: *mode = RIG_MODE_CW; break; case 0x03: *mode = RIG_MODE_CWR; break; case 0x04: *mode = RIG_MODE_AM; break; case 0x06: *mode = RIG_MODE_WFM; break; case 0x08: *mode = RIG_MODE_FM; break; case 0x0a: switch (p->dig_mode) { case FT817_DIGI_RTTY: *mode = RIG_MODE_RTTYR; break; case FT817_DIGI_PSK_L: *mode = RIG_MODE_PSKR; break; case FT817_DIGI_PSK_U: *mode = RIG_MODE_PSK; break; case FT817_DIGI_USER_L: *mode = RIG_MODE_PKTLSB; break; case FT817_DIGI_USER_U: *mode = RIG_MODE_PKTUSB; break; default: *mode = RIG_MODE_NONE; } break; case 0x0C: *mode = RIG_MODE_PKTFM; break; default: *mode = RIG_MODE_NONE; } if (p->fm_status[4] & 0x80) /* narrow */ { *width = rig_passband_narrow(rig, *mode); } else { *width = RIG_PASSBAND_NORMAL; } return RIG_OK; } static int ft817_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { const struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; ptt_t ptt; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); n = ft817_get_ptt(rig, 0, &ptt); if (n != RIG_OK) { return n; } /* Check if rig is in TX mode */ if (ptt == RIG_PTT_OFF) { // TX status not valid when in RX unsigned char c[2]; /* Get split status from EEPROM */ n = ft817_read_eeprom(rig, 0x7a, c); if (n != RIG_OK) { return n; } *split = (c[0] & 0x80) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; *tx_vfo = RIG_VFO_A; } else { *split = (p->tx_status & 0x20) ? RIG_SPLIT_ON : RIG_SPLIT_OFF; *tx_vfo = RIG_VFO_B; } return RIG_OK; } static int ft817_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_TX_STATUS)) < 0) { return n; } } *ptt = p->tx_status != 0xff; return RIG_OK; } static int ft817_get_tx_level(RIG *rig, value_t *val, unsigned char *tx_level, const cal_table_float_t *cal) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->tx_level_tv)) { int n; ptt_t ptt; /* Default to not keyed */ *tx_level = 0; /* TX metering is special; it sends 1 byte if not keyed and 2 if keyed. * To handle this properly we first verify the rig is keyed. * Otherwise we experience at least a full timeout and * perhaps pointless retries + timeouts. */ n = ft817_get_ptt(rig, 0, &ptt); if (n != RIG_OK) { return n; } if (ptt == RIG_PTT_OFF) { val->f = p->swr; return RIG_OK; } n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_TX_METERING); if (n != RIG_OK) { return n; } } p->swr = val->f = rig_raw2val_float(*tx_level, cal); rig_debug(RIG_DEBUG_VERBOSE, "%s: level %f\n", __func__, val->f); return RIG_OK; } /* frontend will always use RAWSTR+cal_table */ static int ft817_get_smeter_level(RIG *rig, value_t *val) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } //n = (p->rx_status & 0x0F) - 9; //val->i = n * ((n > 0) ? 10 : 6); /* S-meter value is returned in the lower 4 bits. 0x00 = S0 (-54dB) 0x01 = S1 0x02 = S2 ... 0x09 = S9 (0dB) 0x0A = S9+10 (10dB) 0x0B = S9+20 and so on */ n = (p->rx_status & 0x0F); if (n < 0x0A) { val->i = (6 * n) - 54; } else { val->i = 10 * (n - 9); } return RIG_OK; } static int ft817_get_raw_smeter_level(RIG *rig, value_t *val) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } val->i = p->rx_status & 0x0F; return RIG_OK; } static int ft817_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; switch (level) { case RIG_LEVEL_STRENGTH: /* The front-end will always call for RAWSTR and use the cal_table */ return ft817_get_smeter_level(rig, val); case RIG_LEVEL_RAWSTR: return ft817_get_raw_smeter_level(rig, val); case RIG_LEVEL_RFPOWER: return ft817_get_tx_level(rig, val, &p->pwr_level, &rig->caps->rfpower_meter_cal); case RIG_LEVEL_ALC: return ft817_get_tx_level(rig, val, &p->alc_level, &rig->caps->alc_cal); case RIG_LEVEL_SWR: return ft817_get_tx_level(rig, val, &p->swr_level, &rig->caps->swr_cal); case RIG_LEVEL_RFPOWER_METER_WATTS: return ft817_get_tx_level(rig, val, &p->pwr_level, &rig->caps->rfpower_meter_cal); default: return -RIG_EINVAL; } return RIG_OK; } static int ft817_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { struct ft817_priv_data *p = (struct ft817_priv_data *) STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (check_cache_timeout(&p->rx_status_tv)) { int n; if ((n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_RX_STATUS)) < 0) { return n; } } /* TODO: consider bit 6 too ??? (CTCSS/DCS code match) */ if (p->rx_status & 0x80) { *dcd = RIG_DCD_OFF; } else { *dcd = RIG_DCD_ON; } return RIG_OK; } static int ft818_817_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx, bool is817) { /* The FT818/817 has no RIG_TARGETABLE_ALL * so rig.c switched the active VFO to the one requested */ int ret; unsigned char eeprom_band[2], eeprom_ant[2]; /* Read eeprom for current 'band' for both VFO's */ ret = ft817_read_eeprom(rig, 0x59, eeprom_band); if (ret != RIG_OK) { return ret; } /* Read eeprom for antenna selection per band. * The FT818/817 stores antenna per band not per VFO! * So changing antenna will change for both VFO's */ ret = ft817_read_eeprom(rig, 0x7A, eeprom_ant); if (ret != RIG_OK) { return ret; } /* if CURR then get real VFO before parsing EEPROM */ if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } /* band info is 4 bit per VFO, for A lower nibble, B is upper nible */ switch (vfo) { case RIG_VFO_A: eeprom_band[0] &= 0xF; break; case RIG_VFO_B: eeprom_band[0] = eeprom_band[0] >> 4; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %0x!\n", __func__, vfo); return -RIG_EINTERNAL; } /* The 818 and the 817 differ in bands: the 818 has 60m. * The band selection flags for the 818 and 817 thus differ: * 2 means 60m on 818 and 40m for 817. * And the rest of the values are shifted. * * So to make the code simple: if we have a 817 and 2 or higher band then * add 1 to the value to align it on the 818 mapping. */ if (is817 && eeprom_band[0] >= 2) { eeprom_band[0]++; } /* The 817/818 does not have a antenna selection per VFO but per band. * So we read the band for the requested VFO and then map it to the * selected antenna. */ switch (eeprom_band[0]) { case 0: /* 160M */ case 1: /* 80M */ case 2: /* 60M, 818 only */ case 3: /* 40M */ case 4: /* 30M */ case 5: /* 20M */ case 6: /* 17M */ case 7: /* 15M */ case 8: /* 12M */ case 9: /* 10M */ /* All HF use the same antenna setting, bit 0 */ eeprom_ant[0] &= 1 << 0; break; case 0xA: /* 6m, bit 1 */ eeprom_ant[0] &= 1 << 1; break; case 0xB: /* FM BCB 76Mhz - 108Mhz, bit 2 */ eeprom_ant[0] &= 1 << 2; break; case 0xC: /* Airband, bit 3 */ eeprom_ant[0] &= 1 << 3; break; case 0xD: /* 2M, bit 4 */ eeprom_ant[0] &= 1 << 4; break; case 0xE: /* 70cm / UHF, bit 5 */ eeprom_ant[0] &= 1 << 5; break; case 0xF: /* Free-tuning?, bit 6 */ eeprom_ant[0] &= 1 << 6; break; } /* We have no split TX/RX capability per VFO. * So only set ant_curr and leave rx/tx set to unknown. */ *ant_curr = eeprom_ant[0] ? FT817_ANT_REAR : FT817_ANT_FRONT; return RIG_OK; } static int ft817_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { return ft818_817_get_ant(rig, vfo, ant, option, ant_curr, ant_tx, ant_rx, true); } static int ft818_get_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { return ft818_817_get_ant(rig, vfo, ant, option, ant_curr, ant_tx, ant_rx, false); } /* ---------------------------------------------------------------------- */ int ft817_read_ack(RIG *rig) { unsigned char dummy; hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (rp->post_write_delay == 0) { if (read_block(rp, &dummy, 1) < 0) { rig_debug(RIG_DEBUG_ERR, "%s: error reading ack\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: adjusting post_write_delay to avoid ack\n", __func__); rp->post_write_delay = 10; // arbitrary choice right now of max 100 cmds/sec return RIG_OK; // let it continue without checking for ack now } rig_debug(RIG_DEBUG_TRACE, "%s: ack value=0x%x\n", __func__, dummy); #if 0 // don't know of any reject codes -- none documented if (dummy != 0) { return -RIG_ERJCTED; } #endif } return RIG_OK; } /* * private helper function to send a private command sequence. * Must only be complete sequences. */ static int ft817_send_cmd(RIG *rig, int index) { hamlib_port_t *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Incomplete sequence\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); write_block(rp, ncmd[index].nseq, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* * The same for incomplete commands. */ static int ft817_send_icmd(RIG *rig, int index, const unsigned char *data) { unsigned char cmd[YAESU_CMD_LENGTH]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); if (ncmd[index].ncomp == 1) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Complete sequence\n", __func__); return -RIG_EINTERNAL; } cmd[YAESU_CMD_LENGTH - 1] = ncmd[index].nseq[YAESU_CMD_LENGTH - 1]; memcpy(cmd, data, YAESU_CMD_LENGTH - 1); write_block(RIGPORT(rig), cmd, YAESU_CMD_LENGTH); return ft817_read_ack(rig); } /* ---------------------------------------------------------------------- */ static int ft817_get_vfo(RIG *rig, vfo_t *vfo) { unsigned char c[2]; rig_debug(RIG_DEBUG_VERBOSE, "%s: called \n", __func__); if (ft817_read_eeprom(rig, 0x55, c) < 0) /* get vfo status */ { return -RIG_EPROTO; } if ((c[0] & 0x1) == 0) { *vfo = RIG_VFO_A; } else { *vfo = RIG_VFO_B; } return RIG_OK; } static int ft817_set_vfo(RIG *rig, vfo_t vfo) { vfo_t curvfo; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); retval = ft817_get_vfo(rig, &curvfo); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error get_vfo '%s'\n", __func__, rigerror(retval)); return retval; } if (curvfo == vfo) { return RIG_OK; } retval = ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_VFOAB); hl_usleep(50 * 1000); // can take a little while for vfo swap to happen -- otherwise we get errors trying to read eeprom to quickly return retval; } static int ft817_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { unsigned char data[YAESU_CMD_LENGTH - 1]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "ft817: requested freq = %"PRIfreq" Hz\n", freq); /* fill in the frequency */ /* changed to truncate the freq for gpredict compatibility */ to_bcd_be(data, (freq + 0) / 10, 8); rig_force_cache_timeout( &((struct ft817_priv_data *)STATE(rig)->priv)->fm_status_tv); retval = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_FREQ, data); hl_usleep(50 * 1000); // FT817 needs a little time after setting freq return retval; } static int ft817_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int index; /* index of sequence to send */ rig_debug(RIG_DEBUG_VERBOSE, "%s: generic mode = %s\n", __func__, rig_strrmode(mode)); switch (mode) { case RIG_MODE_AM: index = FT817_NATIVE_CAT_SET_MODE_AM; break; case RIG_MODE_CW: index = FT817_NATIVE_CAT_SET_MODE_CW; break; case RIG_MODE_USB: index = FT817_NATIVE_CAT_SET_MODE_USB; break; case RIG_MODE_LSB: index = FT817_NATIVE_CAT_SET_MODE_LSB; break; case RIG_MODE_RTTY: case RIG_MODE_PKTUSB: case RIG_MODE_PKTLSB: case RIG_MODE_PSK: case RIG_MODE_PSKR: { // first we get our dig mode to see if it needs changing unsigned char data[YAESU_CMD_LENGTH]; unsigned char digmode[2]; int ret = ft817_read_eeprom(rig, 0x65, digmode); if (ret != RIG_OK) { return ret; } rig_debug(RIG_DEBUG_VERBOSE, "%s: digmode=0x%02x%02x\n", __func__, digmode[0], digmode[1]); digmode[0] = digmode[0] >> 5; // shift 5 bits // check if we're already in the mode and return if so // the memory check was failing when in FM mode -- still showing digmode if (STATE(rig)->current_mode == mode) { if (digmode[0] == 0x00 && mode == RIG_MODE_RTTY) { return RIG_OK; } else if (digmode[0] == 0x01 && mode == RIG_MODE_PSKR) { return RIG_OK; } else if (digmode[0] == 0x02 && mode == RIG_MODE_PSK) { return RIG_OK; } else if (digmode[0] == 0x03 && mode == RIG_MODE_PKTLSB) { return RIG_OK; } else if (digmode[0] == 0x04 && mode == RIG_MODE_PKTUSB) { return RIG_OK; } } memcpy(data, ncmd[FT817_NATIVE_CAT_EEPROM_WRITE].nseq, YAESU_CMD_LENGTH); data[0] = 0x00; data[1] = 0x65; if (mode == RIG_MODE_RTTY) { data[2] = 0; } if (mode == RIG_MODE_PSKR) { data[2] = 1 << 5; } if (mode == RIG_MODE_PSK) { data[2] = 2 << 5; } if (mode == RIG_MODE_PKTLSB) { data[2] = 3 << 5; } if (mode == RIG_MODE_PKTUSB) { data[2] = 4 << 5; } // data[3] should be the original value at address 0x66, // i.e. "DCS INV" / digmode[1]. This is so we don't end // up overwriting this setting by mistake. data[3] = digmode[1]; index = FT817_NATIVE_CAT_SET_MODE_DIG; ret = ft817_send_cmd(rig, index); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: ft817_send_cmd: %s\n", __func__, rigerror(ret)); } index = FT817_NATIVE_CAT_EEPROM_WRITE; ret = ft817_send_icmd(rig, index, data); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: ft817_send_icmd: %s\n", __func__, rigerror(ret)); } return RIG_OK; } case RIG_MODE_FM: index = FT817_NATIVE_CAT_SET_MODE_FM; break; case RIG_MODE_CWR: index = FT817_NATIVE_CAT_SET_MODE_CWR; break; case RIG_MODE_PKTFM: index = FT817_NATIVE_CAT_SET_MODE_PKT; break; default: return -RIG_EINVAL; } /* just ignore passband */ /* if (width != RIG_PASSBAND_NORMAL) */ /* return -RIG_EINVAL; */ rig_force_cache_timeout( &((struct ft817_priv_data *)STATE(rig)->priv)->fm_status_tv); return ft817_send_cmd(rig, index); } static int ft817_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int index; ptt_t ptt_response = -1; int retries = RIGPORT(rig)->retry; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (ptt) { case RIG_PTT_ON: index = FT817_NATIVE_CAT_PTT_ON; break; case RIG_PTT_OFF: index = FT817_NATIVE_CAT_PTT_OFF; break; default: return -RIG_EINVAL; } do { int n; n = ft817_send_cmd(rig, index); if (n < 0 && n != -RIG_ERJCTED) { rig_debug(RIG_DEBUG_ERR, "%s: send ptt cmd failed\n", __func__); return n; } /* Read TX status it contains the PTT flag. * Use TX_STATUS instead of ft817_get_ptt to skip the cache. */ n = ft817_get_status(rig, FT817_NATIVE_CAT_GET_TX_STATUS); if (n < 0 && n != -RIG_ERJCTED) { rig_debug(RIG_DEBUG_ERR, "%s: get ptt cmd failed\n", __func__); return n; } /* Should be in cache now! But if above command was rejected * we will still try again here. */ n = ft817_get_ptt(rig, vfo, &ptt_response); if (n < 0 && n != -RIG_ERJCTED) { rig_debug(RIG_DEBUG_ERR, "%s: get ptt cmd failed\n", __func__); return n; } if (ptt_response != ptt) { rig_debug(RIG_DEBUG_TRACE, "%s: ptt not requested level, retry\n", __func__); hl_usleep(1000l * FT817_RETRY_DELAY); // Wait before next try. Helps with slower rigs cloning FT817 protocol (e.g. MCHF) } } while (ptt_response != ptt && retries-- > 0); if (retries >= 0) { return RIG_OK; } else { return -RIG_EIO; } } static int ft817_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_LOCK: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_LOCK_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_LOCK_OFF); } case RIG_FUNC_TONE: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_TSQL: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_CSQL: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } case RIG_FUNC_RIT: if (status) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } else { return ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } default: return -RIG_EINVAL; } } static int ft817_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; /* int n; */ rig_debug(RIG_DEBUG_VERBOSE, "ft817: set DCS code (%u)\n", code); if (code == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); /* FT-817 does not have the DCS_ENC_ON command, so we just set the tone here */ /* if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) */ /* return n; */ /* return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ENC_ON); */ return ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data); } static int ft817_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set DCS sql (%u)\n", code); if (code == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the DCS code - the rig doesn't support separate codes... */ to_bcd_be(data, code, 4); to_bcd_be(data + 2, code, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_DCS_CODE, data)) < 0) { return n; } return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_DCS_ON); } static int ft817_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set CTCSS tone (%.1f)\n", tone / 10.0); if (tone == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ENC_ON); } static int ft817_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set CTCSS sql (%.1f)\n", tone / 10.0); if (tone == 0) { return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_DCS_OFF); } /* fill in the CTCSS freq - the rig doesn't support separate tones... */ to_bcd_be(data, tone, 4); to_bcd_be(data + 2, tone, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_CTCSS_FREQ, data)) < 0) { return n; } return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_CTCSS_ON); } static int ft817_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { /* Note: this doesn't have effect unless FT817 is in FM mode although the command is accepted in any mode. */ rig_debug(RIG_DEBUG_VERBOSE, "ft817: set repeter shift = %i\n", shift); switch (shift) { case RIG_RPT_SHIFT_NONE: return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_SIMPLEX); case RIG_RPT_SHIFT_MINUS: return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_MINUS); case RIG_RPT_SHIFT_PLUS: return ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_RPT_SHIFT_PLUS); } return -RIG_EINVAL; } static int ft817_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { unsigned char data[YAESU_CMD_LENGTH - 1]; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set repeter offs = %li\n", offs); /* fill in the offset freq */ to_bcd_be(data, offs / 10, 8); return ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_RPT_OFFSET, data); } static int ft817_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { unsigned char data[YAESU_CMD_LENGTH - 1]; int n; rig_debug(RIG_DEBUG_VERBOSE, "ft817: set rit = %li)\n", rit); /* fill in the RIT freq */ data[0] = (rit < 0) ? 255 : 0; data[1] = 0; to_bcd_be(data + 2, labs(rit) / 10, 4); if ((n = ft817_send_icmd(rig, FT817_NATIVE_CAT_SET_CLAR_FREQ, data)) < 0) { return n; } /* the rig rejects if these are repeated - don't confuse user with retcode */ /* not used anymore, RIG_FUNC_RIT implemented if (rit == 0) { ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_OFF); } else { ft817_send_cmd(rig, FT817_NATIVE_CAT_CLAR_ON); } */ return RIG_OK; } int ft817_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (status) { case RIG_POWER_OFF: return ft817_send_cmd(rig, FT817_NATIVE_CAT_PWR_OFF); case RIG_POWER_ON: // send 5 bytes first, snooze a bit, then PWR_ON write_block(RIGPORT(rig), ncmd[FT817_NATIVE_CAT_PWR_WAKE].nseq, YAESU_CMD_LENGTH); hl_usleep(200 * 1000); write_block(RIGPORT(rig), ncmd[FT817_NATIVE_CAT_PWR_ON].nseq, YAESU_CMD_LENGTH); return RIG_OK; case RIG_POWER_STANDBY: default: return -RIG_EINVAL; } } static int ft817_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (op) { int n; case RIG_OP_TOGGLE: rig_force_cache_timeout(&((struct ft817_priv_data *) STATE(rig)->priv)->fm_status_tv); n = ft817_send_cmd(rig, FT817_NATIVE_CAT_SET_VFOAB); hl_usleep(100 * 1000); // rig needs a little time to do this return n; default: return -RIG_EINVAL; } } /* FIXME: this function silently ignores the vfo args and just turns split ON or OFF. */ static int ft817_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int index, n; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (split) { case RIG_SPLIT_ON: index = FT817_NATIVE_CAT_SPLIT_ON; break; case RIG_SPLIT_OFF: index = FT817_NATIVE_CAT_SPLIT_OFF; break; default: return -RIG_EINVAL; } n = ft817_send_cmd(rig, index); if (n < 0 && n != -RIG_ERJCTED) { return n; } CACHE(rig)->split = split; return RIG_OK; } /* FIXME: currently ignores mode and freq */ /* No documentation on how to interpret it but the max number of bars on the display is 10 and I measure: 8 bars = 5W 5 bars = 2.5W 3 bars = 1W 1 bar = 0.5W */ static int ft817_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *mwpower = (int)(power * 6000); return RIG_OK; } /* FIXME: currently ignores mode and freq */ static int ft817_mW2power(RIG *rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); *power = mwpower / 6000.0; return RIG_OK; } /* ---------------------------------------------------------------------- */ hamlib-4.6.2/rigs/yaesu/ft891.h0000644000175000017500000001167414752216205013033 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft891.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008 * * This shared library provides an API for communicating * via serial interface to an FT-950 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT891_H #define _FT891_H 1 #define FT891_VFO_ALL (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) /* Receiver caps */ #define FT891_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_FMN) #define FT891_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FT891_AM_RX_MODES (RIG_MODE_AM) #define FT891_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_FMN) #define FT891_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR) #define FT891_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FT891_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|\ RIG_MODE_FM|RIG_MODE_FMN) /* 100 W class */ #define FT891_AM_TX_MODES (RIG_MODE_AM) /* set 25W max */ #define FT891_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_STRENGTH|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NB|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) #define FT891_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_TUNER|RIG_FUNC_APF) #define FT891_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO) // borrowed from FT991 #define FT891_RFPOWER_METER_CAL \ { \ 7, \ { \ {0, 0.0f}, \ {10, 0.8f}, \ {50, 8.0f}, \ {100, 26.0f}, \ {150, 54.0f}, \ {200, 92.0f}, \ {250, 140.0f}, \ } \ } /* TBC */ #define FT891_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ } } /* * Other features (used by rig_caps) * */ #define FT891_ANTS (RIG_ANT_CURR) #define FT891_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT891_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FT891_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT891_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FT891_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FT891_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FT891_PACING_INTERVAL 5 // #define FT891_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-891 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ #define FT891_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FT891_POST_WRITE_DELAY 50 /* Reuse newcat_get_cmd */ extern int newcat_get_cmd(RIG *rig); #endif /* _FT891_H */ hamlib-4.6.2/rigs/yaesu/newcat.h0000644000175000017500000002273214752216205013436 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * and the Hamlib Group (hamlib-developer at lists.sourceforge.net) * * newcat.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Terry Embry 2008-2010 * * This shared library provides the backend API for communicating * via serial interface to any Yaesu radio using the new "CAT" * interface commands that are similar to the Kenwood command set. * * Models this code aims to support are FTDX-9000*, FT-2000, * FT-950, FT-450. Much testing remains. -N0NB * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _NEWCAT_H #define _NEWCAT_H 1 #include #include /* Handy constants */ #ifndef TRUE #define TRUE 1 #endif #define ON TRUE #ifndef FALSE #define FALSE 0 #endif #define OFF FALSE typedef char ncboolean; /* shared function version */ #define NEWCAT_VER "20241118" /* Hopefully large enough for future use, 128 chars plus '\0' */ #define NEWCAT_DATA_LEN 129 /* arbitrary value for now. 11 bits (8N2+1) == 2.2917 mS @ 4800 bps */ #define NEWCAT_DEFAULT_READ_TIMEOUT (NEWCAT_DATA_LEN * 5) #define NEWCAT_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .rit = 1, \ .xit = 1, \ .rptr_shift = 1, \ .ctcss_tone = 1,\ .ctcss_sql = 1,\ } #define YAESU_DEFAULT_VD_METER_200W_CAL \ { \ 3, \ { \ {0, 0.0f}, \ {196, 50.0f}, \ {255, 65.0f}, \ } \ } extern const struct confparams newcat_cfg_params[]; /* * Private caps for newcat rigs */ #define NEWCAT_ROOFING_FILTER_COUNT 12 struct newcat_roofing_filter { /* Index of the roofing filter in the ext level combo */ int index; /* Value to set the selected roofing filter, must be 0 for a get-only choice */ char set_value; /* Value returned by the rig for this roofing filter, must be 0 for a set-only choice */ char get_value; /* Width of the filter in Hz */ int width; /* 0 = Always available, 1 = Optional filter */ int optional; }; struct newcat_priv_caps { int roofing_filter_count; struct newcat_roofing_filter roofing_filters[NEWCAT_ROOFING_FILTER_COUNT]; }; /* * Private state for newcat rigs */ struct newcat_priv_data { char cmd_str[NEWCAT_DATA_LEN]; /* command string buffer */ char ret_data[NEWCAT_DATA_LEN]; /* returned data--max value, most are less */ int current_mem; /* private memory channel number */ int rig_id; /* rig id from CAT Command ID; */ int trn_state; /* AI state found at startup */ int fast_set_commands; /* do not check for ACK/NAK; needed for high throughput > 100 commands/s */ int width_frequency; /* found at startup */ struct timespec cache_start; char last_if_response[NEWCAT_DATA_LEN]; int poweron; /* to prevent powering on more than once */ int question_mark_response_means_rejected; /* the question mark response has multiple meanings */ char front_rear_status; /* e.g. FTDX5000 EX103 status */ int split_st_command_missing; /* is ST command gone? assume not until proven otherwise */ int band_index; }; /* * Functions considered to be Stable: * * Functions considered to be Beta: * * Functions considered to be Alpha: * newcat_set_freq * newcat_get_freq * newcat_set_vfo * newcat_get_vfo * newcat_get_rit * newcat_set_rit * newcat_get_xit * newcat_set_xit * power2mW * mW2power * newcat_get_ant * newcat_set_ant * newcat_get_ptt * Functions not yet implemented * most everything at this time. * * At this time, CAT documentation for the FT-450 can be obtained from * the Yaesu website at: http://www.yaesu.com/downloadFile.cfm?FileID=2600&FileCatID=158&FileName=FT%2D450%5FCAT%5FOperation%5FReference%5FBook.pdf&FileContentType=application%2Fpdf * */ /* * newcat function definitions. * */ int newcat_get_cmd(RIG *rig); int newcat_set_cmd(RIG *rig); int newcat_init(RIG *rig); int newcat_cleanup(RIG *rig); int newcat_open(RIG *rig); int newcat_close(RIG *rig); int newcat_set_conf(RIG *rig, hamlib_token_t token, const char *val); int newcat_get_conf(RIG *rig, hamlib_token_t token, char *val); int newcat_get_conf2(RIG *rig, hamlib_token_t token, char *val, int val_len); int newcat_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int newcat_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int newcat_set_vfo(RIG *rig, vfo_t vfo); int newcat_get_vfo(RIG *rig, vfo_t *vfo); int newcat_set_tx_vfo(RIG *rig, vfo_t tx_vfo); int newcat_get_tx_vfo(RIG *rig, vfo_t *tx_vfo); int newcat_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int newcat_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int newcat_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int newcat_get_ptt(RIG * rig, vfo_t vfo, ptt_t * ptt); int newcat_set_ant(RIG * rig, vfo_t vfo, ant_t ant, value_t option); int newcat_get_ant(RIG * rig, vfo_t vfo, ant_t dummy, value_t * option, ant_t * ant_curr, ant_t * ant_tx, ant_t *ant_rx); int newcat_set_level(RIG * rig, vfo_t vfo, setting_t level, value_t val); int newcat_get_level(RIG * rig, vfo_t vfo, setting_t level, value_t * val); int newcat_set_func(RIG * rig, vfo_t vfo, setting_t func, int status); int newcat_get_func(RIG * rig, vfo_t vfo, setting_t func, int *status); int newcat_set_parm(RIG * rig, setting_t parm, value_t val); int newcat_get_parm(RIG * rig, setting_t parm, value_t *val); int newcat_set_mem(RIG * rig, vfo_t vfo, int ch); int newcat_get_mem(RIG * rig, vfo_t vfo, int *ch); int newcat_vfo_op(RIG * rig, vfo_t vfo, vfo_op_t op); const char *newcat_get_info(RIG * rig); int newcat_get_rit(RIG * rig, vfo_t vfo, shortfreq_t * rit); int newcat_set_rit(RIG * rig, vfo_t vfo, shortfreq_t rit); int newcat_get_xit(RIG * rig, vfo_t vfo, shortfreq_t * xit); int newcat_set_xit(RIG * rig, vfo_t vfo, shortfreq_t xit); int newcat_get_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t *freq); int newcat_set_clarifier_frequency(RIG *rig, vfo_t vfo, shortfreq_t freq); int newcat_power2mW(RIG * rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); int newcat_mW2power(RIG * rig, float *power, unsigned int mwpower, freq_t freq, rmode_t mode); int newcat_set_split_vfo(RIG * rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int newcat_get_split_vfo(RIG * rig, vfo_t vfo, split_t * split, vfo_t *tx_vfo); int newcat_set_rptr_shift(RIG * rig, vfo_t vfo, rptr_shift_t rptr_shift); int newcat_get_rptr_shift(RIG * rig, vfo_t vfo, rptr_shift_t * rptr_shift); int newcat_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs); int newcat_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs); int newcat_set_ctcss_tone(RIG * rig, vfo_t vfo, tone_t tone); int newcat_get_ctcss_tone(RIG * rig, vfo_t vfo, tone_t * tone); int newcat_set_ctcss_sql(RIG * rig, vfo_t vfo, tone_t tone); int newcat_get_ctcss_sql(RIG * rig, vfo_t vfo, tone_t * tone); int newcat_set_powerstat(RIG * rig, powerstat_t status); int newcat_get_powerstat(RIG * rig, powerstat_t * status); int newcat_set_ts(RIG * rig, vfo_t vfo, shortfreq_t ts); int newcat_get_ts(RIG * rig, vfo_t vfo, shortfreq_t * ts); int newcat_set_trn(RIG * rig, int trn); int newcat_get_trn(RIG * rig, int *trn); int newcat_set_channel(RIG * rig, vfo_t vfo, const channel_t * chan); int newcat_get_channel(RIG * rig, vfo_t vfo, channel_t * chan, int read_only); rmode_t newcat_rmode(char mode); char newcat_modechar(rmode_t rmode); rmode_t newcat_rmode_width(RIG *rig, vfo_t vfo, char mode, pbwidth_t *width); int newcat_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int newcat_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int newcat_send_morse(RIG *rig, vfo_t vfo, const char *msg); int newcat_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int newcat_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int newcat_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int newcat_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); #define TOKEN_BACKEND(t) (t) #define TOK_ROOFING_FILTER TOKEN_BACKEND(100) #define TOK_KEYER TOKEN_BACKEND(101) #define TOK_APF_FREQ TOKEN_BACKEND(102) #define TOK_APF_WIDTH TOKEN_BACKEND(103) #define TOK_CONTOUR TOKEN_BACKEND(104) #define TOK_CONTOUR_FREQ TOKEN_BACKEND(105) #define TOK_CONTOUR_LEVEL TOKEN_BACKEND(106) #define TOK_CONTOUR_WIDTH TOKEN_BACKEND(107) #define TOK_MAXPOWER_HF TOKEN_BACKEND(108) #define TOK_MAXPOWER_6M TOKEN_BACKEND(109) #define TOK_MAXPOWER_4M TOKEN_BACKEND(110) #define TOK_MAXPOWER_AM TOKEN_BACKEND(111) #define TOK_MAXPOWER_VHF TOKEN_BACKEND(112) #define TOK_MAXPOWER_UHF TOKEN_BACKEND(113) #endif /* _NEWCAT_H */ hamlib-4.6.2/rigs/yaesu/ft5000.h0000644000175000017500000001266414752216205013076 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ft5000.h - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * * This shared library provides an API for communicating * via serial interface to an FT-DX5000 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT5000_H #define _FT5000_H 1 #define FTDX5000_VFO_ALL (RIG_VFO_MAIN|RIG_VFO_SUB|RIG_VFO_MEM) /* Receiver caps */ #define FTDX5000_ALL_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|\ RIG_MODE_FM|RIG_MODE_FMN) #define FTDX5000_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define FTDX5000_AM_RX_MODES (RIG_MODE_AM|RIG_MODE_AMN) #define FTDX5000_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) #define FTDX5000_CW_RTTY_PKT_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR|\ RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_CW|RIG_MODE_CWR) /* TRX caps */ #define FTDX5000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY| \ RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_FMN) /* 100 W class */ #define FTDX5000_AM_TX_MODES (RIG_MODE_AM|RIG_MODE_AMN) /* set 25W max */ /* TBC */ #define FTDX5000_LEVELS (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|\ RIG_LEVEL_ALC|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_RF|RIG_LEVEL_SQL|\ RIG_LEVEL_MICGAIN|RIG_LEVEL_IF|RIG_LEVEL_CWPITCH|\ RIG_LEVEL_KEYSPD|RIG_LEVEL_AF|RIG_LEVEL_AGC|\ RIG_LEVEL_METER|RIG_LEVEL_BKINDL|RIG_LEVEL_SQL|\ RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY|RIG_LEVEL_COMP|\ RIG_LEVEL_ANTIVOX|RIG_LEVEL_NR|RIG_LEVEL_NOTCHF|\ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|\ RIG_LEVEL_COMP_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_ID_METER|\ RIG_LEVEL_BAND_SELECT) /* TBC */ #define FTDX5000_FUNCS (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_LOCK|\ RIG_FUNC_MON|RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_NR|RIG_FUNC_VOX|\ RIG_FUNC_FBKIN|RIG_FUNC_COMP|RIG_FUNC_ANF|RIG_FUNC_MN|\ RIG_FUNC_RIT|RIG_FUNC_XIT|\ RIG_FUNC_TUNER|RIG_FUNC_APF) /* TBC */ #define FTDX5000_VFO_OPS (RIG_OP_TUNE|RIG_OP_CPY|RIG_OP_XCHG|\ RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|\ RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_TOGGLE) /* TBC */ #define FTDX5000_STR_CAL { 16, \ { \ { 0, -54 }, /* S0 */ \ { 12, -48 }, /* S1 */ \ { 27, -42 }, /* S2 */ \ { 40, -36 }, /* S3 */ \ { 55, -30 }, /* S4 */ \ { 65, -24 }, /* S5 */ \ { 80, -18 }, /* S6 */ \ { 95, -12 }, /* S7 */ \ { 112, -6 }, /* S8 */ \ { 130, 0 }, /* S9 */ \ { 150, 10 }, /* +10 */ \ { 172, 20 }, /* +20 */ \ { 190, 30 }, /* +30 */ \ { 220, 40 }, /* +40 */ \ { 240, 50 }, /* +50 */ \ { 255, 60 }, /* +60 */ \ }\ } // Values stolen from FLRig -- thanks to Dave W1HKJ #define FT5000_RFPOWER_METER_CAL \ { \ 14, \ { \ {55, 10.0f}, \ {75, 20.0f}, \ {101, 40.0f}, \ {125, 60.0f}, \ {144, 80.0f}, \ {161, 100.0f}, \ {177, 120.0f}, \ {190, 140.0f}, \ {202, 160.0f}, \ {215, 180.0f}, \ {225, 200.0f}, \ {237, 220.0f}, \ {242, 240.0f}, \ {255, 250.0f}, \ } \ } /* * Other features (used by rig_caps) * */ #define FTDX5000_TX_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) #define FTDX5000_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FTDX5000_OP_DATA_LENGTH 19 /* 0x10 P1 = 03 return size */ #define FTDX5000_VFO_DATA_LENGTH 18 /* 0x10 P1 = 03 return size -- A & B returned */ #define FTDX5000_MEM_CHNL_DATA_LENGTH 19 /* 0x10 P1 = 04, P4 = 0x01-0x20 return size */ #define FTDX5000_STATUS_FLAGS_LENGTH 5 /* 0xf7, 0xfa return size */ #define FTDX5000_ALL_DATA_LENGTH 649 /* 0x10 P1 = 00 return size */ /* Timing values in mS */ // #define FTDX5000_PACING_INTERVAL 5 // #define FTDX5000_PACING_DEFAULT_VALUE 0 /* Delay between bytes sent to FT-5000 * Should not exceed value set in CAT TOT menu (rig default is 10 mSec) */ // a 1ms delay was not working with microham and eltima ports #define FTDX5000_WRITE_DELAY 0 /* Delay sequential fast writes */ #define FTDX5000_POST_WRITE_DELAY 5 #endif /* _FT5000_H */ hamlib-4.6.2/rigs/yaesu/ftdx101.c0000644000175000017500000003346114752216205013340 00000000000000/* * hamlib - (C) Frank Singleton 2000 (javabear at users.sourceforge.net) * * ftdx101.c - (C) Nate Bargmann 2007 (n0nb at arrl.net) * (C) Stephane Fillod 2008-2010 * (C) Terry Embry 2008-2009 * (C) Mikael Nousiainen 2020 * * This shared library provides an API for communicating * via serial interface to an FTDX101(D/MP) using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "bandplan.h" #include "tones.h" #include "newcat.h" #include "yaesu.h" #include "ftdx101.h" const struct newcat_priv_caps ftdx101d_priv_caps = { .roofing_filter_count = 6, .roofing_filters = { // The index must match ext level combo index { .index = 0, .set_value = '0', .get_value = 0, .width = 12000, .optional = 0 }, { .index = 1, .set_value = '1', .get_value = '6', .width = 12000, .optional = 0 }, { .index = 2, .set_value = '2', .get_value = '7', .width = 3000, .optional = 0 }, { .index = 3, .set_value = '3', .get_value = '8', .width = 1200, .optional = 1 }, { .index = 4, .set_value = '4', .get_value = '9', .width = 600, .optional = 0 }, { .index = 5, .set_value = '5', .get_value = 'A', .width = 300, .optional = 1 }, } }; const struct confparams ftdx101d_ext_levels[] = { { TOK_ROOFING_FILTER, "ROOFINGFILTER", "Roofing filter", "Roofing filter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "AUTO", "12 kHz", "3 kHz", "1.2 kHz (optional)", "600 Hz", "300 Hz (optional)", NULL } } } }, { TOK_KEYER, "KEYER", "Keyer", "Keyer on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_APF_FREQ, "APF_FREQ", "APF frequency", "Audio peak filter frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = -250, .max = 250, .step = 10 } }, }, { TOK_APF_WIDTH, "APF_WIDTH", "APF width", "Audio peak filter width", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "Narrow", "Medium", "Wide", NULL } } }, }, { TOK_CONTOUR, "CONTOUR", "Contour", "Contour on/off", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_CONTOUR_FREQ, "CONTOUR_FREQ", "Contour frequency", "Contour frequency", NULL, RIG_CONF_NUMERIC, { .n = { .min = 10, .max = 3200, .step = 1 } }, }, { TOK_CONTOUR_LEVEL, "CONTOUR_LEVEL", "Contour level", "Contour level (dB)", NULL, RIG_CONF_NUMERIC, { .n = { .min = -40, .max = 20, .step = 1 } }, }, { TOK_CONTOUR_WIDTH, "CONTOUR_WIDTH", "Contour width", "Contour width", NULL, RIG_CONF_NUMERIC, { .n = { .min = 1, .max = 11, .step = 1 } }, }, { TOK_MAXPOWER_HF, "MAXPOWER_HF", "Maxpower HF", "Maxpower HF", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_6M, "MAXPOWER_6M", "Maxpower 6m", "Maxpower 6m", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 100, .step = 1 } }, }, { TOK_MAXPOWER_4M, "MAXPOWER_4M", "Maxpower 4m", "Maxpower 4m", NULL, RIG_CONF_INT, { .n = { .min = 5, .max = 50, .step = 1 } }, }, { TOK_MAXPOWER_AM, "MAXPOWER_AM", "Maxpower AM", "Maxpower AM", NULL, RIG_CONF_NUMERIC, { .n = { .min = 5, .max = 25, .step = 1 } }, }, { RIG_CONF_END, NULL, } }; int ftdx101d_ext_tokens[] = { TOK_ROOFING_FILTER, TOK_KEYER, TOK_APF_FREQ, TOK_APF_WIDTH, TOK_CONTOUR, TOK_CONTOUR_FREQ, TOK_CONTOUR_LEVEL, TOK_CONTOUR_WIDTH, TOK_MAXPOWER_HF, TOK_MAXPOWER_6M, TOK_MAXPOWER_4M, TOK_MAXPOWER_AM, TOK_BACKEND_NONE }; struct rig_caps ftdx101d_caps = { RIG_MODEL(RIG_MODEL_FTDX101D), .model_name = "FTDX-101D", .mfg_name = "Yaesu", .version = NEWCAT_VER ".21", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = FTDX101_WRITE_DELAY, .post_write_delay = FTDX101_POST_WRITE_DELAY, .timeout = 2000, .retry = 3, .has_get_func = FTDX101_FUNCS, .has_set_func = FTDX101_FUNCS, .has_get_level = FTDX101_LEVELS, .has_set_level = RIG_LEVEL_SET(FTDX101_LEVELS), .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_MICGAIN #define NO_LVL_SQL #define NO_LVL_MONITOR_GAIN #define NO_LVL_RFPOWER #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #include "level_gran_yaesu.h" #undef NO_LVL_MICGAIN #undef NO_LVL_SQL #undef NO_LVL_MONITOR_GAIN #undef NO_LVL_RFPOWER #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT [LVL_MICGAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_USB_AF] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = .0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 100.0f } }, }, .parm_gran = { [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BANDGEN,BANDMW,BANDUNUSED,BANDUNUSED,BANDUNUSED,BANDUNUSED,BAND4M"}} }, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(1200), .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_MEDIUM, RIG_AGC_SLOW, RIG_AGC_AUTO }, .vfo_ops = FTDX101_VFO_OPS, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE | RIG_TARGETABLE_FUNC | RIG_TARGETABLE_LEVEL | RIG_TARGETABLE_COMMON | RIG_TARGETABLE_ANT | RIG_TARGETABLE_ROOFING | RIG_TARGETABLE_TONE, .transceive = RIG_TRN_OFF, /* May enable later as the FTDX101 has an Auto Info command */ .bank_qty = 0, .chan_desc_sz = 0, .rfpower_meter_cal = FTDX101D_RFPOWER_METER_WATTS_CAL, .str_cal = FTDX101D_STR_CAL, .swr_cal = FTDX101D_SWR_CAL, .chan_list = { { 1, 99, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, { 100, 117, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // P1L-P9U PMS channels { 501, 510, RIG_MTYPE_MEM, NEWCAT_MEM_CAP }, // 5xx 5MHz band { 1, 5, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { /* General coverage + ham, ANT_5 is RX only antenna */ {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "USA"}, RIG_FRNG_END, }, .tx_range_list1 = { /* the 101DX is 100W and the MP is 200W */ FRQ_RNG_HF(1, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(1, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(1, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(1, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(30), MHz(60), FTDX101_ALL_RX_MODES, -1, -1, FTDX101_VFO_ALL, FTDX101_TX_ANTS, "EUR"}, RIG_FRNG_END, }, .tx_range_list2 = { FRQ_RNG_HF(2, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_HF(2, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_6m(2, FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_6m(2, FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ FRQ_RNG_4m_REGION2(FTDX101_OTHER_TX_MODES, W(5), W(100), FTDX101_VFO_ALL, FTDX101_TX_ANTS), FRQ_RNG_4m_REGION2(FTDX101_AM_TX_MODES, W(5), W(25), FTDX101_VFO_ALL, FTDX101_TX_ANTS), /* AM class */ RIG_FRNG_END, }, .tuning_steps = { {FTDX101_SSB_CW_RX_MODES, Hz(10)}, /* Normal */ {FTDX101_SSB_CW_RX_MODES, Hz(100)}, /* Fast */ {FTDX101_AM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_AM_RX_MODES, kHz(1)}, /* Fast */ {FTDX101_FM_RX_MODES, Hz(100)}, /* Normal */ {FTDX101_FM_RX_MODES, kHz(1)}, /* Fast */ RIG_TS_END, }, /* mode/filter list, remember that order matters! */ .filters = { {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(600)}, /* Normal CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(300)}, /* Narrow CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(2400)}, /* Wide CW, RTTY, PKT/USER */ {FTDX101_CW_RTTY_PKT_RX_MODES, Hz(1200)}, /* Normal CW, RTTY, PKT/USER */ {RIG_MODE_SSB, Hz(2400)}, /* Normal SSB */ {RIG_MODE_SSB, Hz(1800)}, /* Narrow SSB */ {RIG_MODE_SSB, Hz(3000)}, /* Wide SSB */ {RIG_MODE_AM, Hz(9000)}, /* Normal AM */ {RIG_MODE_AMN, Hz(6000)}, /* Narrow AM */ {RIG_MODE_FM | RIG_MODE_PKTFM, Hz(16000)}, /* Normal FM */ {RIG_MODE_FMN | RIG_MODE_PKTFMN, Hz(9000)}, /* Narrow FM */ {FTDX101_CW_RTTY_PKT_RX_MODES | RIG_MODE_SSB, RIG_FLT_ANY}, RIG_FLT_END, }, .ext_tokens = ftdx101d_ext_tokens, .extlevels = ftdx101d_ext_levels, .priv = &ftdx101d_priv_caps, .rig_init = newcat_init, .rig_cleanup = newcat_cleanup, .rig_open = newcat_open, /* port opened */ .rig_close = newcat_close, /* port closed */ .cfgparams = newcat_cfg_params, .set_conf = newcat_set_conf, .get_conf2 = newcat_get_conf2, .set_freq = newcat_set_freq, .get_freq = newcat_get_freq, .set_mode = newcat_set_mode, .get_mode = newcat_get_mode, .set_vfo = newcat_set_vfo, .get_vfo = newcat_get_vfo, .set_ptt = newcat_set_ptt, .get_ptt = newcat_get_ptt, .set_split_vfo = newcat_set_split_vfo, .get_split_vfo = newcat_get_split_vfo, .set_rit = newcat_set_rit, .get_rit = newcat_get_rit, .set_xit = newcat_set_xit, .get_xit = newcat_get_xit, .set_ant = newcat_set_ant, .get_ant = newcat_get_ant, .get_func = newcat_get_func, .set_func = newcat_set_func, .get_level = newcat_get_level, .set_level = newcat_set_level, .get_mem = newcat_get_mem, .set_mem = newcat_set_mem, .vfo_op = newcat_vfo_op, .get_info = newcat_get_info, .power2mW = newcat_power2mW, .mW2power = newcat_mW2power, .set_rptr_shift = newcat_set_rptr_shift, .get_rptr_shift = newcat_get_rptr_shift, .set_rptr_offs = newcat_set_rptr_offs, .get_rptr_offs = newcat_get_rptr_offs, .set_ctcss_tone = newcat_set_ctcss_tone, .get_ctcss_tone = newcat_get_ctcss_tone, .set_ctcss_sql = newcat_set_ctcss_sql, .get_ctcss_sql = newcat_get_ctcss_sql, .set_powerstat = newcat_set_powerstat, .get_powerstat = newcat_get_powerstat, .get_ts = newcat_get_ts, .set_ts = newcat_set_ts, .set_trn = newcat_set_trn, .get_trn = newcat_get_trn, .set_channel = newcat_set_channel, .get_channel = newcat_get_channel, .set_ext_level = newcat_set_ext_level, .get_ext_level = newcat_get_ext_level, .send_morse = newcat_send_morse, .wait_morse = rig_wait_morse, .set_clock = newcat_set_clock, .get_clock = newcat_get_clock, .scan = newcat_scan, .morse_qsize = 50, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/yaesu/ft747.h0000644000175000017500000000466514752216205013035 00000000000000/* * hamlib - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * (C) Stephane Fillod 2000-2010 * * ft747.h - (C) Frank Singleton 2000 (vk3fcs@@ix.netcom.com) * This shared library provides an API for communicating * via serial interface to an FT-747GX using the "CAT" interface * box (FIF-232C) or similar (max232 + some capacitors :-) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT747_H #define _FT747_H 1 /* * According to manual, the UPDATE data length should be 345 * but some rigs are short by one byte. */ #define FT747_STATUS_UPDATE_DATA_LENGTH 344 #define FT747_PACING_DEFAULT_VALUE 0 #define FT747_WRITE_DELAY 5 /* manual say 50 ms, but it doesn't work though */ /* Sequential fast writes confuse my FT747 without this delay */ /* Node Red combined "F 028074000 M USB 0" needed 10ms */ #define FT747_POST_WRITE_DELAY 10 /* * 8N2 and 1 start bit = 11 bits at 4800 bps => effective byte rate = 1 byte in 2.2917 msec * => 345 bytes in 790 msec * * delay for 1 byte = 2.2917 + (pace_interval * 5) * * pace_interval time to read 345 bytes * ------------ ---------------------- * * 0 790 msec * 1 2515 msec * 2 4240 msec * 255 441 sec => 7 min 21 seconds * */ /* * The time the status block is cached (in millisec). * This optimises the common case of doing eg. rig_get_freq() and * rig_get_mode() in a row. * * The timeout is set to at least the time to transfer the block (790ms) * plus post write delay, plus some margin as get_freq was taking > 1000ms */ #define FT747_CACHE_TIMEOUT 1500 #endif /* _FT747_H */ hamlib-4.6.2/rigs/yaesu/ft990.h0000755000175000017500000002221014752216205013022 00000000000000/* * hamlib - (C) Stephane Fillod 2002, 2003 (fillods at users.sourceforge.net) * * ft990.h - (C) Berndt Josef Wulf (wulf at ping.net.au) * * This shared library provides an API for communicating * via serial interface to an FT-990 using the "CAT" interface * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FT990_H #define _FT990_H 1 // Global Definitions #define TRUE 1 #define FALSE 0 #define ON TRUE #define OFF FALSE /* RX caps */ #define FT990_ALL_RX_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) #define FT990_SSB_CW_RX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_PKTLSB) #define FT990_RTTY_RX_MODES (RIG_MODE_RTTY|RIG_MODE_RTTYR) #define FT990_AM_RX_MODES (RIG_MODE_AM) #define FT990_FM_RX_MODES (RIG_MODE_FM|RIG_MODE_PKTFM) /* TX caps */ #define FT990_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_PKTFM|RIG_MODE_PKTLSB) /* 100 W class */ #define FT990_AM_TX_MODES (RIG_MODE_AM ) /* set 25W max */ #define FT990_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_SBKIN|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TUNER) /* fix */ /* Other features */ #define FT990_VFO_ALL (RIG_VFO_A|RIG_VFO_B) #define FT990_ANTS 0 #define FT990_VFO_OPS (RIG_OP_TO_VFO|RIG_OP_FROM_VFO|RIG_OP_CPY|RIG_OP_UP|RIG_OP_DOWN) /* Returned data length in bytes */ #define FT990_ALL_DATA_LENGTH 1508 /* 0x10 P1 = 00 return size */ #define FT990_MEM_CHNL_LENGTH 1 /* 0x10 P1 = 01 return size */ #define FT990_OP_DATA_LENGTH 32 /* 0x10 P1 = 02 return size */ #define FT990_VFO_DATA_LENGTH 32 /* 0x10 P1 = 03 return size -- A & B returned */ #define FT990_MEM_CHNL_DATA_LENGTH 16 /* 0x10 P1 = 04, P4 = 0x00-0x59 return size */ #define FT990_READ_METER_LENGTH 5 /* 0xf7 return size */ #define FT990_STATUS_FLAGS_LENGTH 5 /* 0xfa return size */ /* BCD coded frequency length */ #define FT990_BCD_DIAL 8 #define FT990_BCD_RIT 3 #define FT990_BCD_RPTR_OFFSET 6 /* Timing values in mS */ #define FT990_PACING_INTERVAL 5 #define FT990_PACING_DEFAULT_VALUE 0 #define FT990_WRITE_DELAY 50 /* Delay sequential fast writes */ #define FT990_POST_WRITE_DELAY 5 /* Rough safe value for default timeout */ #define FT990_DEFAULT_READ_TIMEOUT FT990_ALL_DATA_LENGTH * ( 5 + (FT990_PACING_INTERVAL * FT990_PACING_DEFAULT_VALUE)) /* * The definitions below are copied from the kft990 * project and are hereby made available to the * hamlib project. [BJW] */ // OpCode Declarations #define FT990_CMD_SPLIT 0x01 #define FT990_CMD_RECALLMEM 0x02 #define FT990_CMD_VFO2MEM 0x03 #define FT990_CMD_LOCK 0x04 #define FT990_CMD_SELVFOAB 0x05 #define FT990_CMD_MEM2VFO 0x06 #define FT990_CMD_UP 0x07 #define FT990_CMD_DOWN 0x08 #define FT990_CMD_CLARIFIER 0x09 #define FT990_CMD_SETVFOA 0x0a #define FT990_CMD_SELOPMODE 0x0c #define FT990_CMD_PACING 0x0e #define FT990_CMD_PTT 0x0f #define FT990_CMD_UPDATE 0x10 #define FT990_CMD_TUNER 0x81 #define FT990_CMD_START 0x82 #define FT990_CMD_RPT 0x84 #define FT990_CMD_VFOA2B 0x85 #define FT990_CMD_BW 0x8c #define FT990_CMD_MEMSCANSKIP 0x8d #define FT990_CMD_STEPVFO 0x8e #define FT990_CMD_RDMETER 0xf7 #define FT990_CMD_DIMLEVEL 0xf8 #define FT990_CMD_RPTROFFSET 0xf9 #define FT990_CMD_RDFLAGS 0xfa // Bandwidth Filter #define FT990_BW_F2400 0x00 #define FT990_BW_F2000 0x01 #define FT990_BW_F500 0x02 #define FT990_BW_F250 0x03 #define FT990_BW_F6000 0x04 #define FT990_BW_FMPKTRTTY 0x80 // Operating Mode Status #define FT990_MODE_LSB 0x00 #define FT990_MODE_USB 0x01 #define FT990_MODE_CW 0x02 #define FT990_MODE_AM 0x03 #define FT990_MODE_FM 0x04 #define FT990_MODE_RTTY 0x05 #define FT990_MODE_PKT 0x06 // Operation Mode Selection #define FT990_OP_MODE_LSB 0x00 #define FT990_OP_MODE_USB 0x01 #define FT990_OP_MODE_CW2400 0x02 #define FT990_OP_MODE_CW500 0x03 #define FT990_OP_MODE_AM6000 0x04 #define FT990_OP_MODE_AM2400 0x05 #define FT990_OP_MODE_FM 0x06 #define FT990_OP_MODE_RTTYLSB 0x08 #define FT990_OP_MODE_RTTYUSB 0x09 #define FT990_OP_MODE_PKTLSB 0x0a #define FT990_OP_MODE_PKTFM 0x0b // Clarifier Operation #define FT990_CLAR_TX_EN 0x01 #define FT990_CLAR_RX_EN 0x02 #define FT990_CLAR_RX_OFF 0x00 #define FT990_CLAR_RX_ON 0x01 #define FT990_CLAR_TX_OFF 0x80 #define FT990_CLAR_TX_ON 0x81 #define FT990_CLAR_CLEAR 0xff #define FT990_CLAR_TUNE_UP 0x00 #define FT990_CLAR_TUNE_DOWN 0xff // Repeater Shift Enable #define FT990_RPT_POS_EN 0x04 #define FT990_RPT_NEG_EN 0x08 #define FT990_RPT_MASK 0x0C // Status Flag 1 Masks #define FT990_SF_SPLIT 0x01 #define FT990_SF_VFOB 0x02 #define FT990_SF_FAST 0x04 #define FT990_SF_CAT 0x08 #define FT990_SF_TUNING 0x10 #define FT990_SF_KEY_ENTRY 0x20 #define FT990_SF_MEM_EMPTY 0x40 #define FT990_SF_XMIT 0x80 // Status Flag 2 Masks #define FT990_SF_MEM_SCAN_PAUSE 0x01 #define FT990_SF_MEM_CHECK 0x02 #define FT990_SF_MEM_SCAN 0x04 #define FT990_SF_LOCKED 0x08 #define FT990_SF_MTUNE 0x10 #define FT990_SF_VFO 0x20 #define FT990_SF_MEM 0x40 #define FT990_SF_GEN 0x80 // Status Flag 3 Masks #define FT990_SF_PTT 0x01 #define FT990_SF_TX_INHIBIT 0x02 #define FT990_SF_KEY_TIMER 0x04 #define FT990_SF_MEM_TIMER 0x08 #define FT990_SF_PTT_INHIBIT 0x10 #define FT990_SF_XMIT_MON 0x20 #define FT990_SF_TUNER_ON 0x40 #define FT990_SF_SIDETONE 0x80 #define FT990_EMPTY_MEM 0x80 #define FT990_AMFILTER2400 0x80 // Flags Byte 1 typedef struct _ft990_flags1_t { unsigned split: 1; unsigned vfob: 1; unsigned fast: 1; unsigned cat: 1; unsigned tuning: 1; unsigned keyentry: 1; unsigned memempty: 1; unsigned xmit: 1; } ft990_flags1_t; // Flags Byte 2 typedef struct _ft990_flags2_t { unsigned memscanpause:1; unsigned memcheck: 1; unsigned memscan: 1; unsigned locked: 1; unsigned mtune: 1; unsigned vfo: 1; unsigned mem: 1; unsigned gen: 1; } ft990_flags2_t; // Flags Byte 3 typedef struct _ft990_status3_t { unsigned ptt: 1; unsigned txinhibit: 1; unsigned keytimer: 1; unsigned memtimer: 1; unsigned pttinhibit: 1; unsigned xmitmon: 1; unsigned tuneron: 1; unsigned sidetone: 1; } ft990_flags3_t; typedef union _ft990_flags1_u { ft990_flags1_t bits; unsigned char byte; } ft990_flags1_u; typedef union _ft990_flags2_u { ft990_flags2_t bits; unsigned char byte; } ft990_flags2_u; typedef union _ft990_flags3_u { ft990_flags3_t bits; unsigned char byte; } ft990_flags3_u; typedef struct _ft990_status_data_t { ft990_flags1_u flags1; ft990_flags2_u flags2; ft990_flags3_u flags3; unsigned char id1; unsigned char id2; } ft990_status_data_t; typedef struct _ft990_meter_data_t { unsigned char mdata1; unsigned char mdata2; unsigned char mdata3; unsigned char mdata4; unsigned char id1; } ft990_meter_data_t; typedef struct _ft990_op_data_t { unsigned char bpf; unsigned char basefreq[3]; unsigned char status; unsigned char coffset[2]; unsigned char mode; unsigned char filter; unsigned char lastssbfilter; unsigned char lastcwfilter; unsigned char lastrttyfilter; unsigned char lastpktfilter; unsigned char lastclariferstate; unsigned char skipscanamfilter; unsigned char amfm100; } ft990_op_data_t; // Update Data Structure typedef struct _ft990_update_data_t { unsigned char flag1; unsigned char flag2; unsigned char flag3; unsigned char channelnumber; ft990_op_data_t current_front; ft990_op_data_t current_rear; ft990_op_data_t vfoa; ft990_op_data_t vfob; ft990_op_data_t channel[90]; } ft990_update_data_t; // Command Structure typedef struct _ft990_command_t { unsigned char data[4]; unsigned char opcode; } ft990_command_t; #endif /* _FT990_H */ hamlib-4.6.2/rigs/kenwood/0000755000175000017500000000000014752216243012400 500000000000000hamlib-4.6.2/rigs/kenwood/thd7.c0000644000175000017500000001356114752216205013336 00000000000000/* * Hamlib Kenwood backend - TH-D7 description * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #include "th.h" #if 1 #define RIG_ASSERT(x) if (!(x)) { rig_debug(RIG_DEBUG_ERR, "Assertion failed on line %i\n",__LINE__); abort(); } #else #define RIG_ASSERT(x) #endif #define THD7_MODES (RIG_MODE_FM|RIG_MODE_AM) #define THD7_MODES_TX (RIG_MODE_FM) #define THD7_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_AIP| \ RIG_FUNC_MON| \ RIG_FUNC_SQL| \ RIG_FUNC_TONE| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO) #define THD7_LEVEL_ALL (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SQL| \ RIG_LEVEL_AF| \ RIG_LEVEL_RF|\ RIG_LEVEL_MICGAIN) #define THD7_PARMS (RIG_PARM_BACKLIGHT) #define THD7_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) /* * TODO: Band A & B */ #define THD7_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t td7_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_AM, }; static struct kenwood_priv_caps thd7_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = td7_mode_table, }; /* * th-d7a rig capabilities. * * http://www.qsl.net/ta1dx/kenwood/thd7kom.htm */ struct rig_caps thd7a_caps = { RIG_MODEL(RIG_MODEL_THD7A), .model_name = "TH-D7A", .mfg_name = "Kenwood", .version = TH_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD | RIG_FLAG_APRS | RIG_FLAG_TNC | RIG_FLAG_DXCLUSTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THD7_FUNC_ALL, .has_set_func = THD7_FUNC_ALL, .has_get_level = THD7_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THD7_LEVEL_ALL), .has_get_parm = THD7_PARMS, .has_set_parm = THD7_PARMS, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = { [PARM_BACKLIGHT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f}}, }, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THD7_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, .chan_list = { { 1, 199, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* normal MEM */ { 200, 219, RIG_MTYPE_EDGE, {TH_CHANNEL_CAPS}}, /* U/L MEM */ { 221, 222, RIG_MTYPE_CALL, {TH_CHANNEL_CAPS}}, /* Call 0/1 */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(144), MHz(148), THD7_MODES, -1, -1, THD7_VFO}, {MHz(430), MHz(440), THD7_MODES, -1, -1, THD7_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), THD7_MODES_TX, W(5.5), W(5.5), THD7_VFO}, {MHz(430), MHz(440), THD7_MODES_TX, W(5.5), W(5.5), THD7_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {THD7_MODES, kHz(5)}, {THD7_MODES, kHz(6.25)}, {THD7_MODES, kHz(10)}, {THD7_MODES, kHz(12.5)}, {THD7_MODES, kHz(15)}, {THD7_MODES, kHz(20)}, {THD7_MODES, kHz(25)}, {THD7_MODES, kHz(30)}, {THD7_MODES, kHz(50)}, {THD7_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(14)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .priv = (void *)& thd7_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = th_set_freq, .get_freq = th_get_freq, .set_mode = th_set_mode, .get_mode = th_get_mode, .set_vfo = th_set_vfo, .get_vfo = th_get_vfo, .set_ctcss_tone = th_set_ctcss_tone, .get_ctcss_tone = th_get_ctcss_tone, .set_ctcss_sql = th_set_ctcss_sql, .get_ctcss_sql = th_get_ctcss_sql, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_trn = th_set_trn, .get_trn = th_get_trn, .get_func = th_get_func, .get_level = th_get_level, .get_parm = th_get_parm, .get_info = th_get_info, .get_dcd = th_get_dcd, .decode_event = th_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* end of file */ hamlib-4.6.2/rigs/kenwood/ts950.c0000644000175000017500000003042014752216205013345 00000000000000/* * Hamlib Kenwood backend - TS950 description * Copyright (c) 2002-2012 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Edited by Martin Ewing AA6E, March, 2012 * The '950 has a relatively small command set. */ #include #include #include "kenwood.h" #define TS950_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS950_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS950_AM_TX_MODES RIG_MODE_AM #define TS950_VFO (RIG_VFO_A|RIG_VFO_B) #define TS950_GET_LEVEL (RIG_LEVEL_RAWSTR) // STR_CAL borrowed from TS850 #define TS950_STR_CAL { 4, \ { \ { 0, -54 }, \ { 15, 0 }, \ { 22,30 }, \ { 30, 66}, \ } } #define cmd_trm(rig) ((struct kenwood_priv_caps *)(rig)->caps->priv)->cmdtrm static struct kenwood_priv_caps ts950_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * This backend should work with all models in the TS-950 series (TS-950S, SDX, etc.) * There are minor differences between the SDX and other models, but they are * in commands not implemented here. * * Reference: TS-950 series External Control Instruction Manual (1992) */ struct rig_caps ts950s_caps = { RIG_MODEL(RIG_MODEL_TS950S), .model_name = "TS-950S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 600, // this rig takes over 250ms to respond an IF command .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = TS950_GET_LEVEL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* atten settings are not available in CAT interface */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // No AGC levels .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS950_ALL_MODES, -1, -1, TS950_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(3500), MHz(4) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(7), kHz(7300), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(7), kHz(7300), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(10100), kHz(10150), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(10100), kHz(10150), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(14), kHz(14350), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(14), kHz(14350), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(18068), kHz(18168), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(18068), kHz(18168), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(21), kHz(21450), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(21), kHz(21450), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(24890), kHz(24990), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(24890), kHz(24990), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(28), kHz(29700), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(28), kHz(29700), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS950_ALL_MODES, 50}, {TS950_ALL_MODES, 100}, {TS950_ALL_MODES, kHz(1)}, {TS950_ALL_MODES, kHz(5)}, {TS950_ALL_MODES, kHz(9)}, {TS950_ALL_MODES, kHz(10)}, {TS950_ALL_MODES, 12500}, {TS950_ALL_MODES, kHz(20)}, {TS950_ALL_MODES, kHz(25)}, {TS950_ALL_MODES, kHz(100)}, {TS950_ALL_MODES, MHz(1)}, {TS950_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .str_cal = TS950_STR_CAL, .priv = (void *)& ts950_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, /* Things that the '950 doesn't do ... * .set_func = kenwood_set_func, * .get_func = kenwood_get_func, * .set_level = kenwood_set_level, */ .get_level = kenwood_get_level, /* * .send_morse = kenwood_send_morse, */ .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps ts950sdx_caps = { RIG_MODEL(RIG_MODEL_TS950SDX), .model_name = "TS-950SDX", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, .timeout = 600, // this rig takes over 250ms to respond an IF command .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = TS950_GET_LEVEL, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* atten settings are not available in CAT interface */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS950_ALL_MODES, -1, -1, TS950_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(3500), MHz(4) - 1, TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(7), kHz(7300), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(7), kHz(7300), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(10100), kHz(10150), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(10100), kHz(10150), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(14), kHz(14350), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(14), kHz(14350), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(18068), kHz(18168), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(18068), kHz(18168), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(21), kHz(21450), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(21), kHz(21450), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {kHz(24890), kHz(24990), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {kHz(24890), kHz(24990), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, {MHz(28), kHz(29700), TS950_OTHER_TX_MODES, 5000, W(150), TS950_VFO}, {MHz(28), kHz(29700), TS950_AM_TX_MODES, 2000, W(40), TS950_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS950_ALL_MODES, 50}, {TS950_ALL_MODES, 100}, {TS950_ALL_MODES, kHz(1)}, {TS950_ALL_MODES, kHz(5)}, {TS950_ALL_MODES, kHz(9)}, {TS950_ALL_MODES, kHz(10)}, {TS950_ALL_MODES, 12500}, {TS950_ALL_MODES, kHz(20)}, {TS950_ALL_MODES, kHz(25)}, {TS950_ALL_MODES, kHz(100)}, {TS950_ALL_MODES, MHz(1)}, {TS950_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .str_cal = TS950_STR_CAL, .priv = (void *)& ts950_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, /* Things that the '950 doesn't do ... * .set_func = kenwood_set_func, * .get_func = kenwood_get_func, * .set_level = kenwood_set_level, */ .get_level = kenwood_get_level, /* * .send_morse = kenwood_send_morse, */ .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/ts890s.c0000644000175000017500000005552214752216205013545 00000000000000/* * Hamlib Kenwood backend - TS-890S description * Copyright (c) 2000-2004 by Stephane Fillod and Juergen Rinas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "cal.h" #include "misc.h" #define TS890_VFO (RIG_VFO_A|RIG_VFO_B) #define TS890_ALL_MODES (RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_RTTY|RIG_MODE_CWR|RIG_MODE_RTTYR|RIG_MODE_PSK|RIG_MODE_PSKR|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_PKTFM|RIG_MODE_PKTAM) #define TS890_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS890_AM_TX_MODES RIG_MODE_AM #define TS890_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH|RIG_LEVEL_ATT|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT) #define TS890_LEVEL_GET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_KEYSPD|RIG_LEVEL_ALC|RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ID_METER|RIG_LEVEL_VD_METER|RIG_LEVEL_TEMP_METER|RIG_LEVEL_CWPITCH|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_ATT|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT|RIG_LEVEL_RFPOWER_METER_WATTS) #define TS890_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_NB2|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER|RIG_FUNC_SEND_MORSE|RIG_FUNC_TONE|RIG_FUNC_TSQL) #define TS890_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) static int kenwood_ts890_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16], *command_string; int kenwood_val, retval; gran_t *level_info; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = check_level_param(rig, level, val, &level_info); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_AGC: /* hamlib argument is int, possible values rig.h:enum agc_level_e */ /* possible values for TS890 0(=off), 1(=slow), 2(=mid), 3(=fast), 4(=off/Last) */ rig_debug(RIG_DEBUG_VERBOSE, "%s TS890S RIG_LEVEL_AGC\n", __func__); kenwood_val = -1; /* Flag invalid value */ for (int j = 0; j < rig->caps->agc_level_count; j++) { if (val.i == rig->caps->agc_levels[j]) { kenwood_val = j; break; } } if (kenwood_val < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value:%d\n", __func__, val.i); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GC%d", kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); /* Odd man out */ case RIG_LEVEL_RF: command_string = "RG%03d"; break; case RIG_LEVEL_SQL: command_string = "SQ%03d"; break; case RIG_LEVEL_USB_AF: command_string = "EX00708 %03d"; break; case RIG_LEVEL_USB_AF_INPUT: command_string = "EX00706 %03d"; break; default: return kenwood_set_level(rig, vfo, level, val); } //TODO: Add use of RIG_LEVEL_IS_FLOAT() if need to handle int level kenwood_val = val.f / level_info->step.f + 0.5; SNPRINTF(levelbuf, sizeof(levelbuf), command_string, kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); } static int kenwood_ts890_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len, ack_len_expected, len; int levelint; int retval; char *command_string; gran_t *level_info; level_info = &rig->caps->level_gran[rig_setting2idx(level)]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { // TODO: This doesn't appear in TS890_LEVEL_GET - should it? case RIG_LEVEL_VOXDELAY: retval = kenwood_safe_transaction(rig, "VD0", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(ackbuf + 3, "%d", &levelint); val->i = levelint * 3 / 2; /* 150ms units converted to 100ms units */ return RIG_OK; case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = levelint / (float) 255; return RIG_OK; case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ", ackbuf, sizeof(ackbuf)); ack_len_expected = 5; if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint * level_info->step.f; return RIG_OK; case RIG_LEVEL_AGC: retval = kenwood_safe_transaction(rig, "GC", ackbuf, sizeof(ackbuf), 3); if (RIG_OK != retval) { return retval; } levelint = ackbuf[2] - '0'; /* atoi */ if (levelint < 0 || levelint >= rig->caps->agc_level_count) { rig_debug(RIG_DEBUG_ERR, "%s: unknown agc value: %s\n", __func__, ackbuf); return -RIG_EPROTO; } val->i = rig->caps->agc_levels[levelint]; return RIG_OK; case RIG_LEVEL_ALC: retval = get_kenwood_meter_reading(rig, '1', &levelint); if (retval != RIG_OK) { return retval; } val->f = (float)levelint / 35.0; /* Half scale [0,35] -> [0.0,1.0] */ return RIG_OK; case RIG_LEVEL_SWR: retval = get_kenwood_meter_reading(rig, '2', &levelint); if (retval != RIG_OK) { return retval; } if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(levelint, &rig->caps->swr_cal); } else { /* Linear approximations of a very non-linear function */ if (levelint < 12) { val->f = 1.0 + (float)levelint / 22.0; } else if (levelint < 24) { val->f = 1.5 + (float)(levelint - 11) / 24.0; } else if (levelint < 36) { val->f = 2.0 + (float)(levelint - 23) / 12.0; } else { val->f = 3.0 + (float)(levelint - 35) / 6.0; } } return RIG_OK; case RIG_LEVEL_COMP_METER: retval = get_kenwood_meter_reading(rig, '3', &levelint); if (retval != RIG_OK) { return retval; } if (levelint < 21) { val->f = (float)levelint / 2.0; } /* db */ else if (levelint < 51) { val->f = 10.0 + (float)(levelint - 20) / 3.0; } else { val->f = 20.0 + (float)(levelint - 50) / 4.0; } return RIG_OK; case RIG_LEVEL_ID_METER: retval = get_kenwood_meter_reading(rig, '4', &levelint); if (retval != RIG_OK) { return retval; } val->f = (20.0 * (float)levelint) / 70.0; /* amperes */ return RIG_OK; case RIG_LEVEL_VD_METER: retval = get_kenwood_meter_reading(rig, '5', &levelint); if (retval != RIG_OK) { return retval; } val->f = (15.0 * (float)levelint) / 65.0; /* volts */ return RIG_OK; case RIG_LEVEL_TEMP_METER: #if 0 retval = get_kenwood_meter_reading(rig, '6', &levelint); if (retval != RIG_OK) { return retval; } #endif return -RIG_ENIMPL; case RIG_LEVEL_STRENGTH: case RIG_LEVEL_RFPOWER_METER_WATTS: { cal_table_float_t *table; ptt_t ptt = RIG_PTT_OFF; /* Values taken from the TS-890S In-Depth Manual (IDM), p. 8 * 0.03 - 21.5 MHz, Preamp 1 */ /* Meter Type 1 - Kenwood specific, factory default */ static cal_table_float_t meter_type1 = { 9, { { 0, -28.4f}, { 3, -26}, {11, -19.5f}, {19, -13}, {27, -6.5f}, {35, 0}, {48, 20}, {59, 40}, {70, 60} } }; /* Meter Type 2 - IARU recommended */ static cal_table_float_t meter_type2 = { 9, { { 0, -54}, { 3, -48}, {11, -36}, {19, -24}, {27, -12}, {35, 0}, {48, 20}, {59, 40}, {70, 60} } }; static cal_table_t power_meter = { 7, { { 0, 0}, { 5, 5}, { 10, 10}, {19, 25}, { 35, 50}, { 59, 100}, { 70, 150} } }; /* Make sure we're asking the right question */ kenwood_get_ptt(rig, vfo, &ptt); if ((ptt == RIG_PTT_OFF) != (level == RIG_LEVEL_STRENGTH)) { /* We're sorry, the number you have dialed is not in service */ if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f = 0; } else { val->i = 0; } return RIG_OK; } /* Find out which meter type is in use */ retval = kenwood_safe_transaction(rig, "EX00011", ackbuf, sizeof(ackbuf), 11); if (retval != RIG_OK) { return retval; } if (strncmp(ackbuf + 8, "000", 3) == 0) { table = &meter_type1; } else if (strncmp(ackbuf + 8, "001", 3) == 0) { table = &meter_type2; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected meter type: %s\n", __func__, ackbuf); return -RIG_EPROTO; } retval = kenwood_safe_transaction(rig, "SM", ackbuf, 10, 6); if (retval != RIG_OK) { return retval; } sscanf(ackbuf + 2, "%d", &val->i); if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f = roundf(rig_raw2val(val->i, &power_meter)); } else { /* Convert reading back to dB (rounded) */ val->i = (int)floorf(rig_raw2val_float(val->i, table) + 0.5f); } return RIG_OK; } case RIG_LEVEL_USB_AF: case RIG_LEVEL_USB_AF_INPUT: if (level == RIG_LEVEL_USB_AF) { command_string = "EX00708"; } else { command_string = "EX00706"; } len = strlen(command_string); retval = kenwood_safe_transaction(rig, command_string, ackbuf, sizeof(ackbuf), len + 4); if (retval != RIG_OK) { return retval; } sscanf(&ackbuf[len + 1], "%3d", &levelint); /* Skip the extra space */ val->f = levelint * level_info->step.f; return RIG_OK; default: return kenwood_get_level(rig, vfo, level, val); } return -RIG_EINTERNAL; } static int ts890_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int mask, retval; char current[4]; switch (func) { case RIG_FUNC_TONE: mask = 1; break; case RIG_FUNC_TSQL: mask = 2; break; default: return (kenwood_set_func(rig, vfo, func, status)); } retval = kenwood_safe_transaction(rig, "TO", current, sizeof(current), 3); if (retval != RIG_OK) { return (retval); } current[2] &= ~mask; current[2] |= status == 0 ? 0 : mask; return kenwood_transaction(rig, current, NULL, 0); } static int ts890_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int mask, retval; char current[4]; switch (func) { case RIG_FUNC_TONE: mask = 1; break; case RIG_FUNC_TSQL: mask = 2; break; default: return (kenwood_get_func(rig, vfo, func, status)); } retval = kenwood_safe_transaction(rig, "TO", current, sizeof(current), 3); if (retval != RIG_OK) { return retval; } *status = current[2] & mask ? 1 : 0; return RIG_OK; } /* * Gets split VFO status * */ static int ts890s_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { char buf[4]; int retval; vfo_t tvfo; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; if (RIG_OK == (retval = kenwood_safe_transaction(rig, "FT", buf, sizeof(buf), 3))) { if ('0' == buf[2]) { tvfo = RIG_VFO_A; } else if ('1' == buf[2]) { tvfo = RIG_VFO_B; } else if ('3' == buf[2]) { tvfo = RIG_VFO_MEM; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unknown VFO - %s\n", __func__, buf); return -RIG_EPROTO; } *txvfo = priv->tx_vfo = rs->tx_vfo = tvfo; // Now get split status retval = kenwood_safe_transaction(rig, "TB", buf, sizeof buf, 3); if (RIG_OK != retval) {return retval;} *split = priv->split = buf[2] == '1'; } return retval; } static struct kenwood_priv_caps ts890s_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 0, }; /* SWR meter calibration table */ /* The full scale value reads infinity, so arbitrary */ #define TS890_SWR_CAL { 5, \ { \ { 0, 1.0 }, \ { 11, 1.5 }, \ { 23, 2.0 }, \ { 35, 3.0 }, \ { 70, 15.0 } \ } } /* * TS-890S rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps ts890s_caps = { RIG_MODEL(RIG_MODEL_TS890S), .model_name = "TS-890S", .mfg_name = "Kenwood", .version = BACKEND_VER ".16", .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 = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 1, .preamp = {12, RIG_DBLST_END,}, .attenuator = {6, 12, 18, 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 = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_ON }, .chan_list = { { 1, 6, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS890_ALL_MODES, -1, -1, TS890_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(3500), kHz(3800), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(7), kHz(7200), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(7), kHz(7200), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(14), kHz(14350), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(14), kHz(14350), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(21), kHz(21450), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(21), kHz(21450), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(28), kHz(29700), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(28), kHz(29700), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(50), kHz(52000), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(50), kHz(52000), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS890_ALL_MODES, -1, -1, TS890_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(3500), MHz(4) - 1, TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(5250), kHz(5450), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(5250), kHz(5450), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(7), kHz(7300), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(7), kHz(7300), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(10100), kHz(10150), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(14), kHz(14350), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(14), kHz(14350), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(18068), kHz(18168), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(21), kHz(21450), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(21), kHz(21450), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {kHz(24890), kHz(24990), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(28), kHz(29700), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(28), kHz(29700), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, {MHz(50), kHz(52000), TS890_OTHER_TX_MODES, 5000, 100000, TS890_VFO}, {MHz(50), kHz(52000), TS890_AM_TX_MODES, 5000, 25000, TS890_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS890_ALL_MODES, kHz(1)}, {TS890_ALL_MODES, Hz(2500)}, {TS890_ALL_MODES, kHz(5)}, {TS890_ALL_MODES, Hz(6250)}, {TS890_ALL_MODES, kHz(10)}, {TS890_ALL_MODES, Hz(12500)}, {TS890_ALL_MODES, kHz(15)}, {TS890_ALL_MODES, kHz(20)}, {TS890_ALL_MODES, kHz(25)}, {TS890_ALL_MODES, kHz(30)}, {TS890_ALL_MODES, kHz(100)}, {TS890_ALL_MODES, kHz(500)}, {TS890_ALL_MODES, MHz(1)}, {TS890_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(15)}, RIG_FLT_END, }, .vfo_ops = TS890_VFO_OPS, .ctcss_list = kenwood51_ctcss_list, .swr_cal = TS890_SWR_CAL, .priv = (void *)& ts890s_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit_new, .get_rit = kenwood_get_rit_new, .set_xit = kenwood_set_rit_new, // Same routines as for RIT .get_xit = kenwood_get_rit_new, // Same .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = ts890s_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .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 = NULL, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .wait_morse = rig_wait_morse, .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 = TS890_LEVEL_SET, .has_get_level = TS890_LEVEL_GET, .set_level = kenwood_ts890_set_level, .get_level = kenwood_ts890_get_level, .level_gran = { #define NO_LVL_ATT #define NO_LVL_CWPITCH #define NO_LVL_SQL #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #include "level_gran_kenwood.h" #undef NO_LVL_ATT #undef NO_LVL_CWPITCH #undef NO_LVL_SQL #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1100 }, .step = { .i = 5 } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0 / 255.0 } }, [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0 / 100.0 } }, [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0 / 100.0 } }, }, .has_get_func = TS890_FUNC_ALL, .has_set_func = TS890_FUNC_ALL, .set_func = ts890_set_func, .get_func = ts890_get_func, .get_clock = kenwood_get_clock, .set_clock = kenwood_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/transfox.c0000644000175000017500000002340714752216205014334 00000000000000/* * Hamlib backend - SigFox Transfox description * Copyright (c) 2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. */ #include #include #include "kenwood.h" #define TRANSFOX_MODES (RIG_MODE_USB) /* SDR */ #define TRANSFOX_FUNC_ALL (RIG_FUNC_NONE) #define TRANSFOX_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP) #define TRANSFOX_VFO (RIG_VFO_A) #define TRANSFOX_VFO_OP (RIG_OP_NONE) #define TRANSFOX_ANTS (RIG_ANT_1) /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps transfox_priv_caps = { .cmdtrm = EOM_KEN, }; /* TRANSFOX specific rig_caps API function declarations */ static int transfox_open(RIG *rig); static const char *transfox_get_info(RIG *rig); static int transfox_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); static int transfox_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int transfox_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); /* * Transfox rig capabilities. * This SDR only share some basic Kenwood's protocol. * * Part of info comes from http://www.sigfox-system.com/TransFox-FE?lang=en */ struct rig_caps transfox_caps = { RIG_MODEL(RIG_MODEL_TRANSFOX), .model_name = "Transfox", .mfg_name = "SigFox", .version = "20111223.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TUNER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 19200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 10, /* Timing between command strings */ .timeout = 500, .retry = 3, .has_get_func = TRANSFOX_FUNC_ALL, .has_set_func = TRANSFOX_FUNC_ALL, .has_get_level = TRANSFOX_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TRANSFOX_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .extparms = NULL, .preamp = { 22, 44, RIG_DBLST_END, }, .attenuator = { 10, 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TRANSFOX_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {MHz(1), MHz(1450), TRANSFOX_MODES, -1, -1, TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(1), MHz(1450), TRANSFOX_MODES, mW(100), mW(100), TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(1), MHz(1450), TRANSFOX_MODES, -1, -1, TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(1), MHz(1450), TRANSFOX_MODES, mW(100), mW(100), TRANSFOX_VFO, TRANSFOX_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TRANSFOX_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {TRANSFOX_MODES, kHz(192)}, RIG_FLT_END, }, .priv = (void *)& transfox_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = transfox_open, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_level = transfox_set_level, .get_level = transfox_get_level, .set_ptt = kenwood_set_ptt, .get_ptt = transfox_get_ptt, .get_info = transfox_get_info, #ifdef XXREMOVEDXX .set_trn = transfox_set_trn, .get_trn = transfox_get_trn, .scan = transfox_scan, .set_conf = transfox_set_conf, .get_conf = transfox_get_conf, #endif .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * TRANSFOX extension function definitions follow */ /* transfox_open() * */ int transfox_open(RIG *rig) { rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); STATE(rig)->current_vfo = RIG_VFO_A; /* do not call kenwood_open(rig), rig has no "ID" command */ return RIG_OK; } int transfox_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char buf[8]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "Cs", buf, 8, 2); if (retval != RIG_OK) { return retval; } *ptt = buf[0] == 'T' ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } const char *transfox_get_info(RIG *rig) { static char firmbuf[32]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); firmbuf[0] = '\0'; retval = kenwood_transaction(rig, "CS", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } return firmbuf; } int transfox_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret = RIG_OK; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: if (val.i == 0) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C20", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 10) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C21", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 20) { ret = kenwood_transaction(rig, "C31", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C21", NULL, 0); if (ret != RIG_OK) { return ret; } } break; case RIG_LEVEL_PREAMP: if (val.i == 0) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C20", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 22) { ret = kenwood_transaction(rig, "C30", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C22", NULL, 0); if (ret != RIG_OK) { return ret; } } else if (val.i == 44) { ret = kenwood_transaction(rig, "C32", NULL, 0); if (ret != RIG_OK) { return ret; } ret = kenwood_transaction(rig, "C22", NULL, 0); if (ret != RIG_OK) { return ret; } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return ret; } int transfox_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[16]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "C2x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i = (lvlbuf[2] == '1') ? 10 : 0; retval = kenwood_safe_transaction(rig, "C3x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i += (lvlbuf[2] == '1') ? 10 : 0; break; case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "C2x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i = (lvlbuf[2] == '2') ? 22 : 0; retval = kenwood_safe_transaction(rig, "C3x", lvlbuf, 8, 3); if (retval != RIG_OK) { return retval; } val->i += (lvlbuf[2] == '2') ? 22 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.2/rigs/kenwood/thf6a.c0000644000175000017500000002414214752216205013475 00000000000000/* * Hamlib Kenwood backend - TH-F6A Cloned from TH-F7E description * Copyright (c) 2001-2009 by Stephane Fillod * Copyright (c) 2010 by Scott Martin * * 10-03-2010 * Ported from Stephane Fillod's thf7.c * Changed TH-F7E parameters to reflect TH-F6A * Changed RIG_ITU_REGION from 1 to 2 * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "tones.h" #include "kenwood.h" #include "th.h" #define THF6_MODES_TX (RIG_MODE_FM) #define THF6_HIGH_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_WFM) #define THF6_ALL_MODES (THF6_HIGH_MODES|RIG_MODE_SSB|RIG_MODE_CW) #define THF6_FUNC_ALL (RIG_FUNC_ARO|RIG_FUNC_LOCK|RIG_FUNC_BC) /* * How incredible, there's no RIG_LEVEL_STRENGTH! */ #define THF6_LEVEL_ALL (RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_ATT|\ RIG_LEVEL_BALANCE|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY) #define THF6_PARMS (RIG_PARM_APO|RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define THF6_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define THF6_ANTS (RIG_ANT_1|RIG_ANT_2) /* * TODO: * scan_group can only be get. scan_group=channel_num%50; */ #define THF6_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define THF6_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, /* CTCSS 01..42 */ static tone_t thf6_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0 }; static rmode_t thf6_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_WFM, [2] = RIG_MODE_AM, [3] = RIG_MODE_LSB, [4] = RIG_MODE_USB, [5] = RIG_MODE_CW }; /* * Band A & B */ #define THF6_VFO (RIG_VFO_A|RIG_VFO_B) static struct kenwood_priv_caps thf6_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thf6_mode_table, }; static int thf6a_init(RIG *rig); static int thf6a_open(RIG *rig); static int thf6a_get_vfo(RIG *rig, vfo_t *vfo); static int thf6a_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* * TH-F6A rig capabilities. * * Manual, thanks to K6MAY: http://www.k6may.com/KenwoodTHF6Tip1.shtml * * TODO: * - set/get_ctcss_tone/sql through set/get_channel() and VR/VW * - emulate RIG_FUNC_TONE|RIG_FUNC_TSQL by setting ctcss_tone/sql to 0/non zero? */ struct rig_caps thf6a_caps = { RIG_MODEL(RIG_MODEL_THF6A), .model_name = "TH-F6A", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THF6_FUNC_ALL, .has_set_func = THF6_FUNC_ALL | RIG_FUNC_TBURST, .has_get_level = THF6_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THF6_LEVEL_ALL), .has_get_parm = THF6_PARMS, .has_set_parm = THF6_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = thf6_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THF6_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, /* TBC */ .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 0, 399, RIG_MTYPE_MEM, {THF6_CHANNEL_CAPS}}, /* normal MEM */ { 400, 409, RIG_MTYPE_EDGE, {THF6_CHANNEL_CAPS}}, /* L0-L9 lower scan limit */ { 410, 419, RIG_MTYPE_EDGE, {THF6_CHANNEL_CAPS}}, /* U0-U9 upper scan limit */ { 420, 429, RIG_MTYPE_MEM, {THF6_CHANNEL_CAPS}}, /* I0-I9 info */ { 430, 431, RIG_MTYPE_PRIO, {THF6_CHANNEL_CAPS}}, /* PR0,PR1 priority */ { 432, 434, RIG_MTYPE_CALL, {THF6_CHANNEL_CAPS_WO_LO}}, /* Call (for each ham band) */ { 435, 449, RIG_MTYPE_BAND, {THF6_CHANNEL_CAPS_WO_LO}}, /* VFO */ /* 3 A-band VFO */ /* 11 B-band VFO */ /* TODO: 10 DTMF */ RIG_CHAN_END, }, .rx_range_list1 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(146), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF6_ALL_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF6_HIGH_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list1 = { /* power actually depends on DC power supply */ {MHz(144), MHz(146), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, /* region 2 is model TH-F6A in fact */ .rx_range_list2 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(148), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF6_MODES_TX, -1, -1, RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF6_ALL_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF6_HIGH_MODES, -1, -1, RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list2 = { /* power actually depends on DC power supply */ {MHz(144), MHz(148), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF6_MODES_TX, W(0.05), W(5), RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, .tuning_steps = { /* This table is ordered according to protocol, from '0' to 'b' */ /* The steps are not available on every band/frequency limit 470MHz */ {THF6_ALL_MODES, kHz(5)}, {THF6_ALL_MODES, kHz(6.25)}, {THF6_ALL_MODES, kHz(8.33)}, {THF6_ALL_MODES, kHz(9)}, {THF6_ALL_MODES, kHz(10)}, {THF6_ALL_MODES, kHz(12.5)}, {THF6_ALL_MODES, kHz(15)}, {THF6_ALL_MODES, kHz(20)}, {THF6_ALL_MODES, kHz(25)}, {THF6_ALL_MODES, kHz(30)}, {THF6_ALL_MODES, kHz(50)}, {THF6_ALL_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* real width to be checked (missing specs) */ {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, /* narrow FM */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(150)}, /* or 230? */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, RIG_FLT_END, }, .priv = (void *)& thf6_priv_caps, .rig_init = thf6a_init, .rig_cleanup = kenwood_cleanup, .rig_open = thf6a_open, .rig_close = kenwood_close, .set_freq = th_set_freq, .get_freq = th_get_freq, .set_mode = th_set_mode, .get_mode = th_get_mode, .set_vfo = th_set_vfo, .get_vfo = thf6a_get_vfo, .set_ptt = th_set_ptt, .get_dcd = th_get_dcd, .vfo_op = thf6a_vfo_op, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_func = th_set_func, .get_func = th_get_func, .set_level = th_set_level, .get_level = th_get_level, .get_parm = th_get_parm, .set_parm = th_set_parm, .get_info = th_get_info, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_ant = th_set_ant, .get_ant = th_get_ant, .reset = th_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int thf6a_init(RIG *rig) { return kenwood_init(rig); } int thf6a_open(RIG *rig) { return kenwood_open(rig); } /* * th_get_vfo * Assumes rig!=NULL */ int thf6a_get_vfo(RIG *rig, vfo_t *vfo) { char vfoch; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = th_get_vfo_char(rig, vfo, &vfoch); if (retval != RIG_OK) { return retval; } switch (vfoch) { case '0' : case '3' : /* Fine Step Enable */ break; case '1' : /* MR */ case '2' : /* CALL */ case '4' : /* INFO */ *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, vfoch); return -RIG_EVFO; } return RIG_OK; } /* * thf6a_vfo_op */ int thf6a_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", NULL, 0); /* Not implemented! case RIG_OP_BAND_UP: return kenwood_transaction(rig, "BU", NULL, 0); case RIG_OP_BAND_DOWN: return kenwood_transaction(rig, "BD", NULL, 0); */ default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } } hamlib-4.6.2/rigs/kenwood/ts711.c0000644000175000017500000001360614752216205013347 00000000000000/* * Hamlib Kenwood backend - TS-711 description * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS711_ALL_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) /* func and levels to be checked */ #define TS711_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define TS711_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define TS711_VFO (RIG_VFO_A|RIG_VFO_B) #define TS711_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS711_SCAN_OP (RIG_SCAN_VFO) /* * There are some platform differences: * * + Tone on/off isn't applicable to "kenwood" versions of the E rigs * + Tone frequency is only A/B rigs * + Offset is only TS-811A, TS-811B, TS-811E, TS-711A, TS-711E. * * So maybe this should have a separate set of backends for each * rig variation because of the frequency range differences, capability * differences, etc, etc. */ static struct kenwood_priv_caps ts711_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' /* Note: The 140/680/711/811 need this to set the VFO on the radio */ static int ts711_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts711 rig capabilities. */ struct rig_caps ts711_caps = { RIG_MODEL(RIG_MODEL_TS711), .model_name = "TS-711", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 10, .has_get_func = TS711_FUNC_ALL, .has_set_func = TS711_FUNC_ALL, .has_get_level = TS711_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS711_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .vfo_ops = TS711_VFO_OP, .scan_ops = TS711_SCAN_OP, .ctcss_list = kenwood38_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(9.9), .max_xit = 0, .max_ifshift = 0, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, /* FIXME: split memories, call channel, etc. */ .chan_list = { { 1, 59, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), TS711_ALL_MODES, -1, -1, TS711_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TS711_ALL_MODES, W(5), W(25), TS711_VFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(144), MHz(148), TS711_ALL_MODES, -1, -1, TS711_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TS711_ALL_MODES, W(5), W(25), TS711_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS711_ALL_MODES, 50}, {TS711_ALL_MODES, 100}, {TS711_ALL_MODES, kHz(1)}, {TS711_ALL_MODES, kHz(5)}, {TS711_ALL_MODES, kHz(9)}, {TS711_ALL_MODES, kHz(10)}, {TS711_ALL_MODES, 12500}, {TS711_ALL_MODES, kHz(20)}, {TS711_ALL_MODES, kHz(25)}, {TS711_ALL_MODES, kHz(100)}, {TS711_ALL_MODES, MHz(1)}, {TS711_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts711_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts711_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/ts870s.c0000644000175000017500000004455714752216205013551 00000000000000/* * Hamlib Kenwood backend - TS870S description * Copyright (c) 2000-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "bandplan.h" #define TS870S_ALL_MODES \ (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB \ |RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS870S_OTHER_TX_MODES \ (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS870S_AM_TX_MODES RIG_MODE_AM #define TS870S_FUNC_ALL \ (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR \ |RIG_FUNC_BC|RIG_FUNC_ANF|RIG_FUNC_LOCK) #define TS870S_LEVEL_SET \ (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_RFPOWER \ |RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_PREAMP) #define TS870S_LEVEL_GET \ (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR \ |RIG_LEVEL_COMP|RIG_LEVEL_ALC|RIG_LEVEL_AGC|RIG_LEVEL_RFPOWER \ |RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_PREAMP) #define TS870S_VFO (RIG_VFO_A|RIG_VFO_B) #define TS870S_ANTS (RIG_ANT_1|RIG_ANT_2) static struct kenwood_priv_caps ts870s_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* only the ts870s and ts2000 support get_vfo with the 'FR;' command NOTE: using byte 31 in 'IF' will also work. TODO: check other rigs */ static int ts870s_get_vfo(RIG *rig, vfo_t *vfo) { char vfobuf[50]; size_t vfo_len; int retval; /* query RX VFO */ retval = kenwood_transaction(rig, "FR", vfobuf, sizeof(vfobuf)); if (retval != RIG_OK) { return retval; } vfo_len = strlen(vfobuf); if (vfo_len != 3 || vfobuf[1] != 'R') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer %s, len=%d\n", __func__, vfobuf, (int)vfo_len); return -RIG_ERJCTED; } /* TODO: replace 0,1,2,.. constants by defines */ switch (vfobuf[2]) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; case '2': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, vfobuf[2]); return -RIG_EPROTO; } return RIG_OK; } static int ts870s_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[50]; size_t buf_len; int retval; retval = kenwood_transaction(rig, "MD", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } buf_len = strlen(buf); if (buf_len != 3 || buf[1] != 'D') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected MD answer, len=%d\n", __func__, (int)buf_len); return -RIG_ERJCTED; } switch (buf[2]) { case MD_CW: *mode = RIG_MODE_CW; break; case MD_CWR: *mode = RIG_MODE_CWR; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_FM: *mode = RIG_MODE_FM; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FSK: *mode = RIG_MODE_RTTY; break; case MD_FSKR: *mode = RIG_MODE_RTTYR; break; case MD_NONE: *mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, buf[2]); return -RIG_EINVAL; } retval = kenwood_transaction(rig, "FW", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } buf_len = strlen(buf); if (buf_len != 6 || buf[1] != 'W') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected FW answer, len=%d\n", __func__, (int)buf_len); return -RIG_ERJCTED; } *width = 10 * atoi(&buf[2]); if (RIG_MODE_USB == *mode || RIG_MODE_LSB == *mode || RIG_MODE_AM == *mode) { /* we only have HPF value and need LPF as well to calculate bandwidth */ retval = kenwood_transaction(rig, "IS", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } buf_len = strlen(buf); if (buf_len != 7 || buf[1] != 'S') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected IS answer, len=%d\n", __func__, (int)buf_len); return -RIG_ERJCTED; } *width = atoi(&buf[3]) - *width; /* bandwidth <- LPF - HPF */ } return RIG_OK; } static int ts870s_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[16]; int kmode, retval; switch (mode) { case RIG_MODE_CW: kmode = MD_CW; break; case RIG_MODE_CWR: kmode = MD_CWR; break; case RIG_MODE_USB: kmode = MD_USB; break; case RIG_MODE_LSB: kmode = MD_LSB; break; case RIG_MODE_FM: kmode = MD_FM; break; case RIG_MODE_AM: kmode = MD_AM; break; case RIG_MODE_RTTY: kmode = MD_FSK; break; case RIG_MODE_RTTYR: kmode = MD_FSKR; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD%c", kmode); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { if (RIG_PASSBAND_NORMAL != width) /* leave well alone if default passband requested */ { if (RIG_MODE_USB == mode || RIG_MODE_LSB == mode || RIG_MODE_AM == mode) { pbwidth_t mode_default_hpf; /* we assume the HPF is set to default and set the LPF to give the best approximaation of the requested width */ if (RIG_MODE_AM == mode) { mode_default_hpf = 300; } else { mode_default_hpf = 100; } SNPRINTF(buf, sizeof(buf), "IS %04d", (int)(width + mode_default_hpf)); retval = kenwood_transaction(rig, buf, NULL, 0); } else { /* * This rig will simply use an IF bandpass which is closest to width, * so we don't need to check the value... */ SNPRINTF(buf, sizeof(buf), "FW%04d", (int)width / 10); retval = kenwood_transaction(rig, buf, NULL, 0); } } } return retval; } int ts870s_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int intval; switch (level) { case RIG_LEVEL_RFPOWER: intval = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", intval); return kenwood_transaction(rig, levelbuf, NULL, 0); break; default: return kenwood_set_level(rig, vfo, level, val); } return RIG_OK; } static int ts870s_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; size_t lvl_len; int lvl, retval; int i, ret, agclevel; switch (level) { case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6 || lvlbuf[1] != 'M') { rig_debug(RIG_DEBUG_ERR, "ts870s_get_level: wrong answer len=%d\n", (int)lvl_len); return -RIG_ERJCTED; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 2, "%d", &val->i); val->i = (val->i * 3.6) - 54; break; case RIG_LEVEL_SWR: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } /* set meter to SWR if needed */ if (lvlbuf[2] != '1') { retval = kenwood_transaction(rig, "RM1", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } } i = atoi(&lvlbuf[3]); if (i == 30) { val->f = 150.0; /* infinity :-) */ } else { val->f = 60.0 / (30.0 - (float)i) - 1.0; } break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } /* set meter to COMP if needed */ if (lvlbuf[2] != '2') { retval = kenwood_transaction(rig, "RM2", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; case RIG_LEVEL_ALC: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } /* set meter to ALC if needed */ if (lvlbuf[2] != '3') { retval = kenwood_transaction(rig, "RM3", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; case RIG_LEVEL_ATT: retval = kenwood_transaction(rig, "RA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else { for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) if (STATE(rig)->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "ts870s_get_level: " "unexpected att level %d\n", lvl); return -RIG_EPROTO; } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->attenuator[i - 1]; } break; case RIG_LEVEL_RFPOWER: /* RFPOWER is 0..100 and not 0..255 like all the other levels*/ retval = kenwood_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5 || lvlbuf[1] != 'C') { rig_debug(RIG_DEBUG_ERR, "ts870s_get_level: wrong answer len=%d\n", (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 100.; break; case RIG_LEVEL_AF: return get_kenwood_level(rig, "AG", &val->f, NULL); case RIG_LEVEL_RF: return get_kenwood_level(rig, "RG", &val->f, NULL); case RIG_LEVEL_SQL: return get_kenwood_level(rig, "SQ", &val->f, NULL); case RIG_LEVEL_MICGAIN: return get_kenwood_level(rig, "MG", &val->f, NULL); case RIG_LEVEL_AGC: ret = get_kenwood_level(rig, "GT", &val->f, NULL); agclevel = 255 * val->f; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } return ret; case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_KEYSPD: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; case RIG_LEVEL_PREAMP: return -RIG_ENAVAIL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * ts870s rig capabilities. * Notice that some rigs share the same functions. * RIT: Variable Range ±9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts870s_caps = { RIG_MODEL(RIG_MODEL_TS870S), .model_name = "TS-870S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = TS870S_FUNC_ALL, .has_set_func = TS870S_FUNC_ALL, .has_get_level = TS870S_LEVEL_GET, .has_set_level = TS870S_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #include "level_gran_kenwood.h" #undef NO_LVL_ATT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // Has GT command but ranges from 000-005(Off) to 255 max // Would take special processing .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), TS870S_ALL_MODES, -1, -1, TS870S_VFO, TS870S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS870S_OTHER_TX_MODES, W(5), W(100), TS870S_VFO, TS870S_ANTS), /* 100W class */ FRQ_RNG_HF(1, TS870S_AM_TX_MODES, W(2), W(25), TS870S_VFO, TS870S_ANTS), /* 25W class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS870S_ALL_MODES, -1, -1, TS870S_VFO, TS870S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS870S_OTHER_TX_MODES, W(5), W(100), TS870S_VFO, TS870S_ANTS), /* 100W class */ FRQ_RNG_HF(2, TS870S_AM_TX_MODES, W(2), W(25), TS870S_VFO, TS870S_ANTS), /* 25W class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS870S_ALL_MODES, 50}, {TS870S_ALL_MODES, 100}, {TS870S_ALL_MODES, kHz(1)}, {TS870S_ALL_MODES, kHz(5)}, {TS870S_ALL_MODES, kHz(9)}, {TS870S_ALL_MODES, kHz(10)}, {TS870S_ALL_MODES, 12500}, {TS870S_ALL_MODES, kHz(20)}, {TS870S_ALL_MODES, kHz(25)}, {TS870S_ALL_MODES, kHz(100)}, {TS870S_ALL_MODES, MHz(1)}, {TS870S_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, Hz(200)}, {RIG_MODE_SSB, Hz(0)}, {RIG_MODE_SSB, Hz(600)}, {RIG_MODE_CW, Hz(400)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_CW, Hz(1000)}, {RIG_MODE_RTTY, Hz(1000)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, Hz(200)}, {RIG_MODE_AM, Hz(0)}, {RIG_MODE_AM, Hz(500)}, {RIG_MODE_FM, kHz(8)}, {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .priv = (void *)& ts870s_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = ts870s_set_mode, .get_mode = ts870s_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = ts870s_get_vfo, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = ts870s_set_level, .get_level = ts870s_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/ts680.c0000644000175000017500000001433014752216205013347 00000000000000/* * Hamlib Kenwood backend - TS680 description * Copyright (c) 2000-2008 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "kenwood.h" #define TS680_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_CWR) #define TS680_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_CWR) #define TS680_AM_TX_MODES RIG_MODE_AM #define TS680_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS680_ANTS (0) /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' static struct kenwood_priv_caps ts680_priv_caps = { .cmdtrm = EOM_KEN, }; static int ts680_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "ts680_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); /* The 680 and 140 need this to set the VFO on the radio */ return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts680 rig capabilities. * GW0VNR 09042006 */ struct rig_caps ts680s_caps = { RIG_MODEL(RIG_MODEL_TS680S), .model_name = "TS-680S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, /* Rig only capable of 4800 baud from factory and 9k6 with jumper change */ .serial_data_bits = 8, .serial_stop_bits = 2, /* TWO stop bits. This is correct. */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* No PARAMS controllable */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* Not controllable */ .attenuator = { RIG_DBLST_END, }, /* Not controllable */ .max_rit = kHz(1.2), .max_xit = kHz(1.2), .max_ifshift = Hz(0), /* Not controllable */ .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 19, RIG_MTYPE_MEM }, { 20, 30, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(50), kHz(34999), TS680_ALL_MODES, -1, -1, TS680_VFO}, {MHz(45), kHz(59999), TS680_ALL_MODES, -1, -1, TS680_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS680_OTHER_TX_MODES, W(5), W(100), TS680_VFO, TS680_ANTS), FRQ_RNG_HF(1, TS680_AM_TX_MODES, W(2), W(40), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(1, TS680_OTHER_TX_MODES, W(1), W(10), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(1, TS680_AM_TX_MODES, W(1), W(4), TS680_VFO, TS680_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(50), kHz(34999), TS680_ALL_MODES, -1, -1, TS680_VFO}, {MHz(45), kHz(59999), TS680_ALL_MODES, -1, -1, TS680_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS680_OTHER_TX_MODES, W(5), W(100), TS680_VFO, TS680_ANTS), FRQ_RNG_HF(2, TS680_AM_TX_MODES, W(2), W(40), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(2, TS680_OTHER_TX_MODES, W(1), W(10), TS680_VFO, TS680_ANTS), FRQ_RNG_6m(2, TS680_AM_TX_MODES, W(1), W(4), TS680_VFO, TS680_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: Done */ {TS680_ALL_MODES, 10}, {TS680_ALL_MODES, 100}, {TS680_ALL_MODES, kHz(1)}, {TS680_ALL_MODES, kHz(5)}, {TS680_ALL_MODES, kHz(9)}, {TS680_ALL_MODES, kHz(10)}, {TS680_ALL_MODES, 12500}, {TS680_ALL_MODES, kHz(20)}, {TS680_ALL_MODES, kHz(25)}, {TS680_ALL_MODES, kHz(100)}, {TS680_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_CWR, 600}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts680_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, // we don't know the ID for this rig .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts680_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/Makefile.am0000644000175000017500000000125414752216205014354 00000000000000 TSSRC = ts850.c ts870s.c ts570.c ts450s.c ts950.c ts50s.c \ ts790.c ts2000.c k2.c k3.c xg3.c ts930.c \ ts680.c ts690.c ts140.c ts480.c trc80.c ts590.c ts890s.c \ ts990s.c ts990s.h flex6xxx.c pihpsdr.c tx500.c IC10SRC = ts440.c ts940.c ts711.c ts811.c r5000.c THSRC = thd7.c thf7.c thg71.c tmd700.c tmv7.c thf6a.c thd72.c tmd710.c thd74.c KENWOODSRC = kenwood.c kenwood.h th.c th.h ic10.c ic10.h elecraft.c elecraft.h \ transfox.c flex.c flex.h level_gran_kenwood.h level_gran_elecraft.h noinst_LTLIBRARIES = libhamlib-kenwood.la libhamlib_kenwood_la_SOURCES = $(TSSRC) $(THSRC) $(IC10SRC) $(KENWOODSRC) EXTRA_DIST = README.kenwood README.k2 README.k3 README.flex Android.mk hamlib-4.6.2/rigs/kenwood/Makefile.in0000644000175000017500000007237514752216216014403 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/kenwood ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_kenwood_la_LIBADD = am__objects_1 = ts850.lo ts870s.lo ts570.lo ts450s.lo ts950.lo \ ts50s.lo ts790.lo ts2000.lo k2.lo k3.lo xg3.lo ts930.lo \ ts680.lo ts690.lo ts140.lo ts480.lo trc80.lo ts590.lo \ ts890s.lo ts990s.lo flex6xxx.lo pihpsdr.lo tx500.lo am__objects_2 = thd7.lo thf7.lo thg71.lo tmd700.lo tmv7.lo thf6a.lo \ thd72.lo tmd710.lo thd74.lo am__objects_3 = ts440.lo ts940.lo ts711.lo ts811.lo r5000.lo am__objects_4 = kenwood.lo th.lo ic10.lo elecraft.lo transfox.lo \ flex.lo am_libhamlib_kenwood_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) libhamlib_kenwood_la_OBJECTS = $(am_libhamlib_kenwood_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/elecraft.Plo ./$(DEPDIR)/flex.Plo \ ./$(DEPDIR)/flex6xxx.Plo ./$(DEPDIR)/ic10.Plo \ ./$(DEPDIR)/k2.Plo ./$(DEPDIR)/k3.Plo ./$(DEPDIR)/kenwood.Plo \ ./$(DEPDIR)/pihpsdr.Plo ./$(DEPDIR)/r5000.Plo \ ./$(DEPDIR)/th.Plo ./$(DEPDIR)/thd7.Plo ./$(DEPDIR)/thd72.Plo \ ./$(DEPDIR)/thd74.Plo ./$(DEPDIR)/thf6a.Plo \ ./$(DEPDIR)/thf7.Plo ./$(DEPDIR)/thg71.Plo \ ./$(DEPDIR)/tmd700.Plo ./$(DEPDIR)/tmd710.Plo \ ./$(DEPDIR)/tmv7.Plo ./$(DEPDIR)/transfox.Plo \ ./$(DEPDIR)/trc80.Plo ./$(DEPDIR)/ts140.Plo \ ./$(DEPDIR)/ts2000.Plo ./$(DEPDIR)/ts440.Plo \ ./$(DEPDIR)/ts450s.Plo ./$(DEPDIR)/ts480.Plo \ ./$(DEPDIR)/ts50s.Plo ./$(DEPDIR)/ts570.Plo \ ./$(DEPDIR)/ts590.Plo ./$(DEPDIR)/ts680.Plo \ ./$(DEPDIR)/ts690.Plo ./$(DEPDIR)/ts711.Plo \ ./$(DEPDIR)/ts790.Plo ./$(DEPDIR)/ts811.Plo \ ./$(DEPDIR)/ts850.Plo ./$(DEPDIR)/ts870s.Plo \ ./$(DEPDIR)/ts890s.Plo ./$(DEPDIR)/ts930.Plo \ ./$(DEPDIR)/ts940.Plo ./$(DEPDIR)/ts950.Plo \ ./$(DEPDIR)/ts990s.Plo ./$(DEPDIR)/tx500.Plo \ ./$(DEPDIR)/xg3.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_kenwood_la_SOURCES) DIST_SOURCES = $(libhamlib_kenwood_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TSSRC = ts850.c ts870s.c ts570.c ts450s.c ts950.c ts50s.c \ ts790.c ts2000.c k2.c k3.c xg3.c ts930.c \ ts680.c ts690.c ts140.c ts480.c trc80.c ts590.c ts890s.c \ ts990s.c ts990s.h flex6xxx.c pihpsdr.c tx500.c IC10SRC = ts440.c ts940.c ts711.c ts811.c r5000.c THSRC = thd7.c thf7.c thg71.c tmd700.c tmv7.c thf6a.c thd72.c tmd710.c thd74.c KENWOODSRC = kenwood.c kenwood.h th.c th.h ic10.c ic10.h elecraft.c elecraft.h \ transfox.c flex.c flex.h level_gran_kenwood.h level_gran_elecraft.h noinst_LTLIBRARIES = libhamlib-kenwood.la libhamlib_kenwood_la_SOURCES = $(TSSRC) $(THSRC) $(IC10SRC) $(KENWOODSRC) EXTRA_DIST = README.kenwood README.k2 README.k3 README.flex Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/kenwood/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/kenwood/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-kenwood.la: $(libhamlib_kenwood_la_OBJECTS) $(libhamlib_kenwood_la_DEPENDENCIES) $(EXTRA_libhamlib_kenwood_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_kenwood_la_OBJECTS) $(libhamlib_kenwood_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elecraft.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flex.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flex6xxx.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ic10.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/k2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/k3.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kenwood.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pihpsdr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/r5000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thd7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thd72.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thd74.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thf6a.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thf7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thg71.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmd700.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmd710.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tmv7.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transfox.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trc80.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts140.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts2000.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts440.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts450s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts480.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts50s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts570.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts590.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts680.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts690.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts711.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts790.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts811.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts850.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts870s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts890s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts930.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts940.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts950.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ts990s.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tx500.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xg3.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/elecraft.Plo -rm -f ./$(DEPDIR)/flex.Plo -rm -f ./$(DEPDIR)/flex6xxx.Plo -rm -f ./$(DEPDIR)/ic10.Plo -rm -f ./$(DEPDIR)/k2.Plo -rm -f ./$(DEPDIR)/k3.Plo -rm -f ./$(DEPDIR)/kenwood.Plo -rm -f ./$(DEPDIR)/pihpsdr.Plo -rm -f ./$(DEPDIR)/r5000.Plo -rm -f ./$(DEPDIR)/th.Plo -rm -f ./$(DEPDIR)/thd7.Plo -rm -f ./$(DEPDIR)/thd72.Plo -rm -f ./$(DEPDIR)/thd74.Plo -rm -f ./$(DEPDIR)/thf6a.Plo -rm -f ./$(DEPDIR)/thf7.Plo -rm -f ./$(DEPDIR)/thg71.Plo -rm -f ./$(DEPDIR)/tmd700.Plo -rm -f ./$(DEPDIR)/tmd710.Plo -rm -f ./$(DEPDIR)/tmv7.Plo -rm -f ./$(DEPDIR)/transfox.Plo -rm -f ./$(DEPDIR)/trc80.Plo -rm -f ./$(DEPDIR)/ts140.Plo -rm -f ./$(DEPDIR)/ts2000.Plo -rm -f ./$(DEPDIR)/ts440.Plo -rm -f ./$(DEPDIR)/ts450s.Plo -rm -f ./$(DEPDIR)/ts480.Plo -rm -f ./$(DEPDIR)/ts50s.Plo -rm -f ./$(DEPDIR)/ts570.Plo -rm -f ./$(DEPDIR)/ts590.Plo -rm -f ./$(DEPDIR)/ts680.Plo -rm -f ./$(DEPDIR)/ts690.Plo -rm -f ./$(DEPDIR)/ts711.Plo -rm -f ./$(DEPDIR)/ts790.Plo -rm -f ./$(DEPDIR)/ts811.Plo -rm -f ./$(DEPDIR)/ts850.Plo -rm -f ./$(DEPDIR)/ts870s.Plo -rm -f ./$(DEPDIR)/ts890s.Plo -rm -f ./$(DEPDIR)/ts930.Plo -rm -f ./$(DEPDIR)/ts940.Plo -rm -f ./$(DEPDIR)/ts950.Plo -rm -f ./$(DEPDIR)/ts990s.Plo -rm -f ./$(DEPDIR)/tx500.Plo -rm -f ./$(DEPDIR)/xg3.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/elecraft.Plo -rm -f ./$(DEPDIR)/flex.Plo -rm -f ./$(DEPDIR)/flex6xxx.Plo -rm -f ./$(DEPDIR)/ic10.Plo -rm -f ./$(DEPDIR)/k2.Plo -rm -f ./$(DEPDIR)/k3.Plo -rm -f ./$(DEPDIR)/kenwood.Plo -rm -f ./$(DEPDIR)/pihpsdr.Plo -rm -f ./$(DEPDIR)/r5000.Plo -rm -f ./$(DEPDIR)/th.Plo -rm -f ./$(DEPDIR)/thd7.Plo -rm -f ./$(DEPDIR)/thd72.Plo -rm -f ./$(DEPDIR)/thd74.Plo -rm -f ./$(DEPDIR)/thf6a.Plo -rm -f ./$(DEPDIR)/thf7.Plo -rm -f ./$(DEPDIR)/thg71.Plo -rm -f ./$(DEPDIR)/tmd700.Plo -rm -f ./$(DEPDIR)/tmd710.Plo -rm -f ./$(DEPDIR)/tmv7.Plo -rm -f ./$(DEPDIR)/transfox.Plo -rm -f ./$(DEPDIR)/trc80.Plo -rm -f ./$(DEPDIR)/ts140.Plo -rm -f ./$(DEPDIR)/ts2000.Plo -rm -f ./$(DEPDIR)/ts440.Plo -rm -f ./$(DEPDIR)/ts450s.Plo -rm -f ./$(DEPDIR)/ts480.Plo -rm -f ./$(DEPDIR)/ts50s.Plo -rm -f ./$(DEPDIR)/ts570.Plo -rm -f ./$(DEPDIR)/ts590.Plo -rm -f ./$(DEPDIR)/ts680.Plo -rm -f ./$(DEPDIR)/ts690.Plo -rm -f ./$(DEPDIR)/ts711.Plo -rm -f ./$(DEPDIR)/ts790.Plo -rm -f ./$(DEPDIR)/ts811.Plo -rm -f ./$(DEPDIR)/ts850.Plo -rm -f ./$(DEPDIR)/ts870s.Plo -rm -f ./$(DEPDIR)/ts890s.Plo -rm -f ./$(DEPDIR)/ts930.Plo -rm -f ./$(DEPDIR)/ts940.Plo -rm -f ./$(DEPDIR)/ts950.Plo -rm -f ./$(DEPDIR)/ts990s.Plo -rm -f ./$(DEPDIR)/tx500.Plo -rm -f ./$(DEPDIR)/xg3.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/kenwood/ts811.c0000644000175000017500000001254414752216205013350 00000000000000/* * Hamlib Kenwood backend - TS-811 description * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS811_ALL_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS811_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define TS811_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS811_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS811_SCAN_OP (RIG_SCAN_VFO) static struct kenwood_priv_caps ts811_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' /* Note: The 140/680/711/811 need this to set the VFO on the radio */ static int ts811_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts811 rig capabilities. */ struct rig_caps ts811_caps = { RIG_MODEL(RIG_MODEL_TS811), .model_name = "TS-811", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = TS811_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS811_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(9.9), .max_xit = 0, .max_ifshift = 0, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, /* FIXME: split memories, call channel, etc. */ .chan_list = { { 1, 59, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(430), MHz(440), TS811_ALL_MODES, -1, -1, TS811_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(430), MHz(440), TS811_ALL_MODES, W(5), W(25), TS811_VFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(430), MHz(450), TS811_ALL_MODES, -1, -1, TS811_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(430), MHz(450), TS811_ALL_MODES, W(5), W(25), TS811_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS811_ALL_MODES, 50}, {TS811_ALL_MODES, 100}, {TS811_ALL_MODES, kHz(1)}, {TS811_ALL_MODES, kHz(5)}, {TS811_ALL_MODES, kHz(9)}, {TS811_ALL_MODES, kHz(10)}, {TS811_ALL_MODES, 12500}, {TS811_ALL_MODES, kHz(20)}, {TS811_ALL_MODES, kHz(25)}, {TS811_ALL_MODES, kHz(100)}, {TS811_ALL_MODES, MHz(1)}, {TS811_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts811_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts811_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/level_gran_kenwood.h0000644000175000017500000001100314752216205016326 00000000000000 // Once included these values can be overridden in the back-end // Known variants are PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, #if !defined(NO_LVL_ATT) [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 12 }, .step = { .i = 0 } }, #endif [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, /* levels with WPM units */ #if !defined(NO_LVL_KEYSPD) [LVL_KEYSPD] = { .min = { .i = 4 }, .max = { .i = 60 }, .step = { .i = 1 } }, #endif /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1050 }, .step = { .i = 50 } }, #endif [LVL_IF] = { .min = { .i = -1000 }, .max = { .i = 1000 }, .step = { .i = 1 } }, [LVL_NOTCHF] = { .min = { .i = 1 }, .max = { .i = 3200 }, .step = { .i = 10 } }, #if !defined(NO_LVL_SLOPE_LOW) [LVL_SLOPE_LOW] = { .min = { .i = 10}, .max = { .i = 1000 }, .step = { .i = 50 } }, #endif #if !defined(NO_LVL_SLOPE_HIGH) [LVL_SLOPE_HIGH] = { .min = { .i = 1000 }, .max = { .i = 5000 }, .step = { .i = 10 } }, #endif /* levels with time units */ #if !defined(NO_LVL_VOXDELAY) [LVL_VOXDELAY] = { .min = { .i = 3 }, .max = { .i = 300 }, .step = { .i = 1 } }, #endif [LVL_BKINDL] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, #if !defined(NO_LVL_BKIN_DLYMS) [LVL_BKIN_DLYMS] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, #endif /* level with misc units */ [LVL_SWR] = { .min = { .f = 0 }, .max = { .f = 5.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_BAND_SELECT] = { .min = { .i = 0 }, .max = { .i = 16 }, .step = { .i = 1 } }, /* levels with 0-1 values -- increment based on rig's range */ #if !defined(NO_LVL_NR) [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/10.0f } }, #endif #if !defined(NO_LVL_NB) [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/10.0f } }, #endif #if !defined(NO_LVL_AF) [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, #endif #if !defined(NO_LVL_RF) [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, #endif [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, [LVL_COMP_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_ID_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_VD_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, #if !defined(NO_LVL_SQL) [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } }, #endif [LVL_MICGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #if !defined(NO_LVL_COMP) [LVL_COMP] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #endif [LVL_VOXGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ANTIVOX] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ALC] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, #if !defined(NO_LVL_USB_AF) [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/10.0f } }, #endif #if !defined(NO_LVL_USB_AF_INPUT) [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/10.0f } }, #endif hamlib-4.6.2/rigs/kenwood/ts50s.c0000644000175000017500000002016314752216205013442 00000000000000/* * Hamlib Kenwood backend - TS50 description * Copyright (c) 2002-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS50_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS50_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define TS50_AM_TX_MODES RIG_MODE_AM #define TS50_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_TSQL|RIG_FUNC_TONE|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_LOCK|RIG_FUNC_BC) #define TS50_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN) #define TS50_VFO (RIG_VFO_A|RIG_VFO_B) #define TS50_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) static struct kenwood_priv_caps ts50_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * ts50 rig capabilities. * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts50s_caps = { RIG_MODEL(RIG_MODEL_TS50), .model_name = "TS-50S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = TS50_FUNC_ALL, .has_set_func = TS50_FUNC_ALL, .has_get_level = TS50_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS50_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { 18, RIG_DBLST_END, }, .max_rit = kHz(1.1), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TS50_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS50_ALL_MODES, -1, -1, TS50_VFO}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, /* 25W class */ {kHz(3500), kHz(3800) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(3500), kHz(3800) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(7), kHz(7100), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(7), kHz(7100), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(14), kHz(14350), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(14), kHz(14350), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(21), kHz(21450), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(21), kHz(21450), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(28), kHz(29700), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(28), kHz(29700), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS50_ALL_MODES, -1, -1, TS50_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(3500), MHz(4) - 1, TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(7), kHz(7300), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(7), kHz(7300), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(10100), kHz(10150), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(14), kHz(14350), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(14), kHz(14350), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(18068), kHz(18168), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(21), kHz(21450), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(21), kHz(21450), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {kHz(24890), kHz(24990), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, {MHz(28), kHz(29700), TS50_OTHER_TX_MODES, 5000, 100000, TS50_VFO}, {MHz(28), kHz(29700), TS50_AM_TX_MODES, 5000, 25000, TS50_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS50_ALL_MODES, 50}, {TS50_ALL_MODES, 100}, {TS50_ALL_MODES, kHz(1)}, {TS50_ALL_MODES, kHz(5)}, {TS50_ALL_MODES, kHz(9)}, {TS50_ALL_MODES, kHz(10)}, {TS50_ALL_MODES, 12500}, {TS50_ALL_MODES, kHz(20)}, {TS50_ALL_MODES, kHz(25)}, {TS50_ALL_MODES, kHz(100)}, {TS50_ALL_MODES, MHz(1)}, {TS50_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.2)}, {RIG_MODE_AM, kHz(5)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts50_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split, .get_split_vfo = kenwood_get_split_vfo_if, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/README.kenwood0000644000175000017500000000146714752216205014653 00000000000000hamlib - Copyright (C) 2000 Frank Singleton libkenwood.so - Copyright (C) 2000 Stephane Fillod This shared library provides an API for communicating via serial interface to a Kenwood rig. Reference Documentation ----------------------- Kenwood CAT protocol (manual). Status ------ All primitives are written from spec. Some testing has been done with a TS-870S. At least reading and setting of frequency, mode, VFO, audio- and RF level should work. Patches and contributions are welcome! I'm also looking for a real maintainer :) --SF This lib should/will support other Kenwood models as well. Warnings -------- 1. This library should be tested with more kenwood rigs. 2. Error codes returned by the rig are not yet handled. Contributors ------------ Joop Stakenborg, PA4TU for TS-870S. hamlib-4.6.2/rigs/kenwood/ic10.h0000644000175000017500000000554214752216205013231 00000000000000/* * Hamlib Kenwood backend - IC-10 header * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _IC10_H #define _IC10_H 1 #define IC10_VER "20231002" int ic10_cmd_trim (char *data, int data_len); int ic10_transaction (RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len); int ic10_set_vfo(RIG *rig, vfo_t vfo); int ic10_get_vfo(RIG *rig, vfo_t *vfo); int ic10_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int ic10_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int ic10_set_split_vfo(RIG *rig, vfo_t vfo , split_t split, vfo_t txvfo); int ic10_get_split_vfo(RIG *rig, vfo_t vfo , split_t *split, vfo_t *txvfo); int ic10_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int ic10_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int ic10_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int ic10_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int ic10_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int ic10_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int ic10_set_parm(RIG *rig, setting_t parm, value_t val); int ic10_get_parm(RIG *rig, setting_t parm, value_t *val); int ic10_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int ic10_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int ic10_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int ic10_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int ic10_set_mem(RIG *rig, vfo_t vfo, int ch); int ic10_get_mem(RIG *rig, vfo_t vfo, int *ch); int ic10_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int ic10_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int ic10_set_powerstat(RIG *rig, powerstat_t status); int ic10_get_powerstat(RIG *rig, powerstat_t *status); int ic10_set_trn(RIG *rig, int trn); int ic10_get_trn(RIG *rig, int *trn); int ic10_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int ic10_scan(RIG * rig, vfo_t vfo, scan_t scan, int ch); const char* ic10_get_info(RIG *rig); int ic10_decode_event (RIG *rig); #define IC10_CHANNEL_CAPS \ .freq=1,\ .tx_freq=1,\ .mode=1,\ .tx_mode=1 #endif /* _IC10_H */ hamlib-4.6.2/rigs/kenwood/tmd700.c0000644000175000017500000001624714752216205013507 00000000000000/* * Hamlib Kenwood backend - TM-D700 description * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "tones.h" #define TMD700_MODES (RIG_MODE_FM|RIG_MODE_AM) #define TMD700_MODES_TX (RIG_MODE_FM) /* TBC */ #define TMD700_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_AIP| \ RIG_FUNC_MON| \ RIG_FUNC_MUTE| \ RIG_FUNC_SQL| \ RIG_FUNC_TONE| \ RIG_FUNC_TBURST| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO) #define TMD700_LEVEL_ALL (RIG_LEVEL_STRENGTH| \ RIG_LEVEL_SQL| \ RIG_LEVEL_AF| \ RIG_LEVEL_RF|\ RIG_LEVEL_MICGAIN) #define TMD700_PARMS (RIG_PARM_BACKLIGHT|\ RIG_PARM_BEEP|\ RIG_PARM_APO) #define TMD700_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TMD700_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define TMD700_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, /* * TODO: Band A & B */ #define TMD700_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t tmd700_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_AM, }; static struct kenwood_priv_caps tmd700_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = tmd700_mode_table, }; /* * TM-D700 rig capabilities. * * specs: http://www.geocities.jp/hkwatarin/TM-D700/English/spec.htm * protocol: http://www.qsl.net/k/k7jar//pages/D700Cmds.html */ struct rig_caps tmd700_caps = { RIG_MODEL(RIG_MODEL_TMD700), .model_name = "TM-D700", .mfg_name = "Kenwood", .version = TH_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE | RIG_FLAG_APRS | RIG_FLAG_TNC, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 57600, .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 = 1000, .retry = 3, .has_get_func = TMD700_FUNC_ALL, .has_set_func = TMD700_FUNC_ALL, .has_get_level = TMD700_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TMD700_LEVEL_ALL), .has_get_parm = TMD700_PARMS, .has_set_parm = TMD700_PARMS, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TMD700_VFO_OP, .scan_ops = RIG_SCAN_VFO, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 1, 199, RIG_MTYPE_MEM, {TMD700_CHANNEL_CAPS}}, /* normal MEM */ { 200, 219, RIG_MTYPE_EDGE, {TMD700_CHANNEL_CAPS}}, /* U/L MEM */ { 221, 222, RIG_MTYPE_CALL, {TMD700_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ RIG_CHAN_END, }, /* * TODO: Japan & TM-D700S, and Taiwan models */ .rx_range_list1 = { {MHz(118), MHz(470), TMD700_MODES, -1, -1, RIG_VFO_A}, {MHz(136), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(300), MHz(524), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(800), MHz(1300), RIG_MODE_FM, -1, -1, RIG_VFO_B}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TMD700_MODES_TX, W(5), W(50), RIG_VFO_A}, {MHz(430), MHz(440), TMD700_MODES_TX, W(5), W(35), RIG_VFO_A}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(118), MHz(470), TMD700_MODES, -1, -1, RIG_VFO_A}, {MHz(136), MHz(174), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(300), MHz(524), RIG_MODE_FM, -1, -1, RIG_VFO_B}, {MHz(800), MHz(1300), RIG_MODE_FM, -1, -1, RIG_VFO_B}, /* TODO: cellular blocked */ RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TMD700_MODES_TX, W(5), W(50), RIG_VFO_A}, {MHz(430), MHz(450), TMD700_MODES_TX, W(5), W(35), RIG_VFO_A}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TMD700_MODES, kHz(5)}, {TMD700_MODES, kHz(6.25)}, {TMD700_MODES, kHz(10)}, {TMD700_MODES, kHz(12.5)}, {TMD700_MODES, kHz(15)}, {TMD700_MODES, kHz(20)}, {TMD700_MODES, kHz(25)}, {TMD700_MODES, kHz(30)}, {TMD700_MODES, kHz(50)}, {TMD700_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM, kHz(9)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& tmd700_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = th_set_freq, .get_freq = th_get_freq, .set_mode = th_set_mode, .get_mode = th_get_mode, .set_vfo = tm_set_vfo_bc2, .get_vfo = th_get_vfo, .set_split_vfo = th_set_split_vfo, .get_split_vfo = th_get_split_vfo, .set_ctcss_tone = th_set_ctcss_tone, .get_ctcss_tone = th_get_ctcss_tone, .set_ctcss_sql = th_set_ctcss_sql, .get_ctcss_sql = th_get_ctcss_sql, .set_dcs_sql = th_set_dcs_sql, .get_dcs_sql = th_get_dcs_sql, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_trn = th_set_trn, .get_trn = th_get_trn, .set_func = th_set_func, .get_func = th_get_func, .set_level = th_set_level, .get_level = th_get_level, .set_parm = th_set_parm, .get_parm = th_get_parm, .get_info = th_get_info, .get_dcd = th_get_dcd, .set_ptt = th_set_ptt, .vfo_op = th_vfo_op, .scan = th_scan, .decode_event = th_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* end of file */ hamlib-4.6.2/rigs/kenwood/xg3.c0000644000175000017500000004060314752216205013166 00000000000000/* * Hamlib Kenwood backend - Elecraft XG3 description * Copyright (c) 2002-2009 by Stephane Fillod * Copyright (c) 2010 by Nate Bargmann, n0nb@arrl.net * Copyright (c) 2014 by Michael BlacK, W9MDB, mdblack98@yahoo.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include #include "serial.h" #include "kenwood.h" #include "elecraft.h" #define XG3_LEVEL_ALL (RIG_LEVEL_RFPOWER) #define XG3_PARM_ALL (RIG_PARM_BACKLIGHT) #define XG3_VFO (RIG_VFO_A|RIG_VFO_MEM) #define XG3_CHANNEL_CAPS { \ .freq=1\ } #define NB_CHAN 12 /* see caps->chan_list */ #if 0 struct xg3_priv_data { /* current vfo already in rig_state ? */ vfo_t last_vfo; ptt_t ptt; powerstat_t powerstat; value_t parms[RIG_SETTING_MAX]; channel_t *curr; /* points to vfo_a, vfo_b or mem[] */ channel_t vfo_a; channel_t mem[NB_CHAN]; char *magic_conf; }; #endif /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps xg3_priv_caps = { .cmdtrm = EOM_KEN, }; /* XG3 specific rig_caps API function declarations */ int xg3_init(RIG *rig); int xg3_open(RIG *rig); int xg3_set_vfo(RIG *rig, vfo_t vfo); int xg3_get_vfo(RIG *rig, vfo_t *vfo); int xg3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int xg3_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int xg3_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int xg3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int xg3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int xg3_set_powerstat(RIG *rig, powerstat_t status); int xg3_get_powerstat(RIG *rig, powerstat_t *status); int xg3_set_mem(RIG *rig, vfo_t vfo, int ch); int xg3_get_mem(RIG *rig, vfo_t vfo, int *ch); int xg3_set_parm(RIG *rig, setting_t parm, value_t val); int xg3_get_parm(RIG *rig, setting_t parm, value_t *val); /* * XG3 rig capabilities. * This kit can recognize a small subset of TS-570 commands. * * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K2 * look for KIO2 Programmer's Reference PDF */ struct rig_caps xg3_caps = { RIG_MODEL(RIG_MODEL_XG3), .model_name = "XG3", .mfg_name = "Elecraft", .version = "20230305.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 25, /* Timing between command strings */ .timeout = 25, .retry = 3, .has_get_level = XG3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(XG3_LEVEL_ALL), .has_get_parm = XG3_PARM_ALL, .has_set_parm = XG3_PARM_ALL, .level_gran = { #include "level_gran_elecraft.h" }, /* FIXME: granularity */ .parm_gran = {}, .extparms = kenwood_cfg_params, .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { {0, 11, RIG_MTYPE_MEM, XG3_CHANNEL_CAPS}, RIG_CHAN_END, }, .tx_range_list1 = { // lo power is actually 5e-14W which can't be represented in hamlib as of 20200325 {kHz(1500), MHz(200), RIG_MODE_CW, 0, 2, RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_ALL, 0}, RIG_TS_END }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = (void *)& xg3_priv_caps, .rig_init = xg3_init, .rig_cleanup = kenwood_cleanup, .rig_open = xg3_open, .set_freq = xg3_set_freq, .get_freq = xg3_get_freq, .set_mem = xg3_set_mem, .get_mem = xg3_get_mem, .set_vfo = xg3_set_vfo, .get_vfo = xg3_get_vfo, .get_ptt = xg3_get_ptt, .set_ptt = xg3_set_ptt, .set_level = xg3_set_level, .get_level = xg3_get_level, .set_powerstat = xg3_set_powerstat, .get_powerstat = xg3_get_powerstat, .set_parm = xg3_set_parm, .get_parm = xg3_get_parm, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * xg3_init() */ int xg3_init(RIG *rig) { struct kenwood_priv_data *priv; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct kenwood_priv_data *)calloc(1, sizeof(struct kenwood_priv_data)); if (!priv) { return -RIG_ENOMEM; } STATE(rig)->priv = (void *)priv; RIGPORT(rig)->type.rig = RIG_PORT_SERIAL; // Tried set_trn to turn transceiver on/off but turning it on isn't enabled in hamlib for some reason // So we use PTT instead // STATE(rig)->transceive = RIG_TRN_RIG; // this allows xg3_set_trn to be called STATE(rig)->current_vfo = RIG_VFO_A; // priv->last_vfo = RIG_VFO_A; // priv->ptt = RIG_PTT_ON; // priv->powerstat = RIG_POWER_ON; priv->no_id = 1; //memset(priv->parms, 0, RIG_SETTING_MAX * sizeof(value_t)); for (i = 0; i < NB_CHAN; i++) { //priv->mem[i].channel_num = i; //priv->mem[i].vfo = RIG_VFO_MEM; } return RIG_OK; } /* * XG3 extension function definitions follow */ /* * xg3_open() */ int xg3_open(RIG *rig) { int err; ptt_t ptt; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elecraft_open(rig); if (err != RIG_OK) { return err; } xg3_get_ptt(rig, RIG_VFO_A, &ptt); // set our PTT status return RIG_OK; } int xg3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RFPOWER: if (val.f < 0 || val.f > 3) { return -RIG_EINVAL; } /* XXX check level range */ SNPRINTF(levelbuf, sizeof(levelbuf), "L,%02d", (int)val.f); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return kenwood_transaction(rig, levelbuf, NULL, 0); } /* * kenwood_get_level */ int xg3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char cmdbuf[32], replybuf[32]; int retval; size_t replysize = sizeof(replybuf); struct hamlib_port *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), "L;"); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s write_block failed\n", __func__); return retval; } retval = read_string(rp, (unsigned char *) replybuf, replysize, ";", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); return retval; } sscanf(replybuf, "L,%f", &val->f); return RIG_OK; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_AF: case RIG_LEVEL_RF: case RIG_LEVEL_SQL: case RIG_LEVEL_MICGAIN: case RIG_LEVEL_AGC: case RIG_LEVEL_SLOPE_LOW: case RIG_LEVEL_SLOPE_HIGH: case RIG_LEVEL_CWPITCH: case RIG_LEVEL_KEYSPD: case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_COMP: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * xg3_get_vfo */ int xg3_get_vfo(RIG *rig, vfo_t *vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } *vfo = STATE(rig)->current_vfo; // VFOA or MEM return RIG_OK; } /* * xg3_set_vfo */ int xg3_set_vfo(RIG *rig, vfo_t vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!vfo) { return -RIG_EINVAL; } if (vfo != RIG_VFO_A) { return -RIG_EINVAL; } // We don't actually set the vfo on the XG3 // But we need this so we can set frequencies on the band buttons STATE(rig)->current_vfo = vfo; return RIG_OK; } /* * xg3_set_freq */ int xg3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int err; vfo_t tvfo; char cmdbuf[20]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; switch (tvfo) { case RIG_VFO_A: break; case RIG_VFO_MEM: break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (tvfo == RIG_VFO_MEM) { int ch; xg3_get_mem(rig, vfo, &ch); SNPRINTF(cmdbuf, sizeof(cmdbuf), "M,%02d,%011ld", ch, (long)freq); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "F,%011ld", (long)freq); } err = kenwood_transaction(rig, cmdbuf, NULL, 0); return err; } /* * xg3_get_freq */ int xg3_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct hamlib_port *rp; char freqbuf[50]; int freqsize = sizeof(freqbuf); char cmdbuf[16]; int retval; int offset; vfo_t tvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!freq) { return -RIG_EINVAL; } tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; rp = RIGPORT(rig); switch (tvfo) { case RIG_VFO_A: break; case RIG_VFO_MEM: break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (tvfo == RIG_VFO_MEM) { int ch; xg3_get_mem(rig, vfo, &ch); SNPRINTF(cmdbuf, sizeof(cmdbuf), "M,%02d;", ch); } else { SNPRINTF(cmdbuf, sizeof(cmdbuf), "F;"); } retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s write_block failed\n", __func__); return retval; } retval = read_string(rp, (unsigned char *) freqbuf, freqsize, ";", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); return retval; } offset = tvfo == RIG_VFO_A ? 2 : 5; sscanf(freqbuf + offset, "%" SCNfreq, freq); return RIG_OK; } /* * xg3_set_powerstat */ int xg3_set_powerstat(RIG *rig, powerstat_t status) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (status == RIG_POWER_OFF) { const char *cmd = "X"; //priv->powerstat = RIG_POWER_OFF; return kenwood_transaction(rig, cmd, NULL, 0); } rig_debug(RIG_DEBUG_VERBOSE, "%s invalid powerstat request status=%d\n", __func__, status); return -RIG_EINVAL; } /* * xg3_get_powerstat */ int xg3_get_powerstat(RIG *rig, powerstat_t *status) { const char *cmd = "G"; // any command to test will do char buf[6]; int retval = kenwood_transaction(rig, cmd, buf, 5); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (retval == RIG_OK) { *status = RIG_POWER_ON; //priv->powerstat = RIG_POWER_ON; } else { *status = RIG_POWER_OFF; // Error indicates power is off rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); //priv->powerstat = RIG_POWER_OFF; } return RIG_OK; // Always OK since it's a binary state } /* * xg3_set_mem */ int xg3_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[32]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (ch < 0 || ch > 11) { rig_debug(RIG_DEBUG_VERBOSE, "%s invalid channel#%02d\n", __func__, ch); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "C,%02d;", ch); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s invalid set_mem cmd=%s\n", __func__, cmdbuf); return -RIG_EINVAL; } return RIG_OK; } /* * xg3_get_mem */ int xg3_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmdbuf[32]; char reply[32]; int retval; struct hamlib_port *rp = RIGPORT(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmdbuf, sizeof(cmdbuf), "C;"); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } retval = read_string(rp, (unsigned char *) reply, sizeof(reply), ";", 1, 0, 1); if (retval < 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s read_string failed\n", __func__); return retval; } sscanf(reply, "C,%d", ch); return RIG_OK; } /* * xg3_set_ptt */ int xg3_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_simple_transaction(rig, (ptt == RIG_PTT_ON) ? "O,01" : "O,00", 0); if (retval == RIG_OK) { //priv->ptt = RIG_PTT_ON; } return retval; } /* * kenwood_get_ptt */ int xg3_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ptt) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "O", pttbuf, 6, 4); if (retval != RIG_OK) { return retval; } *ptt = pttbuf[3] == '1' ? RIG_PTT_ON : RIG_PTT_OFF; //priv->ptt = *ptt; return RIG_OK; } /* * xg3_set_parm */ int xg3_set_parm(RIG *rig, setting_t parm, value_t val) { int ival; char cmdbuf[16]; int retval = -RIG_EINVAL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_BACKLIGHT: ival = 3 - (int)(val.f * 3); // gives us 0-3 bright-to-dim rig_debug(RIG_DEBUG_ERR, "%s: BACKLIGHT %d\n", __func__, ival); SNPRINTF(cmdbuf, sizeof(cmdbuf), "G,%02d", ival); retval = kenwood_simple_transaction(rig, cmdbuf, 0); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return retval; } /* * xg3_get_parm */ int xg3_get_parm(RIG *rig, setting_t parm, value_t *val) { int ival; char replybuf[6]; int retval = -RIG_EINVAL; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (parm) { case RIG_PARM_BACKLIGHT: retval = kenwood_safe_transaction(rig, "G", replybuf, 6, 4); if (retval == RIG_OK) { sscanf(&replybuf[3], "%d", &ival); val->f = (3.0f - (float) ival) / 3.0f; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return retval; } hamlib-4.6.2/rigs/kenwood/thd74.c0000644000175000017500000011623414752216205013423 00000000000000/* * Hamlib Kenwood TH-D74 backend * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2018 by Sebastian Denz, based on THD72 from Brian Lucas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "misc.h" #define THD74_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_LSB|RIG_MODE_USB|RIG_MODE_CW|RIG_MODE_FMN|RIG_MODE_WFM|RIG_MODE_CWR) #define THD74_MODES_TX (RIG_MODE_FM) #define THD74_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_TONE) #define THD74_LEVEL_ALL (RIG_LEVEL_RFPOWER|\ RIG_LEVEL_SQL|\ RIG_LEVEL_ATT|\ RIG_LEVEL_VOXGAIN|\ RIG_LEVEL_VOXDELAY) #define THD74_PARMS (RIG_PARM_TIME) #define THD74_VFO_OP (RIG_OP_NONE) #define THD74_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t thd74_mode_table[10] = { [0] = RIG_MODE_FM, /* normal, but narrow compared to broadcast */ // [1] = RIG_MODE_DV, [2] = RIG_MODE_AM, [3] = RIG_MODE_LSB, [4] = RIG_MODE_USB, [5] = RIG_MODE_CW, [6] = RIG_MODE_FMN, /* what kenwood calls narrow */ // [7] = RIG_MODE_DR, [8] = RIG_MODE_WFM, [9] = RIG_MODE_CWR, }; static pbwidth_t thd74_width_table[10] = { [0] = 10000, // +-5KHz [1] = 5000, // +-2.5KHz [2] = 10000, // FIXME: what should this be? [3] = 10000, // FIXME: what should this be? [4] = 10000, // FIXME: what should this be? [5] = 10000, // FIXME: what should this be? [6] = 10000, // FIXME: what should this be? [7] = 10000, // FIXME: what should this be? [8] = 10000, // FIXME: what should this be? [9] = 10000, // FIXME: what should this be? }; static rptr_shift_t thd74_rshf_table[3] = { [0] = RIG_RPT_SHIFT_NONE, [1] = RIG_RPT_SHIFT_PLUS, [2] = RIG_RPT_SHIFT_MINUS, }; static int thd74tuningstep_fine[4] = { [0] = 20, [1] = 100, [2] = 500, [3] = 1000, }; static int thd74tuningstep[11] = { [0] = 5000, [1] = 6250, [2] = 8330, [3] = 9000, [4] = 10000, [5] = 15000, [6] = 20000, [7] = 25000, [8] = 30000, [9] = 50000, [10] = 100000, }; static int thd74voxdelay[7] = { [0] = 2500, [1] = 5000, [2] = 7500, [3] = 10000, [4] = 15000, [5] = 20000, [6] = 30000 }; static float thd74sqlevel[6] = { [0] = 0.0, /* open */ [1] = 0.2, [2] = 0.4, [3] = 0.6, [4] = 0.8, [5] = 1.0 }; static tone_t thd74dcs_list[105] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0 }; static struct kenwood_priv_caps thd74_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thd74_mode_table, }; int thd74_open(RIG *rig) { //int ret; //struct kenwood_priv_data *priv = STATE(rig)->priv; // this is already done in kenwood_init //strcpy(priv->verify_cmd, "ID\r"); //ret = kenwood_transaction(rig, "", NULL, 0); return RIG_OK; } static int thd74_set_vfo(RIG *rig, vfo_t vfo) { const char *cmd; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: cmd = "BC 0"; break; case RIG_VFO_B: cmd = "BC 1"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return kenwood_simple_transaction(rig, cmd, 4); } static int thd74_get_vfo(RIG *rig, vfo_t *vfo) { int retval; char c, buf[10]; size_t length; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "BC", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length == 4) { c = buf[3]; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length %d\n", __func__, (int)length); return -RIG_EPROTO; } switch (c) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EVFO; } return RIG_OK; } static int thd74_vfoc(RIG *rig, vfo_t vfo, char *vfoc) { vfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (vfo) { case RIG_VFO_A: *vfoc = '0'; break; case RIG_VFO_B: *vfoc = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return RIG_OK; } static int thd74_get_freq_info(RIG *rig, vfo_t vfo, char *buf) { int retval; char c, cmd[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "FO %c", c); retval = kenwood_transaction(rig, cmd, buf, 73); return retval; } /* item is an offset into reply buf that is a single char */ static int thd74_get_freq_item(RIG *rig, vfo_t vfo, int item, int hi, int *val) { int retval, lval; char c, buf[128]; retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } c = buf[item]; rig_debug(RIG_DEBUG_TRACE, "%s: c:%c\n", __func__, c); if (c < '0' || c > '9') { return -RIG_EPROTO; } lval = c - '0'; if (lval > hi) { return -RIG_EPROTO; } *val = lval; return RIG_OK; } static int thd74_set_freq_item(RIG *rig, vfo_t vfo, int item, int val) { int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[item] = val + '0'; return kenwood_simple_transaction(rig, buf, 72); } static int thd74_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int retval, tsinx, fine, fine_ts; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_item(rig, vfo, 16, 9, &tsinx); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: fail1\n", __func__); return retval; } retval = thd74_get_freq_item(rig, vfo, 33, 1, &fine); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: fail1\n", __func__); return retval; } retval = thd74_get_freq_item(rig, vfo, 35, 3, &fine_ts); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: fail1\n", __func__); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: tsinx is %d\n", __func__, tsinx); rig_debug(RIG_DEBUG_TRACE, "%s: fine is %d\n", __func__, fine); rig_debug(RIG_DEBUG_TRACE, "%s: fine_ts is %d\n", __func__, fine_ts); if (fine > 0) { *ts = thd74tuningstep_fine[fine_ts]; } else { *ts = thd74tuningstep[tsinx]; } rig_debug(RIG_DEBUG_TRACE, "%s: stepsize is %d\n", __func__, (int)*ts); return RIG_OK; } // needs rig and vfo to get correct stepsize static int thd74_round_freq(RIG *rig, vfo_t vfo, freq_t freq) { int64_t f; long double r; shortfreq_t ts; // cppcheck-suppress * char *fmt = "%s: rounded %"PRIll" to %"PRIll" because stepsize:%d\n"; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); thd74_get_ts(rig, vfo, &ts); f = (int64_t)freq; r = round((double)f / (double)ts); r = ts * r; rig_debug(RIG_DEBUG_TRACE, fmt, __func__, f, (int64_t)r, (int)ts); return (freq_t)r; } static int thd74_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; char buf[128], fbuf[12]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } freq = thd74_round_freq(rig, vfo, freq); SNPRINTF(fbuf, sizeof(fbuf), "%010"PRIll, (int64_t)freq); memcpy(buf + 5, fbuf, 10); retval = kenwood_simple_transaction(rig, buf, 72); return retval; } static int thd74_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { vfo = RIG_VFO_B; } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%"SCNfreq, freq); return RIG_OK; } // setting the mode via FO leads to response 'N.' from the handset int thd74_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char kmode, mdbuf[8], replybuf[8], v; int retval; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &v); if (retval != RIG_OK) { return retval; } if (priv->mode_table) { kmode = rmode2kenwood(mode, priv->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: Unsupported Mode value '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } kmode += '0'; } else { switch (mode) { case RIG_MODE_FM: kmode = '0'; break; case RIG_MODE_AM: kmode = '1'; break; // case RIG_MODE_DV: kmode = '2'; break; case RIG_MODE_LSB: kmode = '3'; break; case RIG_MODE_USB: kmode = '4'; break; case RIG_MODE_CW: kmode = '5'; break; case RIG_MODE_FMN: kmode = '6'; break; // case RIG_MODE_DR: kmode = '7'; break; case RIG_MODE_WFM: kmode = '8'; break; case RIG_MODE_CWR: kmode = '9'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } } SNPRINTF(mdbuf, sizeof(mdbuf), "MD %c,%c", v, kmode); rig_debug(RIG_DEBUG_ERR, "%s: mdbuf: %s\n", __func__, mdbuf); retval = kenwood_transaction(rig, mdbuf, replybuf, 7); rig_debug(RIG_DEBUG_ERR, "%s: retval: %d\n", __func__, retval); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int thd74_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; char modec, buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } modec = buf[31]; if (modec >= '0' && modec <= '9') { *mode = thd74_mode_table[modec - '0']; *width = thd74_width_table[modec - '0']; } else { return -RIG_EINVAL; } return RIG_OK; } static int thd74_set_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: rsinx = 0; break; case RIG_RPT_SHIFT_PLUS: rsinx = 1; break; case RIG_RPT_SHIFT_MINUS: rsinx = 2; break; default: return -RIG_EINVAL; } return thd74_set_freq_item(rig, vfo, 47, rsinx); } static int thd74_get_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int retval, rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_item(rig, vfo, 47, 3, &rsinx); if (retval != RIG_OK) { return retval; } /* rsinx == 3 indicates split mode? */ *rptr_shift = (rsinx == 3) ? RIG_RPT_SHIFT_NONE : thd74_rshf_table[rsinx]; return RIG_OK; } static int thd74_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { int retval; char boff[11], buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } SNPRINTF(boff, sizeof(boff), "%010ld", offs); memcpy(buf + 16, boff, 10); retval = kenwood_simple_transaction(rig, buf, 72); return retval; } static int thd74_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs) { int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 16, "%ld", offs); return RIG_OK; } static int thd74_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int tsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (tsinx = 0; tsinx < 4; tsinx++) { if (thd74tuningstep_fine[tsinx] >= ts) { thd74_set_freq_item(rig, vfo, 33, 1); // Turn fine mode on thd74_set_freq_item(rig, vfo, 35, tsinx); return RIG_OK; } } for (tsinx = 0; tsinx < 10; tsinx++) { if (thd74tuningstep[tsinx] >= ts) { thd74_set_freq_item(rig, vfo, 33, 0); //Turn fine mode off thd74_set_freq_item(rig, vfo, 27, tsinx); return RIG_OK; } } return -RIG_EINVAL; } static int thd74_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[22] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 30, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd74_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[22] == '0') /* no tone */ { *tone = 0; } else { sscanf(buf + 30, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } static int thd74_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int retval, cinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cinx = 0; /* default */ if (code != 0) { for (cinx = 0; cinx < 104; cinx++) { if (code == thd74dcs_list[cinx]) { break; } } if (cinx >= 104) { return -RIG_EINVAL; } } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[26] = (code == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%03d", cinx); memcpy(buf + 36, tmp, 3); return kenwood_simple_transaction(rig, buf, 52); } static int thd74_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int retval, cinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[26] == '0') /* no tone */ { *code = 0; } else { sscanf(buf + 36, "%d", &cinx); *code = thd74dcs_list[cinx]; } return RIG_OK; } static int thd74_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[24] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 33, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd74_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[24] == '0') /* no tsql */ { *tone = 0; } else { sscanf(buf + 33, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } int thd74_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TX"; return kenwood_simple_transaction(rig, ptt_cmd, 4); break; case RIG_PTT_OFF: ptt_cmd = "RX"; return kenwood_simple_transaction(rig, ptt_cmd, 2); break; default: return -RIG_EINVAL; } } static int thd74_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, lvl; char c, lvlc, cmd[11]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: level: %s\n", __func__, rig_strlevel(level)); rig_debug(RIG_DEBUG_TRACE, "%s: value.i: %d\n", __func__, val.i); rig_debug(RIG_DEBUG_TRACE, "%s: value.f: %lf\n", __func__, val.f); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: if (val.f <= 0.01) { lvlc = '3'; } else if (val.f <= 0.1) { lvlc = '2'; } else if (val.f <= 0.4) { lvlc = '1'; } else { lvlc = '0'; } SNPRINTF(cmd, sizeof(cmd), "PC %c,%c", c, lvlc); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_VOXGAIN: SNPRINTF(cmd, sizeof(cmd), "VG %d", (int)(val.f * 10.0 - 0.5)); return kenwood_simple_transaction(rig, cmd, 4); case RIG_LEVEL_VOXDELAY: if (val.i > 20000) { lvl = 6; } else if (val.i > 10000) { lvl = val.i / 10000 + 3; } else { lvl = val.i / 2500; } SNPRINTF(cmd, sizeof(cmd), "VD %d", lvl); return kenwood_simple_transaction(rig, cmd, 4); case RIG_LEVEL_SQL: SNPRINTF(cmd, sizeof(cmd), "SQ %c,%d", c, (int)val.f); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_ATT: // no value provided to distinguish between on/off?? SNPRINTF(cmd, sizeof(cmd), "RA %c,%d", c, (int)val.f); return kenwood_simple_transaction(rig, cmd, 6); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } static int thd74_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, v, l; char c, cmd[10], buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmd, sizeof(cmd), "PC %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "PC %d,%d", &v, &l); if (retval != 2 || l < 0 || l > 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } switch (l) { case 0: val->f = 1.00; break; /* 5.0 W */ case 1: val->f = 0.40; break; /* 2.0 W */ case 2: val->f = 0.1; break; /* 500 mW */ case 3: val->f = 0.01; break; /* 50 mW */ } break; case RIG_LEVEL_VOXGAIN: SNPRINTF(cmd, sizeof(cmd), "VG"); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: VOXGAIN buf:%s\n", __func__, buf); /* FIXME - if VOX is off, what do we return */ val->f = (buf[0] - '0') / 9.0; break; case RIG_LEVEL_VOXDELAY: SNPRINTF(cmd, sizeof(cmd), "VD"); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } /* FIXME - if VOX is off, what do we return */ rig_debug(RIG_DEBUG_TRACE, "%s: VOXDELAY buf:%s\n", __func__, buf); val->i = thd74voxdelay[buf[0] - '0']; break; case RIG_LEVEL_SQL: SNPRINTF(cmd, sizeof(cmd), "SQ %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "SQ %d,%d", &v, &l); if (retval != 2 || l < 0 || l >= 6) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } val->f = thd74sqlevel[l]; break; case RIG_LEVEL_ATT: SNPRINTF(cmd, sizeof(cmd), "RA %c", c); retval = kenwood_transaction(rig, cmd, buf, 7); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%d", &val->i); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } static int thd74_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_TONE: return thd74_set_freq_item(rig, vfo, 37, status); case RIG_FUNC_TSQL: return thd74_set_freq_item(rig, vfo, 39, status); default: return -RIG_EINVAL; } return RIG_OK; } static int thd74_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval, f; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_TONE: retval = thd74_get_freq_item(rig, vfo, 37, 1, &f); break; case RIG_FUNC_TSQL: retval = thd74_get_freq_item(rig, vfo, 39, 1, &f); break; default: return -RIG_EINVAL; } if (retval != RIG_OK) { return retval; } *status = f; return RIG_OK; } static int thd74_set_parm(RIG *rig, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_TIME: // FIXME check val, send formatted via RT default: return -RIG_EINVAL; } return RIG_OK; } static int thd74_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval, hh, mm, ss; char buf[48]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_TIME: retval = kenwood_transaction(rig, "RT", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 11, "%2d%2d%2d", &hh, &mm, &ss); val->i = ss + 60 * (mm + 60 * hh); break; default: return -RIG_EINVAL; } return RIG_OK; } static int thd74_set_mem(RIG *rig, vfo_t vfo, int ch) { int retval; char c, cmd[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c,%03d", c, ch); return kenwood_simple_transaction(rig, cmd, 8); } static int thd74_get_mem(RIG *rig, vfo_t vfo, int *ch) { int retval; char c, cmd[10], buf[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd74_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 3, "%d", ch); return RIG_OK; } static int thd74_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return -RIG_EINVAL; } static int thd74_parse_channel(int kind, const char *buf, channel_t *chan) { int tmp; char c; const char *data; if (kind == 0) { data = buf + 5; } else { data = buf + 7; } sscanf(data, "%"SCNfreq, &chan->freq); c = data[46]; // mode if (c >= '0' && c <= '2') { chan->mode = thd74_mode_table[c - '0']; chan->width = thd74_width_table[c - '0']; } c = data[11]; // tuning step if (c >= '0' && c <= '9') { chan->tuning_step = thd74tuningstep[c - '0']; } c = data[13]; // repeater shift if (c >= '0' && c <= '2') { chan->rptr_shift = thd74_rshf_table[c - '0']; } sscanf(data + 37, "%ld", &chan->rptr_offs); c = data[17]; // Tone status if (c != '0') { sscanf(data + 25, "%d", &tmp); if (tmp > 0 && tmp < 42) { chan->ctcss_tone = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_tone = 0; } c = data[19]; // TSQL status if (c != '0') { sscanf(data + 28, "%d", &tmp); if (tmp > 0 && tmp < 42) { chan->ctcss_sql = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_sql = 0; } c = data[21]; // DCS status if (c != '0') { sscanf(data + 31, "%d", &tmp); chan->dcs_code = tmp; } else { chan->dcs_code = 0; } return RIG_OK; } static int thd74_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int retval; char buf[72]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (chan->vfo == RIG_VFO_MEM) /* memory channel */ { int len; char cmd[16]; SNPRINTF(cmd, sizeof(cmd), "ME %03d", chan->channel_num); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = thd74_parse_channel(1, buf, chan); if (retval != RIG_OK) { return retval; } cmd[1] = 'N'; /* change ME to MN */ retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } len = strlen(buf); memcpy(chan->channel_desc, buf + 7, len - 7); } else /* current channel */ { retval = thd74_get_freq_info(rig, chan->vfo, buf); if (retval != RIG_OK) { return retval; } return thd74_parse_channel(0, buf, chan); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int thd74_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (txvfo != RIG_VFO_A) { return -RIG_EINVAL; } priv->split = split; return RIG_OK; } int thd74_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { *txvfo = RIG_VFO_A; } else { return -RIG_EPROTO; } return RIG_OK; } /* if priv->split is RIG_SPLIT_ON set *tx_freq to freq of VFOA and return RIG_OK otherwise return -RIG_EPROTO */ int thd74_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; char buf[128]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { vfo = RIG_VFO_A; } else { return -RIG_EINVAL; } retval = thd74_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%"SCNfreq, tx_freq); return RIG_OK; } /* if priv->split is RIG_SPLIT_ON set freq of VFOA to txfreq and return RIG_OK otherwise return -RIG_EPROTO */ int thd74_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (priv->split == RIG_SPLIT_ON) { char fbuf[12], buf[128]; int retval = thd74_get_freq_info(rig, RIG_VFO_A, buf); if (retval != RIG_OK) { return retval; } tx_freq = thd74_round_freq(rig, RIG_VFO_A, tx_freq); SNPRINTF(fbuf, sizeof(fbuf), "%010"PRIll, (int64_t)tx_freq); memcpy(buf + 5, fbuf, 10); return kenwood_simple_transaction(rig, buf, 72); } return -RIG_EPROTO; } #ifdef false /* not working */ #define CMD_SZ 5 #define BLOCK_SZ 256 #define BLOCK_COUNT 256 #define CHAN_PER_BLOCK 4 static int thd74_get_block(RIG *rig, int block_num, char *block) { hamlib_port_t *rp = RIGPORT(rig); char cmd[CMD_SZ] = "R\0\0\0\0"; char resp[CMD_SZ]; int ret; /* fetching block i */ cmd[2] = block_num & 0xff; ret = write_block(rp, cmd, CMD_SZ); if (ret != RIG_OK) { return ret; } /* read response first */ ret = read_block(rp, resp, CMD_SZ); if (ret != CMD_SZ) { return ret; } if (resp[0] != 'W' || memcmp(cmd + 1, resp + 1, CMD_SZ - 1)) { return -RIG_EPROTO; } /* read block */ ret = read_block(rp, block, BLOCK_SZ); if (ret != BLOCK_SZ) { return ret; } ret = write_block(rp, "\006", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } return RIG_OK; } #ifdef XXREMOVEDXX int thd74_get_chan_all_cb(RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j, ret; hamlib_port_t *rp = RIGPORT(rig); channel_t *chan; chan_t *chan_list = STATE(rig)->chan_list; int chan_next = chan_list[0].start; char block[BLOCK_SZ]; char resp[CMD_SZ]; ret = kenwood_transaction(rig, "0M PROGRAM", resp, CMD_SZ); if (ret != RIG_OK) { return ret; } if (strlen(resp) != 2 || memcmp(resp, "0M", 2)) { return -RIG_EPROTO; } rp->parm.serial.rate = 57600; serial_setup(rp); hl_usleep(100 * 1000); /* let the pcr settle */ rig_flush(rp); /* flush any remaining data */ ret = ser_set_rts(rp, 1); /* setRTS or Hardware flow control? */ if (ret != RIG_OK) { return ret; } /* * setting chan to NULL means the application * has to provide a struct where to store data * future data for channel channel_num */ chan = NULL; ret = chan_cb(rig, &chan, chan_next, chan_list, arg); if (ret != RIG_OK) { return ret; } if (chan == NULL) { return -RIG_ENOMEM; } for (i = 0; i < BLOCK_COUNT; i++) { ret = thd74_get_block(rig, i, block); if (ret != RIG_OK) { return ret; } /* * Most probably, there's 64 bytes per channel (256*256 / 1000+) */ for (j = 0; j < CHAN_PER_BLOCK; j++) { char *block_chan = block + j * (BLOCK_SZ / CHAN_PER_BLOCK); memset(chan, 0, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; chan->channel_num = i * CHAN_PER_BLOCK + j; /* What are the extra 64 channels ? */ if (chan->channel_num >= 1000) { break; } /* non-empty channel ? */ // if (block_chan[0] != 0xff) { // since block_chan is *signed* char, this maps to -1 if (block_chan[0] != -1) { memcpy(chan->channel_desc, block_chan, 8); /* TODO: chop off trailing chars */ chan->channel_desc[8] = '\0'; /* TODO: parse block and fill in chan */ } /* notify the end? */ chan_next = chan_next < chan_list[i].end ? chan_next + 1 : chan_next; /* * provide application with channel data, * and ask for a new channel structure */ chan_cb(rig, &chan, chan_next, chan_list, arg); } } ret = write_block(rp, "E", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } /* setRTS?? getCTS needed? */ ret = ser_set_rts(rp, 1); if (ret != RIG_OK) { return ret; } return RIG_OK; } #endif #endif /* none working stuff */ /* * th-d74 rig capabilities. */ struct rig_caps thd74_caps = { RIG_MODEL(RIG_MODEL_THD74), .model_name = "TH-D74", .mfg_name = "Kenwood", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD | RIG_FLAG_APRS | RIG_FLAG_TNC | RIG_FLAG_DXCLUSTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_XONXOFF, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THD74_FUNC_ALL, .has_set_func = THD74_FUNC_ALL, .has_get_level = THD74_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THD74_LEVEL_ALL), .has_get_parm = THD74_PARMS, .has_set_parm = THD74_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = { [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, }, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THD74_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, /* TBC */ .chan_list = { { 0, 999, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* TBC MEM */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), THD74_MODES, -1, -1, THD74_VFO}, {MHz(320), MHz(524), THD74_MODES, -1, -1, THD74_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), THD74_MODES_TX, W(0.05), W(5), THD74_VFO}, {MHz(430), MHz(440), THD74_MODES_TX, W(0.05), W(5), THD74_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {THD74_MODES, kHz(5)}, {THD74_MODES, kHz(6.25)}, /* kHz(8.33) ?? */ {THD74_MODES, kHz(10)}, {THD74_MODES, kHz(12.5)}, {THD74_MODES, kHz(15)}, {THD74_MODES, kHz(20)}, {THD74_MODES, kHz(25)}, {THD74_MODES, kHz(30)}, {THD74_MODES, kHz(50)}, {THD74_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(14)}, {RIG_MODE_FMN, kHz(7)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .priv = (void *)& thd74_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = kenwood_open, .set_freq = thd74_set_freq, .get_freq = thd74_get_freq, .set_mode = thd74_set_mode, .get_mode = thd74_get_mode, .set_vfo = thd74_set_vfo, .get_vfo = thd74_get_vfo, .set_ptt = thd74_set_ptt, .set_rptr_shift = thd74_set_rptr_shft, .get_rptr_shift = thd74_get_rptr_shft, .set_rptr_offs = thd74_set_rptr_offs, .get_rptr_offs = thd74_get_rptr_offs, .set_ts = thd74_set_ts, .get_ts = thd74_get_ts, .set_ctcss_tone = thd74_set_ctcss_tone, .get_ctcss_tone = thd74_get_ctcss_tone, .set_dcs_code = thd74_set_dcs_code, .get_dcs_code = thd74_get_dcs_code, .set_ctcss_sql = thd74_set_ctcss_sql, .get_ctcss_sql = thd74_get_ctcss_sql, .set_level = thd74_set_level, .get_level = thd74_get_level, .set_func = thd74_set_func, .get_func = thd74_get_func, .set_parm = thd74_set_parm, .get_parm = thd74_get_parm, .set_mem = thd74_set_mem, .get_mem = thd74_get_mem, .set_channel = thd74_set_channel, .get_channel = thd74_get_channel, .set_split_vfo = thd74_set_split_vfo, .get_split_vfo = thd74_get_split_vfo, .set_split_freq = thd74_set_split_freq, .get_split_freq = thd74_get_split_freq, //.get_chan_all_cb = thd74_get_chan_all_cb, this doesn't work yet .get_info = th_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/r5000.c0000644000175000017500000001147614752216205013241 00000000000000/* * Hamlib Kenwood backend - R5000 description * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #include "ic10.h" #define R5000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define R5000_FUNC_ALL (RIG_FUNC_LOCK) #define R5000_LEVEL_ALL RIG_LEVEL_NONE #define R5000_PARM_ALL (RIG_PARM_TIME) #define R5000_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define R5000_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define R5000_SCAN_OPS (RIG_SCAN_VFO) #define R5000_ANTS (RIG_ANT_1|RIG_ANT_2) static struct kenwood_priv_caps r5000_priv_caps = { .cmdtrm = EOM_KEN, .if_len = 32, .tone_table_base = 1, }; /* * R5000 rig capabilities, with IF-10 interface (like TS440). * * TODO: scan, get/set_channel, RIT */ struct rig_caps r5000_caps = { RIG_MODEL(RIG_MODEL_R5000), .model_name = "R-5000", .mfg_name = "Kenwood", .version = IC10_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 2, .timeout = 500, .retry = 3, .has_get_func = R5000_FUNC_ALL, .has_set_func = R5000_FUNC_ALL, .has_get_level = R5000_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(R5000_LEVEL_ALL), .has_get_parm = R5000_PARM_ALL, .has_set_parm = RIG_PARM_SET(R5000_PARM_ALL), .parm_gran = { [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, }, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = R5000_VFO_OPS, .scan_ops = R5000_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, {IC10_CHANNEL_CAPS} }, /* TBC */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), R5000_ALL_MODES, -1, -1, R5000_VFO}, {MHz(108), MHz(174), R5000_ALL_MODES, -1, -1, R5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), R5000_ALL_MODES, -1, -1, R5000_VFO}, {MHz(108), MHz(174), R5000_ALL_MODES, -1, -1, R5000_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {R5000_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& r5000_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = ic10_set_freq, .get_freq = ic10_get_freq, .set_mode = ic10_set_mode, .get_mode = ic10_get_mode, .set_vfo = ic10_set_vfo, .get_vfo = ic10_get_vfo, .set_func = ic10_set_func, .get_func = ic10_get_func, .set_parm = ic10_set_parm, .get_parm = ic10_get_parm, .set_ant = ic10_set_ant, .get_ant = ic10_get_ant, .set_mem = ic10_set_mem, .get_mem = ic10_get_mem, .vfo_op = ic10_vfo_op, .set_trn = ic10_set_trn, .get_trn = ic10_get_trn, .scan = ic10_scan, .set_channel = ic10_set_channel, .get_channel = ic10_get_channel, .set_powerstat = ic10_set_powerstat, .get_powerstat = ic10_get_powerstat, .get_info = ic10_get_info, .decode_event = ic10_decode_event, .hamlib_check_rig_caps = "HAMLIB_CHECK_RIG_CAPS" }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/Android.mk0000644000175000017500000000113614752216205014230 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := ts850.c ts870s.c ts570.c ts450s.c ts950.c ts50s.c \ ts790.c ts2000.c k2.c k3.c ts930.c \ ts680.c ts690.c ts140.c ts480.c trc80.c ts590.c \ ts440.c ts940.c ts711.c ts811.c r5000.c \ thd7.c thf7.c thg71.c tmd700.c tmv7.c thf6a.c thd72.c tmd710.c \ kenwood.c th.c ic10.c elecraft.c transfox.c flex6xxx.c ts990s.c \ xg3.c thd74.c flex.c pihpsdr.c ts890s.c LOCAL_MODULE := kenwood LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/kenwood/tmd710.c0000644000175000017500000022214514752216205013504 00000000000000/* * Hamlib Kenwood backend - TM-D710(G) description * Copyright (c) 2011 by Charles Suprin * Copyright (c) 2018 Mikael Nousiainen * * Command set specification available in: * - https://github.com/LA3QMA/TM-V71_TM-D710-Kenwood * - http://kd7dvd.us/equipment/tm-d710a/manuals/control_commands.pdf * * Limitations: * - It is possible to set frequency only inside the selected frequency band of the current VFO, * since there is no command to change the frequency band of a VFO * * Features not yet implemented: * - DTMF send * - Tone burst frequency setting * - Call channel settings * - Change between dual-band/single-band mode * - Several miscellaneous settings available via the MU menu command, which could be exposed via extparms/extlevels * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "tones.h" #include "num_stdio.h" static int tmd710_open(RIG *rig); static int tmd710_do_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tmd710_do_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tmd710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tmd710_set_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tmd710_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq); static int tmd710_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq); static int tmd710_set_vfo(RIG *rig, vfo_t vfo); static int tmd710_get_vfo(RIG *rig, vfo_t *vfo); static int tmd710_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); static int tmd710_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo); static int tmd710_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts); static int tmd710_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts); static int tmd710_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); static int tmd710_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); static int tmd710_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); static int tmd710_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); static int tmd710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); static int tmd710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tmd710_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift); static int tmd710_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift); static int tmd710_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offset); static int tmd710_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offset); static int tmd710_get_mem(RIG *rig, vfo_t vfo, int *ch); static int tmd710_set_mem(RIG *rig, vfo_t vfo, int ch); static int tmd710_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); static int tmd710_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); static int tmd710_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static int tmd710_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int tmd710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); static int tmd710_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); static int tmd710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); static int tmd710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int tmd710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int tmd710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); static int tmd710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); static int tmd710_get_parm(RIG *rig, setting_t parm, value_t *val); static int tmd710_set_parm(RIG *rig, setting_t parm, value_t val); static int tmd710_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); static int tmd710_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); #define TMD710_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_AM) #define TMD710_MODES_FM (RIG_MODE_FM|RIG_MODE_FMN) #define TMD710_MODES_TX (RIG_MODE_FM|RIG_MODE_FMN) #define TMD710_FUNC_GET (RIG_FUNC_TSQL| \ RIG_FUNC_TONE| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO| \ RIG_FUNC_AIP| \ RIG_FUNC_RESUME) #define TMD710_FUNC_SET (RIG_FUNC_TSQL| \ RIG_FUNC_TONE| \ RIG_FUNC_TBURST| \ RIG_FUNC_REV| \ RIG_FUNC_LOCK| \ RIG_FUNC_ARO| \ RIG_FUNC_AIP| \ RIG_FUNC_RESUME) #define TMD710_LEVEL_ALL (RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER) #define TMD710_PARMS (RIG_PARM_BACKLIGHT|\ RIG_PARM_BEEP|\ RIG_PARM_APO) #define TMD710_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TMD710_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define TMD710_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, #define TOKEN_BACKEND(t) (t) #define TOK_LEVEL_EXT_DATA_BAND TOKEN_BACKEND(100) // TM-D710 protocol definitions #define TMD710_BAND_A 0 #define TMD710_BAND_B 1 #define TMD710_BAND_MODE_VFO 0 #define TMD710_BAND_MODE_MEMORY 1 #define TMD710_BAND_MODE_CALL 2 #define TMD710_BAND_MODE_WX 3 #define TMD710_RF_POWER_MIN 0 #define TMD710_RF_POWER_MAX 2 #define TMD710_SQL_MIN 0 #define TMD710_SQL_MAX 0x1F // TM-D710 MU command value tables #define TMD710_ANNOUNCE_OFF 0 #define TMD710_ANNOUNCE_AUTO 1 #define TMD710_ANNOUNCE_MANUAL 2 #define TMD710_LANGUAGE_ENGLISH 0 #define TMD710_LANGUAGE_JAPANESE 1 #define TMD710_SMETER_HANG_UP_TIME_OFF 0 #define TMD710_SMETER_HANG_UP_TIME_125 1 #define TMD710_SMETER_HANG_UP_TIME_250 2 #define TMD710_SMETER_HANG_UP_TIME_500 3 #define TMD710_MUTE_HANG_UP_TIME_OFF 0 #define TMD710_MUTE_HANG_UP_TIME_125 1 #define TMD710_MUTE_HANG_UP_TIME_250 2 #define TMD710_MUTE_HANG_UP_TIME_500 3 #define TMD710_MUTE_HANG_UP_TIME_750 4 #define TMD710_MUTE_HANG_UP_TIME_1000 5 #define TMD710_TIMEOUT_TIMER_3MIN 0 #define TMD710_TIMEOUT_TIMER_5MIN 1 #define TMD710_TIMEOUT_TIMER_10MIN 2 #define TMD710_RECALL_METHOD_ALL 0 #define TMD710_RECALL_METHOD_CURRENT 1 #define TMD710_ECHOLINK_SPEED_FAST 0 #define TMD710_ECHOLINK_SPEED_SLOW 1 #define TMD710_DTMF_SPEED_FAST 0 #define TMD710_DTMF_SPEED_SLOW 1 #define TMD710_DTMF_PAUSE_100 0 #define TMD710_DTMF_PAUSE_250 1 #define TMD710_DTMF_PAUSE_500 2 #define TMD710_DTMF_PAUSE_750 3 #define TMD710_DTMF_PAUSE_1000 4 #define TMD710_DTMF_PAUSE_1500 5 #define TMD710_DTMF_PAUSE_2000 6 #define TMD710_BACKLIGHT_COLOR_AMBER 0 #define TMD710_BACKLIGHT_COLOR_GREEN 1 #define TMD710_SCAN_RESUME_TIME 0 #define TMD710_SCAN_RESUME_CARRIER 1 #define TMD710_SCAN_RESUME_SEEK 2 #define TMD710_AUTO_POWER_OFF_OFF 0 #define TMD710_AUTO_POWER_OFF_30MIN 1 #define TMD710_AUTO_POWER_OFF_60MIN 2 #define TMD710_AUTO_POWER_OFF_90MIN 3 #define TMD710_AUTO_POWER_OFF_120MIN 4 #define TMD710_AUTO_POWER_OFF_180MIN 5 #define TMD710_EXT_DATA_BAND_A 0 #define TMD710_EXT_DATA_BAND_B 1 #define TMD710_EXT_DATA_BAND_TXA_RXB 2 #define TMD710_EXT_DATA_BAND_TXB_RXA 3 #define TMD710_EXT_DATA_SPEED_1200 0 #define TMD710_EXT_DATA_SPEED_9600 1 #define TMD710_SQC_SOURCE_OFF 0 #define TMD710_SQC_SOURCE_BUSY 1 #define TMD710_SQC_SOURCE_SQL 2 #define TMD710_SQC_SOURCE_TX 3 #define TMD710_SQC_SOURCE_BUSY_OR_TX 4 #define TMD710_SQC_SOURCE_SQL_OR_TX 5 static rmode_t tmd710_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_FMN, [2] = RIG_MODE_AM, }; static struct kenwood_priv_caps tmd710_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = tmd710_mode_table, }; /* Private TM-D710 extra levels definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams tmd710_ext_levels[] = { { TOK_LEVEL_EXT_DATA_BAND, "EXTDATABAND", "External data band", "External data band", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "A", "B", "TXA-RXB", "TXB-RXA", NULL } } } }, { RIG_CONF_END, NULL, } }; struct rig_caps tmd710_caps = { RIG_MODEL(RIG_MODEL_TMD710), .model_name = "TM-D710(G)", .mfg_name = "Kenwood", .version = BACKEND_VER ".6", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE | RIG_FLAG_APRS | RIG_FLAG_TNC, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 57600, .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 = 1000, .retry = 3, .has_get_func = TMD710_FUNC_GET, .has_set_func = TMD710_FUNC_SET, .has_get_level = TMD710_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TMD710_LEVEL_ALL), .has_get_parm = TMD710_PARMS, .has_set_parm = TMD710_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood42_ctcss_list, .dcs_list = common_dcs_list, .preamp = {RIG_DBLST_END,}, .attenuator = {RIG_DBLST_END,}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TMD710_VFO_OP, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { {0, 199, RIG_MTYPE_MEM, {TMD710_CHANNEL_CAPS}}, /* normal MEM */ {200, 219, RIG_MTYPE_EDGE, {TMD710_CHANNEL_CAPS}}, /* U/L MEM */ {221, 222, RIG_MTYPE_CALL, {TMD710_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ RIG_CHAN_END, }, /* * TODO: Japan & TM-D700S, and Taiwan models */ .rx_range_list1 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(440), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, /* TODO: cellular blocked */ RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(450), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TMD710_MODES, kHz(5)}, {TMD710_MODES, kHz(6.25)}, {TMD710_MODES, kHz(8.33)}, {TMD710_MODES, kHz(10)}, {TMD710_MODES, kHz(12.5)}, {TMD710_MODES, kHz(15)}, {TMD710_MODES, kHz(20)}, {TMD710_MODES, kHz(25)}, {TMD710_MODES, kHz(30)}, {TMD710_MODES, kHz(50)}, {TMD710_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FMN, kHz(5)}, {RIG_MODE_AM, kHz(4)}, RIG_FLT_END, }, .priv = (void *)& tmd710_priv_caps, .rig_init = kenwood_init, .rig_open = tmd710_open, .rig_cleanup = kenwood_cleanup, .set_freq = tmd710_set_freq, .get_freq = tmd710_get_freq, .set_split_freq = tmd710_set_split_freq, .get_split_freq = tmd710_get_split_freq, .set_mode = tmd710_set_mode, .get_mode = tmd710_get_mode, .set_vfo = tmd710_set_vfo, .get_vfo = tmd710_get_vfo, .set_ts = tmd710_set_ts, .get_ts = tmd710_get_ts, .set_ctcss_tone = tmd710_set_ctcss_tone, .get_ctcss_tone = tmd710_get_ctcss_tone, .set_ctcss_sql = tmd710_set_ctcss_sql, .get_ctcss_sql = tmd710_get_ctcss_sql, .set_split_vfo = tmd710_set_split_vfo, .get_split_vfo = tmd710_get_split_vfo, .set_dcs_sql = tmd710_set_dcs_sql, .get_dcs_sql = tmd710_get_dcs_sql, .set_mem = tmd710_set_mem, .get_mem = tmd710_get_mem, .set_channel = tmd710_set_channel, .get_channel = tmd710_get_channel, //.set_trn = th_set_trn, //.get_trn = th_get_trn, .set_func = tmd710_set_func, .get_func = tmd710_get_func, .set_level = tmd710_set_level, .get_level = tmd710_get_level, .set_parm = tmd710_set_parm, .get_parm = tmd710_get_parm, //.get_info = th_get_info, .get_dcd = tmd710_get_dcd, .set_ptt = tmd710_set_ptt, .vfo_op = tmd710_vfo_op, //.scan = th_scan, .set_ext_level = tmd710_set_ext_level, .get_ext_level = tmd710_get_ext_level, .extlevels = tmd710_ext_levels, .set_rptr_shift = tmd710_set_rptr_shift, .get_rptr_shift = tmd710_get_rptr_shift, .set_rptr_offs = tmd710_set_rptr_offs, .get_rptr_offs = tmd710_get_rptr_offs, .decode_event = th_decode_event, }; struct rig_caps tmv71_caps = { RIG_MODEL(RIG_MODEL_TMV71), .model_name = "TM-V71(A)", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE | RIG_FLAG_APRS | RIG_FLAG_TNC, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 3, .has_get_func = TMD710_FUNC_GET, .has_set_func = TMD710_FUNC_SET, .has_get_level = TMD710_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TMD710_LEVEL_ALL), .has_get_parm = TMD710_PARMS, .has_set_parm = TMD710_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood42_ctcss_list, .dcs_list = common_dcs_list, .preamp = {RIG_DBLST_END,}, .attenuator = {RIG_DBLST_END,}, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = TMD710_VFO_OP, .scan_ops = RIG_SCAN_NONE, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { {0, 199, RIG_MTYPE_MEM, {TMD710_CHANNEL_CAPS}}, /* normal MEM */ {200, 219, RIG_MTYPE_EDGE, {TMD710_CHANNEL_CAPS}}, /* U/L MEM */ {221, 222, RIG_MTYPE_CALL, {TMD710_CHANNEL_CAPS_WO_LO}}, /* Call 0/1 */ RIG_CHAN_END, }, /* * TODO: Japan & TM-D700S, and Taiwan models */ .rx_range_list1 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(440), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(118), MHz(470), TMD710_MODES, -1, -1, RIG_VFO_A | RIG_VFO_MEM}, {MHz(136), MHz(174), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(300), MHz(524), TMD710_MODES_FM, -1, -1, RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(800), MHz(1300), TMD710_MODES_FM, -1, -1, RIG_VFO_B | RIG_VFO_MEM}, /* TODO: cellular blocked */ RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TMD710_MODES_TX, W(5), W(50), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, {MHz(430), MHz(450), TMD710_MODES_TX, W(5), W(35), RIG_VFO_A | RIG_VFO_B | RIG_VFO_MEM}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TMD710_MODES, kHz(5)}, {TMD710_MODES, kHz(6.25)}, {TMD710_MODES, kHz(8.33)}, {TMD710_MODES, kHz(10)}, {TMD710_MODES, kHz(12.5)}, {TMD710_MODES, kHz(15)}, {TMD710_MODES, kHz(20)}, {TMD710_MODES, kHz(25)}, {TMD710_MODES, kHz(30)}, {TMD710_MODES, kHz(50)}, {TMD710_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FMN, kHz(5)}, {RIG_MODE_AM, kHz(4)}, RIG_FLT_END, }, .priv = (void *)& tmd710_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = tmd710_set_freq, .get_freq = tmd710_get_freq, .set_mode = tmd710_set_mode, .get_mode = tmd710_get_mode, .set_vfo = tmd710_set_vfo, .get_vfo = tmd710_get_vfo, .set_ts = tmd710_set_ts, .get_ts = tmd710_get_ts, .set_ctcss_tone = tmd710_set_ctcss_tone, .get_ctcss_tone = tmd710_get_ctcss_tone, .set_ctcss_sql = tmd710_set_ctcss_sql, .get_ctcss_sql = tmd710_get_ctcss_sql, //.set_split_vfo = th_set_split_vfo, //.get_split_vfo = th_get_split_vfo, .set_dcs_sql = tmd710_set_dcs_sql, .get_dcs_sql = tmd710_get_dcs_sql, .set_mem = tmd710_set_mem, .get_mem = tmd710_get_mem, .set_channel = tmd710_set_channel, .get_channel = tmd710_get_channel, //.set_trn = th_set_trn, //.get_trn = th_get_trn, .set_func = tmd710_set_func, .get_func = tmd710_get_func, .set_level = tmd710_set_level, .get_level = tmd710_get_level, .set_parm = tmd710_set_parm, .get_parm = tmd710_get_parm, //.get_info = th_get_info, .get_dcd = tmd710_get_dcd, .set_ptt = tmd710_set_ptt, .vfo_op = tmd710_vfo_op, //.scan = th_scan, .set_ext_level = tmd710_set_ext_level, .get_ext_level = tmd710_get_ext_level, .extlevels = tmd710_ext_levels, .set_rptr_shift = tmd710_set_rptr_shift, .get_rptr_shift = tmd710_get_rptr_shift, .set_rptr_offs = tmd710_set_rptr_offs, .get_rptr_offs = tmd710_get_rptr_offs, .decode_event = th_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* structure for handling FO radio command */ typedef struct { int vfo; // P1 freq_t freq; // P2 int step; // P3 int shift; // P4 int reverse; // P5 int tone; // P6 int ct; // P7 int dcs; // P8 int tone_freq; // P9 int ct_freq; // P10 int dcs_val; // P11 int offset; // P12 int mode; // P13 } tmd710_fo; /* structure for handling ME radio command */ typedef struct { int channel; // P1 freq_t freq; // P2 int step; // P3 int shift; // P4 int reverse; // P5 int tone; // P6 int ct; // P7 int dcs; // P8 int tone_freq; // P9 int ct_freq; // P10 int dcs_val; // P11 int offset; // P12 int mode; // P13 freq_t tx_freq; // P14 int p15_unknown; // P15 int lockout; // P16 } tmd710_me; /* structure for handling MU (menu) radio command */ typedef struct { int beep; // P1 0/1 int beep_volume; // P2 (1-7) int ext_speaker_mode; // P3 int announce; // P4 int language; // P5 int voice_volume; // P6 (0-7) int voice_speed; // P7 (0-4) int playback_repeat; // P8 0/1 int playback_repeat_interval; // P9 (00-60) int continuous_recording; // P10 0/1 int vhf_aip; // P11 0/1 int uhf_aip; // P12 0/1 int smeter_sql_hang_up_time; // P13 int mute_hang_up_time; // P14 int beat_shift; // P15 0/1 int timeout_timer; // P16 int recall_method; // P17 int echolink_speed; // P18 int dtmf_hold; // P19 0/1 int dtmf_speed; // P20 int dtmf_pause; // P21 int dtmf_key_lock; // P22 0/1 int auto_repeater_offset; // P23 0/1 int tone_1750_tx_hold; // P24 0/1 int p25_unknown; // TODO int brightness_level; // P26 (0-8) int auto_brightness; // P27 0/1 int backlight_color; // P28 int pf1_key; // P29 int pf2_key; // P30 int mic_pf1_key; // P31 int mic_pf2_key; // P32 int mic_pf3_key; // P33 int mic_pf4_key; // P34 int mic_key_lock; // P35 0/1 int scan_resume; // P36 int auto_power_off; // P37 int ext_data_band; // P38 int ext_data_speed; // P39 int sqc_source; // P40 int auto_pm_store; // P41 0/1 int display_partition_bar; // P42 0/1 } tmd710_mu; static int tmd710_open(RIG *rig) { split_t split; vfo_t vfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); STATE(rig)->tx_vfo = RIG_VFO_A; // Get current RX and TX VFO state, do not care if we succeed or not tmd710_get_vfo(rig, &vfo); tmd710_get_split_vfo(rig, RIG_VFO_CURR, &split, &vfo); rig_debug(RIG_DEBUG_TRACE, "STATE(rig)->tx_vfo: %s\n", rig_strvfo(STATE(rig)->tx_vfo)); return 0; } static int tmd710_get_vfo_num(RIG *rig, int *vfonum, vfo_t *vfo) { char buf[10]; int retval, ctrlnum, pttnum; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "BC", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "BC %d,%d", &ctrlnum, &pttnum); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'BC c,p'\n", buf); return -RIG_EPROTO; } switch (ctrlnum) { case TMD710_BAND_A: if (vfo != NULL) { *vfo = RIG_VFO_A; } break; case TMD710_BAND_B: if (vfo != NULL) { *vfo = RIG_VFO_B; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, buf[3]); return -RIG_EVFO; } if (vfonum != NULL) { *vfonum = ctrlnum; } return RIG_OK; } static int tmd710_get_vfo_and_mode(RIG *rig, vfo_t *vfo, int *vfomode) { char cmdbuf[10], buf[10]; int retval, vfonum, vfomodenum; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = tmd710_get_vfo_num(rig, &vfonum, vfo); if (retval != RIG_OK) { return retval; } /* Get mode of the VFO band */ snprintf(cmdbuf, sizeof(cmdbuf), "VM %d", vfonum); retval = kenwood_safe_transaction(rig, cmdbuf, buf, 10, 6); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "VM %d,%d", &vfonum, &vfomodenum); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'VM c,m'\n", buf); return -RIG_EPROTO; } if (vfomode != NULL) { *vfomode = vfomodenum; } return RIG_OK; } static int tmd710_resolve_vfo(RIG *rig, vfo_t vfo, vfo_t *resolved_vfo, int *resolved_vfonum) { switch (vfo) { case RIG_VFO_CURR: case RIG_VFO_MEM: return tmd710_get_vfo_num(rig, resolved_vfonum, resolved_vfo); case RIG_VFO_A: if (resolved_vfo != NULL) { *resolved_vfo = RIG_VFO_A; } if (resolved_vfonum != NULL) { *resolved_vfonum = TMD710_BAND_A; } break; case RIG_VFO_B: if (resolved_vfo != NULL) { *resolved_vfo = RIG_VFO_B; } if (resolved_vfonum != NULL) { *resolved_vfonum = TMD710_BAND_B; } break; default: return -RIG_ENTARGET; } return RIG_OK; } static int tmd710_scan_me(char *buf, tmd710_me *me_struct) { int retval; retval = num_sscanf(buf, "ME %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d,%"SCNfreq",%d,%d", (unsigned int *)&me_struct->channel, &me_struct->freq, (unsigned int *)&me_struct->step, (unsigned int *)&me_struct->shift, (unsigned int *)&me_struct->reverse, (unsigned int *)&me_struct->tone, (unsigned int *)&me_struct->ct, (unsigned int *)&me_struct->dcs, &me_struct->tone_freq, &me_struct->ct_freq, &me_struct->dcs_val, &me_struct->offset, &me_struct->mode, &me_struct->tx_freq, &me_struct->p15_unknown, &me_struct->lockout); if (retval != 16) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } /* * The TM-D710(G) has a single command ME that queries and sets many values. * This function pulls that string from the radio given a memory channel. * Push/pull naming is used inside the backend rather than get/set. * There is one unknown field. */ int tmd710_pull_me(RIG *rig, int ch, tmd710_me *me_struct) { char cmdbuf[8]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); snprintf(cmdbuf, sizeof(cmdbuf), "ME %03d", ch); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = tmd710_scan_me(buf, me_struct); if (retval != RIG_OK) { return retval; } return RIG_OK; } int tmd710_push_me(RIG *rig, const tmd710_me *me_struct) { char cmdbuf[80]; char buf[80]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); snprintf(cmdbuf, sizeof(cmdbuf), "ME %03d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d,%010.0f,%1d,%1d", me_struct->channel, me_struct->freq, me_struct->step, me_struct->shift, me_struct->reverse, me_struct->tone, me_struct->ct, me_struct->dcs, me_struct->tone_freq, me_struct->ct_freq, me_struct->dcs_val, me_struct->offset, me_struct->mode, me_struct->tx_freq, me_struct->p15_unknown, me_struct->lockout); return kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); } int tmd710_get_memory_name(RIG *rig, int ch, char *name) { char cmdbuf[8]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called on channel %d\n", __func__, ch); snprintf(cmdbuf, sizeof(cmdbuf), "MN %03d", ch); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "MN %d,%30s", &ch, name); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_set_memory_name(RIG *rig, int ch, char *name) { char cmdbuf[32]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called on channel %d with name %s\n", __func__, ch, name); snprintf(cmdbuf, sizeof(cmdbuf), "MN %03d,%s", ch, name); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * The TM-D710(G) has a single command FO that queries and sets many values. * This function pulls that string from the radio given a VFO. * Push/pull language is used inside the backend rather than get/set. */ int tmd710_pull_fo(RIG *rig, vfo_t vfo, tmd710_fo *fo_struct) { char cmdbuf[8]; char buf[80]; int vfonum; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called with VFO %08X\n", __func__, vfo); retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } snprintf(cmdbuf, sizeof(cmdbuf), "FO %1d", vfonum); retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", (unsigned int *)&fo_struct->vfo, &fo_struct->freq, (unsigned int *)&fo_struct->step, (unsigned int *)&fo_struct->shift, (unsigned int *)&fo_struct->reverse, (unsigned int *)&fo_struct->tone, (unsigned int *)&fo_struct->ct, (unsigned int *)&fo_struct->dcs, &fo_struct->tone_freq, &fo_struct->ct_freq, &fo_struct->dcs_val, &fo_struct->offset, &fo_struct->mode); if (retval != 13) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_push_fo(RIG *rig, vfo_t vfo, tmd710_fo *fo_struct) { char cmdbuf[80]; char buf[80]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); snprintf(cmdbuf, sizeof(cmdbuf), "FO %1d,%010.0f,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%02d,%03d,%08d,%1d", fo_struct->vfo, fo_struct->freq, fo_struct->step, fo_struct->shift, fo_struct->reverse, fo_struct->tone, fo_struct->ct, fo_struct->dcs, fo_struct->tone_freq, fo_struct->ct_freq, fo_struct->dcs_val, fo_struct->offset, fo_struct->mode); retval = kenwood_safe_transaction(rig, cmdbuf, buf, sizeof(buf), 48); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "FO %x,%"SCNfreq",%x,%x,%x,%x,%x,%x,%d,%d,%d,%d,%d", (unsigned int *)&fo_struct->vfo, &fo_struct->freq, (unsigned int *)&fo_struct->step, (unsigned int *)&fo_struct->shift, (unsigned int *)&fo_struct->reverse, (unsigned int *)&fo_struct->tone, (unsigned int *)&fo_struct->ct, (unsigned int *)&fo_struct->dcs, &fo_struct->tone_freq, &fo_struct->ct_freq, &fo_struct->dcs_val, &fo_struct->offset, &fo_struct->mode); if (retval != 13) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_scan_mu(char *buf, tmd710_mu *mu_struct) { int retval; retval = num_sscanf(buf, "MU %d,%d,%d,%d,%d,%d,%d,%d,%d,%d," "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," "%d,%d,%d,%d,%d,%d,%d,%d,%X,%X," "%X,%X,%X,%X,%d,%d,%d,%d,%d,%d," "%d,%d", &mu_struct->beep, &mu_struct->beep_volume, &mu_struct->ext_speaker_mode, &mu_struct->announce, &mu_struct->language, &mu_struct->voice_volume, &mu_struct->voice_speed, &mu_struct->playback_repeat, &mu_struct->playback_repeat_interval, &mu_struct->continuous_recording, &mu_struct->vhf_aip, &mu_struct->uhf_aip, &mu_struct->smeter_sql_hang_up_time, &mu_struct->mute_hang_up_time, &mu_struct->beat_shift, &mu_struct->timeout_timer, &mu_struct->recall_method, &mu_struct->echolink_speed, &mu_struct->dtmf_hold, &mu_struct->dtmf_speed, &mu_struct->dtmf_pause, &mu_struct->dtmf_key_lock, &mu_struct->auto_repeater_offset, &mu_struct->tone_1750_tx_hold, &mu_struct->p25_unknown, &mu_struct->brightness_level, &mu_struct->auto_brightness, &mu_struct->backlight_color, (unsigned int *)&mu_struct->pf1_key, (unsigned int *)&mu_struct->pf2_key, (unsigned int *)&mu_struct->mic_pf1_key, (unsigned int *)&mu_struct->mic_pf2_key, (unsigned int *)&mu_struct->mic_pf3_key, (unsigned int *)&mu_struct->mic_pf4_key, &mu_struct->mic_key_lock, &mu_struct->scan_resume, &mu_struct->auto_power_off, &mu_struct->ext_data_band, &mu_struct->ext_data_speed, &mu_struct->sqc_source, &mu_struct->auto_pm_store, &mu_struct->display_partition_bar ); if (retval != 42) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_pull_mu(RIG *rig, tmd710_mu *mu_struct) { char buf[128]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "MU", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = tmd710_scan_mu(buf, mu_struct); if (retval != RIG_OK) { return retval; } return RIG_OK; } int tmd710_push_mu(RIG *rig, tmd710_mu *mu_struct) { char cmdbuf[128]; char buf[128]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); // we reuse fo_struct->vfo for the channel# snprintf(cmdbuf, sizeof(cmdbuf), "MU %1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%02d,%1d," "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d," "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%02X,%02X," "%02X,%02X,%02X,%02X,%1d,%1d,%1d,%1d,%1d,%1d," "%1d,%1d", mu_struct->beep, mu_struct->beep_volume, mu_struct->ext_speaker_mode, mu_struct->announce, mu_struct->language, mu_struct->voice_volume, mu_struct->voice_speed, mu_struct->playback_repeat, mu_struct->playback_repeat_interval, mu_struct->continuous_recording, mu_struct->vhf_aip, mu_struct->uhf_aip, mu_struct->smeter_sql_hang_up_time, mu_struct->mute_hang_up_time, mu_struct->beat_shift, mu_struct->timeout_timer, mu_struct->recall_method, mu_struct->echolink_speed, mu_struct->dtmf_hold, mu_struct->dtmf_speed, mu_struct->dtmf_pause, mu_struct->dtmf_key_lock, mu_struct->auto_repeater_offset, mu_struct->tone_1750_tx_hold, mu_struct->p25_unknown, mu_struct->brightness_level, mu_struct->auto_brightness, mu_struct->backlight_color, mu_struct->pf1_key, mu_struct->pf2_key, mu_struct->mic_pf1_key, mu_struct->mic_pf2_key, mu_struct->mic_pf3_key, mu_struct->mic_pf4_key, mu_struct->mic_key_lock, mu_struct->scan_resume, mu_struct->auto_power_off, mu_struct->ext_data_band, mu_struct->ext_data_speed, mu_struct->sqc_source, mu_struct->auto_pm_store, mu_struct->display_partition_bar ); retval = kenwood_transaction(rig, cmdbuf, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = tmd710_scan_mu(buf, mu_struct); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tmd710_set_freq * Assumes rig!=NULL * Common function for getting the main and split frequency. */ int tmd710_do_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; tmd710_fo fo_struct; long freq5, freq625, freq_sent; int step; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } freq5 = round(freq / 5000) * 5000; freq625 = round(freq / 6250) * 6250; if (fabs(freq5 - freq) < fabs(freq625 - freq)) { step = 0; freq_sent = freq5; } else { step = 1; freq_sent = freq625; } /* Step needs to be at least 10kHz on higher band, otherwise 5 kHz */ fo_struct.step = freq_sent >= MHz(470) ? 4 : step; fo_struct.freq = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; //return tmd710_push_fo(rig, vfo, &fo_struct); return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_do_get_freq * Assumes rig!=NULL, freq!=NULL * Common function for getting the main and split frequency. */ int tmd710_do_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { tmd710_fo fo_struct; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called for vfo: %s(%u)\n", __func__, rig_strvfo(vfo), vfo); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *freq = fo_struct.freq; } return retval; } /* * tmd710_set_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called for vfo: %s(%u)\n", __func__, rig_strvfo(vfo), vfo); return tmd710_do_set_freq(rig, vfo, freq); } /* * tmd710_get_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return tmd710_do_get_freq(rig, vfo, freq); } /* * tmd710_set_split_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_set_split_freq(RIG *rig, vfo_t vfo, freq_t freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); // Use the TX VFO for split return tmd710_do_set_freq(rig, STATE(rig)->tx_vfo, freq); } /* * tmd710_get_split_freq * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_split_freq(RIG *rig, vfo_t vfo, freq_t *freq) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); // Use the TX VFO for split return tmd710_do_get_freq(rig, STATE(rig)->tx_vfo, freq); } static int tmd710_find_ctcss_index(RIG *rig, tone_t tone, int *ctcss_index) { int k, stepind = -1; for (k = 0; k < 42; k++) { if (rig->caps->ctcss_list[k] == tone) { stepind = k; break; } } if (stepind == -1) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tone value '%u'\n", __func__, tone); return -RIG_EINVAL; } *ctcss_index = stepind; return RIG_OK; } /* * tmd710_set_ctcss_tone * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int retval, stepind; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_find_ctcss_index(rig, tone, &stepind); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.tone_freq = stepind; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_ctcss_tone * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { tmd710_fo fo_struct; int retval; struct rig_caps *caps; caps = rig->caps; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *tone = caps->ctcss_list[fo_struct.tone_freq]; } return retval; } /* * tmd710_set_ctcss_sql * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int retval, stepind; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_find_ctcss_index(rig, tone, &stepind); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.ct_freq = stepind; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_ctcss_sql * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { tmd710_fo fo_struct; int retval; struct rig_caps *caps; caps = rig->caps; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *tone = caps->ctcss_list[fo_struct.ct_freq]; } return retval; } /* * status: ok, no vfo checks */ int tmd710_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { int retval; tmd710_fo fo_struct; if (!rig || !code) { return -RIG_EINVAL; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } if (fo_struct.dcs) { const tone_t *dcs_list = common_dcs_list; *code = dcs_list[fo_struct.dcs_val]; } else { *code = 0; } return RIG_OK; } static int tmd710_find_dcs_index(tone_t code, int *dcs_index) { int i = 0; // we only allow exact matches here const tone_t *dcs_list = common_dcs_list; while (code != dcs_list[i]) { if (dcs_list[i] == 0) { return -RIG_EINVAL; } i++; } *dcs_index = i; return RIG_OK; } /* * status: ok, no vfo checks */ int tmd710_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { int retval, dcs_index, dcs_enable; tmd710_fo fo_struct; if (code == 0) { dcs_index = 0; dcs_enable = 0; } else { retval = tmd710_find_dcs_index(code, &dcs_index); if (retval != RIG_OK) { return retval; } dcs_enable = 1; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.dcs = dcs_enable; fo_struct.dcs_val = dcs_index; return tmd710_push_fo(rig, vfo, &fo_struct); } static int tmd710_get_mode_hamlib_values(int tmd710_mode, rmode_t *mode, pbwidth_t *width) { switch (tmd710_mode) { case 0: *mode = RIG_MODE_FM; *width = 15000; break; case 1: *mode = RIG_MODE_FMN; *width = 5000; break; case 2: *mode = RIG_MODE_AM; *width = 4000; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, (long)tmd710_mode); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_get_mode * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { tmd710_fo fo_struct; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } retval = tmd710_get_mode_hamlib_values(fo_struct.mode, mode, width); if (retval != RIG_OK) { return retval; } return RIG_OK; } static int tmd710_get_mode_tmd710_value(rmode_t mode, int *tmd710_mode) { if (mode == RIG_MODE_FM) { *tmd710_mode = 0; } else if (mode == RIG_MODE_FMN) { *tmd710_mode = 1; } else if (mode == RIG_MODE_AM) { *tmd710_mode = 2; } else { rig_debug(RIG_DEBUG_ERR, "%s: Illegal value from radio '%ld'\n", __func__, (long)mode); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_set_mode * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int retval, tmd710_mode = RIG_MODE_NONE; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_get_mode_tmd710_value(mode, &tmd710_mode); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.mode = tmd710_mode; return tmd710_push_fo(rig, vfo, &fo_struct); } static int tmd710_find_tuning_step_index(RIG *rig, shortfreq_t ts, int *step_index) { int k, stepind = -1; for (k = 0; STATE(rig)->tuning_steps[k].ts != 0; ++k) { if ((rig->caps->tuning_steps[k].modes == RIG_MODE_NONE) && (rig->caps->tuning_steps[k].ts == 0)) { break; } else if (rig->caps->tuning_steps[k].ts == ts) { stepind = k; break; } } if (stepind == -1) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported tuning step value '%ld'\n", __func__, ts); return -RIG_EINVAL; } *step_index = stepind; return RIG_OK; } /* * tmd710_set_ts * Assumes rig!=NULL, freq!=NULL */ static int tmd710_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int retval, stepind; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_find_tuning_step_index(rig, ts, &stepind); if (retval != RIG_OK) { return retval; } retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } fo_struct.step = stepind; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_ts * Assumes rig!=NULL, freq!=NULL */ static int tmd710_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int retval; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *ts = rig->caps->tuning_steps[fo_struct.step].ts; } return retval; } int tmd710_get_rptr_shift_tmd710_value(rptr_shift_t shift, int *tmd710_shift) { switch (shift) { case RIG_RPT_SHIFT_NONE: *tmd710_shift = 0; break; case RIG_RPT_SHIFT_PLUS: *tmd710_shift = 1; break; case RIG_RPT_SHIFT_MINUS: *tmd710_shift = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, shift); return -RIG_EPROTO; } return RIG_OK; } /* * tmd710_set_rptr_shift * Assumes rig!=NULL, freq!=NULL */ int tmd710_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t shift) { int retval; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } retval = tmd710_get_rptr_shift_tmd710_value(shift, &fo_struct.shift); if (retval != RIG_OK) { return retval; } return tmd710_push_fo(rig, vfo, &fo_struct); } int tmd710_get_rptr_shift_hamlib_value(int tmd710_shift, rptr_shift_t *shift) { switch (tmd710_shift) { case 0: *shift = RIG_RPT_SHIFT_NONE; break; case 1: *shift = RIG_RPT_SHIFT_PLUS; break; case 2: *shift = RIG_RPT_SHIFT_MINUS; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected shift value '%d'\n", __func__, tmd710_shift); return -RIG_EPROTO; } return RIG_OK; } /* * tmd710_get_rptr_shft * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *shift) { int retval; tmd710_fo fo_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } retval = tmd710_get_rptr_shift_hamlib_value(fo_struct.shift, shift); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tmd710_set_rptr_offs * Assumes rig!=NULL */ int tmd710_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t freq) { int retval; tmd710_fo fo_struct; long freq5, freq625, freq_sent; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } freq5 = round(freq / 5000) * 5000; freq625 = round(freq / 6250) * 6250; if (abs((int)(freq5 - freq)) < abs((int)(freq625 - freq))) { freq_sent = freq5; } else { freq_sent = freq625; } /* Step needs to be at least 10kHz on higher band, otherwise 5 kHz */ fo_struct.offset = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; return tmd710_push_fo(rig, vfo, &fo_struct); } /* * tmd710_get_rptr_offs * Assumes rig!=NULL, freq!=NULL */ int tmd710_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { tmd710_fo fo_struct; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval == RIG_OK) { *rptr_offs = fo_struct.offset; } return retval; } /* * tmd710_get_vfo * Assumes rig!=NULL */ int tmd710_get_vfo(RIG *rig, vfo_t *vfo) { int vfomode; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_get_vfo_and_mode(rig, vfo, &vfomode); if (retval != RIG_OK) { return retval; } switch (vfomode) { case TMD710_BAND_MODE_VFO: break; case TMD710_BAND_MODE_MEMORY: case TMD710_BAND_MODE_CALL: *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO mode value '%c'\n", __func__, vfomode); return -RIG_EVFO; } return RIG_OK; } /* * tmd710_set_vfo * * Assumes rig!=NULL */ int tmd710_set_vfo(RIG *rig, vfo_t vfo) { char vfobuf[16], ackbuf[16]; int vfonum, vfomode; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: vfonum = TMD710_BAND_A; vfomode = TMD710_BAND_MODE_VFO; break; case RIG_VFO_B: vfonum = TMD710_BAND_B; vfomode = TMD710_BAND_MODE_VFO; break; case RIG_VFO_MEM: /* get current band */ retval = tmd710_get_vfo_num(rig, &vfonum, NULL); if (retval != RIG_OK) { return retval; } vfomode = TMD710_BAND_MODE_MEMORY; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %u\n", __func__, vfo); return -RIG_EVFO; } snprintf(vfobuf, sizeof(vfobuf), "VM %1d,%1d", vfonum, vfomode); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } if (vfo == RIG_VFO_MEM) { return RIG_OK; } snprintf(vfobuf, sizeof(vfobuf), "BC %1d,%1d", vfonum, vfonum); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* * tmd710_set_split_vfo * * This radio has two VFOs, and either one can be the TX/RX. As such, this function does the following: * - Keeps VFO control (CTRL) on the currently active VFO. * - Sets PTT control on the specified VFO. * - Sets the tx_vfo for use in set_split_freq(). * - The value of split is ignored, as the radio is always in "split" mode. * */ int tmd710_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { char vfobuf[16], ackbuf[16]; int retval; int ctrl_vfo_index; rig_debug(RIG_DEBUG_TRACE, "%s: called vfo: %s, txvfo: %s\n", __func__, rig_strvfo(vfo), rig_strvfo(txvfo)); retval = tmd710_get_vfo_num(rig, &ctrl_vfo_index, NULL); if (retval != RIG_OK) { return retval; } int ptt_vfo_index = txvfo == RIG_VFO_A ? 0 : 1; // Keep CTRL VFO as it is and only set the PTT VFO as TX VFO sprintf(vfobuf, "BC %d,%d", ctrl_vfo_index, ptt_vfo_index); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } STATE(rig)->tx_vfo = txvfo; return RIG_OK; } int tmd710_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { char buf[10]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_safe_transaction(rig, "BC", buf, 10, 6); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0': *txvfo = RIG_VFO_A; break; case '1': *txvfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected txVFO value '%c'\n", __func__, buf[5]); return -RIG_EPROTO; } STATE(rig)->tx_vfo = *txvfo; // Rig is always in "split mode" and VFOs are targetable, so simply check current and TX VFOs *split = STATE(rig)->current_vfo == STATE(rig)->tx_vfo ? RIG_SPLIT_OFF : RIG_SPLIT_ON; return RIG_OK; } int tmd710_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmd[16]; char membuf[16]; int retval; int vfonum; int n; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !ch) { return -RIG_EINVAL; } if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { retval = tmd710_get_vfo_num(rig, &vfonum, NULL); if (retval != RIG_OK) { return retval; } } else { vfonum = STATE(rig)->current_vfo == RIG_VFO_A ? 0 : 1; } snprintf(cmd, sizeof(cmd), "MR %d", vfonum); retval = kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 8); if (retval != RIG_OK) { return retval; } n = sscanf(membuf, "MR %*d,%d", ch); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "Unable to parse '%s', expected 'MR v,ccc'\n", membuf); return -RIG_EPROTO; } return RIG_OK; } int tmd710_set_mem(RIG *rig, vfo_t vfo, int ch) { int vfonum; char cmd[16]; char membuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int retval = tmd710_get_vfo_num(rig, &vfonum, NULL); if (retval != RIG_OK) { return retval; } } else { vfonum = STATE(rig)->current_vfo == RIG_VFO_A ? 0 : 1; } snprintf(cmd, sizeof(cmd), "MR %d,%03d", vfonum, ch); return kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 8); } int tmd710_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int retval; tmd710_me me_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !chan) { return -RIG_EINVAL; } retval = tmd710_pull_me(rig, chan->channel_num, &me_struct); if (retval != RIG_OK) { return retval; } chan->freq = me_struct.freq; chan->vfo = RIG_VFO_CURR; retval = tmd710_get_mode_hamlib_values(me_struct.mode, &chan->mode, &chan->width); if (retval != RIG_OK) { return retval; } chan->tuning_step = rig->caps->tuning_steps[me_struct.step].ts; chan->funcs = 0; if (me_struct.tone != 0) { chan->funcs |= RIG_FUNC_TONE; } if (me_struct.ct != 0) { chan->funcs |= RIG_FUNC_TSQL; } if (me_struct.reverse != 0) { chan->funcs |= RIG_FUNC_REV; } chan->ctcss_tone = rig->caps->ctcss_list[me_struct.tone_freq]; chan->ctcss_sql = rig->caps->ctcss_list[me_struct.ct_freq]; chan->dcs_code = 0; if (me_struct.dcs) { const tone_t *dcs_list = common_dcs_list; chan->dcs_sql = dcs_list[me_struct.dcs_val]; } else { chan->dcs_sql = 0; } retval = tmd710_get_rptr_shift_hamlib_value(me_struct.shift, &chan->rptr_shift); if (retval != RIG_OK) { return retval; } chan->rptr_offs = me_struct.offset; retval = tmd710_get_memory_name(rig, chan->channel_num, chan->channel_desc); if (retval != RIG_OK) { return retval; } chan->flags = RIG_CHFLAG_NONE; if (me_struct.lockout) { chan->flags |= RIG_CHFLAG_SKIP; } chan->tx_freq = me_struct.tx_freq; // Unsupported features chan->bank_num = 0; chan->ant = 0; chan->split = RIG_SPLIT_OFF; chan->tx_vfo = RIG_VFO_NONE; chan->tx_mode = RIG_MODE_NONE; chan->tx_width = 0; chan->rit = 0; chan->xit = 0; chan->scan_group = 0; // TODO: chan->levels chan->ext_levels = NULL; return RIG_OK; } int tmd710_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { int retval; tmd710_me me_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig || !chan) { return -RIG_EINVAL; } me_struct.channel = chan->channel_num; me_struct.freq = chan->freq; me_struct.tx_freq = chan->tx_freq; retval = tmd710_find_tuning_step_index(rig, chan->tuning_step, &me_struct.step); if (retval != RIG_OK) { return retval; } retval = tmd710_get_rptr_shift_tmd710_value(chan->rptr_shift, &me_struct.shift); if (retval != RIG_OK) { return retval; } me_struct.offset = chan->rptr_offs; me_struct.reverse = (chan->funcs & RIG_FUNC_REV) ? 1 : 0; me_struct.tone = (chan->funcs & RIG_FUNC_TONE) ? 1 : 0; me_struct.ct = (chan->funcs & RIG_FUNC_TSQL) ? 1 : 0; if (!me_struct.tone && chan->ctcss_tone == 0) { me_struct.tone_freq = 0; } else { retval = tmd710_find_ctcss_index(rig, chan->ctcss_tone, &me_struct.tone_freq); if (retval != RIG_OK) { return retval; } } if (!me_struct.ct && chan->ctcss_sql == 0) { me_struct.ct_freq = 0; } else { retval = tmd710_find_ctcss_index(rig, chan->ctcss_sql, &me_struct.ct_freq); if (retval != RIG_OK) { return retval; } } if (chan->dcs_sql == 0) { me_struct.dcs = 0; me_struct.dcs_val = 0; } else { retval = tmd710_find_dcs_index(chan->dcs_sql, &me_struct.dcs_val); if (retval != RIG_OK) { return retval; } me_struct.dcs = 1; } me_struct.lockout = (chan->flags & RIG_CHFLAG_SKIP) ? 1 : 0; retval = tmd710_get_mode_tmd710_value(chan->mode, &me_struct.mode); if (retval != RIG_OK) { return retval; } me_struct.p15_unknown = 0; retval = tmd710_push_me(rig, &me_struct); if (retval != RIG_OK) { return retval; } return tmd710_set_memory_name(rig, me_struct.channel, (char *) chan->channel_desc); } int tmd710_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char ackbuf[32]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", ackbuf, sizeof(ackbuf)); } int tmd710_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char cmd[8], buf[8]; int retval; int vfonum, dcd_val; retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } snprintf(cmd, sizeof(cmd), "BY %d", vfonum); retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), 6); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "BY %d,%d", &vfonum, &dcd_val); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%ld\n", __func__, buf, (long)strlen(buf)); return -RIG_EPROTO; } switch (dcd_val) { case 0: *dcd = RIG_DCD_OFF; break; case 1: *dcd = RIG_DCD_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%ld\n", __func__, buf, (long)strlen(buf)); return -RIG_ERJCTED; } return RIG_OK; } int tmd710_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char ackbuf[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", ackbuf, sizeof(ackbuf)); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", ackbuf, sizeof(ackbuf)); default: return -RIG_EINVAL; } } /* * tmd710_get_level * Assumes rig!=NULL, val!=NULL */ int tmd710_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char buf[10], ackbuf[20]; int retval, v, l; int vfonum; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: snprintf(buf, sizeof(buf), "PC %d", vfonum); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "PC %d,%d", &v, &l); if (retval != 2 || l < 0 || l > 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - TMD710_RF_POWER_MIN) / (float)(TMD710_RF_POWER_MAX - TMD710_RF_POWER_MIN); // RF power needs to be inverted val->f = 1.0f - val->f; break; case RIG_LEVEL_SQL: snprintf(buf, sizeof(buf), "SQ %d", vfonum); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "SQ %X", (unsigned int *)&l); if (retval != 1 || l < TMD710_SQL_MIN || l > TMD710_SQL_MAX) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - TMD710_SQL_MIN) / (float)(TMD710_SQL_MAX - TMD710_SQL_MIN); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %ld\n", __func__, (long)level); return -RIG_EINVAL; } return RIG_OK; } int tmd710_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char buf[12], ackbuf[12]; int vfonum; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_resolve_vfo(rig, vfo, NULL, &vfonum); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: // RF power needs to be inverted snprintf(buf, sizeof(buf), "PC %d,%d", vfonum, (int)((1.0f - val.f) * (TMD710_RF_POWER_MAX - TMD710_RF_POWER_MIN) + TMD710_RF_POWER_MIN)); return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); case RIG_LEVEL_SQL: snprintf(buf, sizeof(buf), "SQ %d,%02X", vfonum, (int)(val.f * (TMD710_SQL_MAX - TMD710_SQL_MIN) + TMD710_SQL_MIN)); return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %ld\n", __func__, (long)level); return -RIG_EINVAL; } } static int tmd710_tburst(RIG *rig, int status) { char ackbuf[8]; return kenwood_transaction(rig, (status == 1) ? "TT" : "RX", ackbuf, sizeof(ackbuf)); } /* * tmd710_get_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int tmd710_get_kenwood_func(RIG *rig, const char *cmd, int *status) { char buf[8]; int retval, len, expected; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); len = strlen(cmd); expected = len + 2; retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), expected); if (retval != RIG_OK) { return retval; } if (status) { *status = (buf[len + 1] == '0') ? 0 : 1; } return RIG_OK; }; /* * tmd710_set_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int tmd710_set_kenwood_func(RIG *rig, const char *cmd, int status) { char buf[16], ackbuf[16]; rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s, status = %d\n", __func__, cmd, status); strncpy(buf, cmd, sizeof(buf) - 2); buf[sizeof(buf) - 1] = '\0'; strncat(buf, status ? " 1" : " 0", sizeof(buf) - 1); return kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); } /* * tmd710_get_func * Assumes rig!=NULL, status!=NULL */ int tmd710_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; int use_fo = 0, use_mu = 0; tmd710_fo fo_struct; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04lx)\n", __func__, (long)func); switch (func) { case RIG_FUNC_TONE: case RIG_FUNC_TSQL: case RIG_FUNC_REV: use_fo = 1; break; case RIG_FUNC_ARO: case RIG_FUNC_AIP: case RIG_FUNC_RESUME: use_mu = 1; break; } if (use_fo) { retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } } if (use_mu) { retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } } switch (func) { case RIG_FUNC_TONE: *status = (fo_struct.tone != 0) ? 1 : 0; break; case RIG_FUNC_TSQL: *status = (fo_struct.ct != 0) ? 1 : 0; break; case RIG_FUNC_REV: *status = (fo_struct.reverse != 0) ? 1 : 0; break; case RIG_FUNC_LOCK: return tmd710_get_kenwood_func(rig, "LK", status); case RIG_FUNC_ARO: *status = (mu_struct.auto_repeater_offset != 0) ? 1 : 0; break; case RIG_FUNC_AIP: *status = ((mu_struct.vhf_aip != 0) || (mu_struct.uhf_aip != 0)) ? 1 : 0; break; case RIG_FUNC_RESUME: *status = (mu_struct.scan_resume == TMD710_SCAN_RESUME_TIME) ? 1 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %#lx\n", __func__, (long)func); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_set_func * Assumes rig!=NULL, status!=NULL */ int tmd710_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; int use_fo = 0, use_mu = 0; tmd710_fo fo_struct; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04lx)\n", __func__, (long)func); switch (func) { case RIG_FUNC_TONE: case RIG_FUNC_TSQL: case RIG_FUNC_REV: use_fo = 1; break; case RIG_FUNC_ARO: case RIG_FUNC_AIP: case RIG_FUNC_RESUME: use_mu = 1; break; } if (use_fo) { retval = tmd710_pull_fo(rig, vfo, &fo_struct); if (retval != RIG_OK) { return retval; } } if (use_mu) { retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } } switch (func) { case RIG_FUNC_TONE: fo_struct.tone = status ? 1 : 0; break; case RIG_FUNC_TSQL: fo_struct.ct = status ? 1 : 0; break; case RIG_FUNC_REV: fo_struct.reverse = status ? 1 : 0; break; case RIG_FUNC_ARO: mu_struct.auto_repeater_offset = status ? 1 : 0; break; case RIG_FUNC_AIP: mu_struct.vhf_aip = status ? 1 : 0; mu_struct.uhf_aip = status ? 1 : 0; break; case RIG_FUNC_RESUME: mu_struct.scan_resume = status ? TMD710_SCAN_RESUME_TIME : TMD710_SCAN_RESUME_CARRIER; break; case RIG_FUNC_LOCK: return tmd710_set_kenwood_func(rig, "LK", status); case RIG_FUNC_TBURST: return tmd710_tburst(rig, status); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %#lx\n", __func__, (long)func); return -RIG_EINVAL; } if (use_fo) { return tmd710_push_fo(rig, vfo, &fo_struct); } if (use_mu) { return tmd710_push_mu(rig, &mu_struct); } return -RIG_EINVAL; } /* * tmd710_get_parm * Assumes rig!=NULL, status!=NULL */ int tmd710_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04lx)\n", __func__, (long)parm); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (parm) { case RIG_PARM_BEEP: val->i = mu_struct.beep ? 1 : 0; break; case RIG_PARM_APO: if (mu_struct.auto_power_off == TMD710_AUTO_POWER_OFF_180MIN) { val->i = 180; } else { val->i = mu_struct.auto_power_off * 30; } break; case RIG_PARM_BACKLIGHT: val->f = ((float) mu_struct.brightness_level) / 8.0f; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %#lx\n", __func__, (long)parm); return -RIG_EINVAL; } return RIG_OK; } int tmd710_set_parm(RIG *rig, setting_t parm, value_t val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (parm) { case RIG_PARM_BEEP: mu_struct.beep = val.i ? 1 : 0; break; case RIG_PARM_BACKLIGHT: if (val.f < 0 || val.f > 1) { return -RIG_EINVAL; } mu_struct.brightness_level = (int)(val.f * 8); break; case RIG_PARM_APO: { int value = 0; if (val.i > 120) { value = TMD710_AUTO_POWER_OFF_180MIN; } else if (val.i > 90) { value = TMD710_AUTO_POWER_OFF_120MIN; } else if (val.i > 60) { value = TMD710_AUTO_POWER_OFF_90MIN; } else if (val.i > 30) { value = TMD710_AUTO_POWER_OFF_60MIN; } else if (val.i > 0) { value = TMD710_AUTO_POWER_OFF_30MIN; } mu_struct.auto_power_off = value; break; } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %#lx\n", __func__, (long)parm); return -RIG_EINVAL; } return tmd710_push_mu(rig, &mu_struct); } /* * tmd710_get_ext_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL, val!=NULL * */ int tmd710_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (token) { case TOK_LEVEL_EXT_DATA_BAND: val->i = mu_struct.ext_data_band; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %ld\n", __func__, (long)token); return -RIG_EINVAL; } return RIG_OK; } /* * tmd710_set_ext_level * Assumes rig!=NULL, STATE(rig)->priv!=NULL * */ int tmd710_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; tmd710_mu mu_struct; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = tmd710_pull_mu(rig, &mu_struct); if (retval != RIG_OK) { return retval; } switch (token) { case TOK_LEVEL_EXT_DATA_BAND: { int v = val.i; if (v != TMD710_EXT_DATA_BAND_A && v != TMD710_EXT_DATA_BAND_B && v != TMD710_EXT_DATA_BAND_TXA_RXB && v != TMD710_EXT_DATA_BAND_TXB_RXA) { return -RIG_EINVAL; } mu_struct.ext_data_band = v; break; } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported ext level %ld\n", __func__, (long)token); return -RIG_EINVAL; } return tmd710_push_mu(rig, &mu_struct); } hamlib-4.6.2/rigs/kenwood/thd72.c0000644000175000017500000011417614752216205013424 00000000000000/* * Hamlib Kenwood TH-D72 backend * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2018 by Brian Lucas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "misc.h" // Some commands are very slow to process so we put a DELAY in those places #define DELAY hl_usleep(300*1000) #define THD72_MODES (RIG_MODE_FM|RIG_MODE_FMN|RIG_MODE_AM) #define THD72_MODES_TX (RIG_MODE_FM|RIG_MODE_FMN) #define THD72_FUNC_ALL (RIG_FUNC_TSQL| \ RIG_FUNC_AIP| \ RIG_FUNC_TONE| \ RIG_FUNC_ARO) #define THD72_LEVEL_ALL (RIG_LEVEL_RFPOWER| \ RIG_LEVEL_SQL| \ RIG_LEVEL_BALANCE| \ RIG_LEVEL_VOXGAIN| \ RIG_LEVEL_VOXDELAY) #define THD72_PARMS (RIG_PARM_APO| \ RIG_PARM_TIME) #define THD72_VFO_OP (RIG_OP_NONE) #define THD72_VFO (RIG_VFO_A|RIG_VFO_B) static rmode_t thd72_mode_table[3] = { [0] = RIG_MODE_FM, /* normal, but narrow compared to broadcast */ [1] = RIG_MODE_FMN, /* what kenwood calls narrow */ [2] = RIG_MODE_AM, }; static pbwidth_t thd72_width_table[3] = { [0] = 10000, // +-5KHz [1] = 5000, // +-2.5KHz [2] = 10000, // what should this be? }; static rptr_shift_t thd72_rshf_table[3] = { [0] = RIG_RPT_SHIFT_NONE, [1] = RIG_RPT_SHIFT_PLUS, [2] = RIG_RPT_SHIFT_MINUS, }; static int thd72tuningstep[11] = { [0] = 5000, [1] = 6250, [2] = 0, // not used in thd72 [3] = 10000, [4] = 12500, [5] = 15000, [6] = 20000, [7] = 25000, [8] = 30000, [9] = 50000, [10] = 100000 }; static int thd72voxdelay[7] = { [0] = 2500, [1] = 5000, [2] = 7500, [3] = 10000, [4] = 15000, [5] = 20000, [6] = 30000 }; static float thd72sqlevel[6] = { [0] = 0.0, /* open */ [1] = 0.2, [2] = 0.4, [3] = 0.6, [4] = 0.8, [5] = 1.0 }; static int thd72apo[4] = { [0] = 0, [1] = 15, [2] = 30, [3] = 60 }; static tone_t thd72dcs_list[105] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0 }; static struct kenwood_priv_caps thd72_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thd72_mode_table, }; int thd72_open(RIG *rig) { int ret; struct kenwood_priv_data *priv = STATE(rig)->priv; strcpy(priv->verify_cmd, "ID\r"); //ret = kenwood_transaction(rig, "", NULL, 0); //DELAY; ret = rig_set_vfo(rig, RIG_VFO_A); return ret; } static int thd72_set_vfo(RIG *rig, vfo_t vfo) { const char *cmd; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: cmd = "BC 0"; STATE(rig)->current_vfo = RIG_VFO_A; break; case RIG_VFO_B: case RIG_VFO_SUB: STATE(rig)->current_vfo = RIG_VFO_B; cmd = "BC 1"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return kenwood_simple_transaction(rig, cmd, 4); } static int thd72_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int retval; char vfobuf[16]; const struct kenwood_priv_data *priv = STATE(rig)->priv; char vfonum = '0'; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo == RIG_VFO_B || priv->split) { vfonum = '1'; } SNPRINTF(vfobuf, sizeof(vfobuf), "BC %c", vfonum); retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", NULL, 0); } static int thd72_get_vfo(RIG *rig, vfo_t *vfo) { int retval; char c, buf[10]; size_t length; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "BC", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length == 4) { c = buf[3]; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length %d\n", __func__, (int)length); return -RIG_EPROTO; } switch (c) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %c\n", __func__, c); return -RIG_EVFO; } return RIG_OK; } static int thd72_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char vfobuf[16]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); if (txvfo != RIG_VFO_B) // Only split with RIG_VFO_B as tx { return -RIG_EINVAL; } /* Set VFO mode */ SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,0"); retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 1,0"); retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "BC 1"); // leave VFOB as selected VFO retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for thd72_set_vfo */ priv->split = split; return RIG_OK; } static int thd72_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char buf[10]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_safe_transaction(rig, "BC", buf, 10, 4); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0': *txvfo = RIG_VFO_A; break; case '1': *txvfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected txVFO value '%c'\n", __func__, buf[5]); return -RIG_EPROTO; } *split = (buf[3] == buf[5]) ? RIG_SPLIT_OFF : RIG_SPLIT_ON; /* Remember whether split is on, for th_set_vfo */ priv->split = *split; return RIG_OK; } static int thd72_vfoc(RIG *rig, vfo_t vfo, char *vfoc) { rig_debug(RIG_DEBUG_TRACE, "%s: called VFO=%s\n", __func__, rig_strvfo(vfo)); vfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: *vfoc = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: *vfoc = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", __func__, rig_strvfo(vfo)); return -RIG_ENTARGET; } return RIG_OK; } static int thd72_get_freq_info(RIG *rig, vfo_t vfo, char *buf) { int retval; char c, cmd[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called VFO=%s\n", __func__, rig_strvfo(vfo)); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "FO %c", c); retval = kenwood_transaction(rig, cmd, buf, 53); return retval; } /* item is an offset into reply buf that is a single char */ static int thd72_get_freq_item(RIG *rig, vfo_t vfo, int item, int hi, int *val) { int retval, lval; char c, buf[64]; retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } c = buf[item]; if (c < '0' || c > '9') { return -RIG_EPROTO; } lval = c - '0'; if (lval > hi) { return -RIG_EPROTO; } *val = lval; return RIG_OK; } static int thd72_set_freq_item(RIG *rig, vfo_t vfo, int item, int val) { int retval; char buf[64]; retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[item] = val + '0'; return kenwood_simple_transaction(rig, buf, 52); } static int thd72_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; int tsindex; shortfreq_t ts; char buf[64], fbuf[11]; rig_debug(RIG_DEBUG_TRACE, "%s: called, vfo=%s, freq=%f\n", __func__, rig_strvfo(vfo), freq); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } tsindex = buf[16] - '0'; if (buf[16] >= 'A') { tsindex = buf[16] - 'A' + 10; } ts = thd72tuningstep[tsindex]; rig_debug(RIG_DEBUG_VERBOSE, "%s: tsindex=%d, stepsize=%d\n", __func__, tsindex, (int)ts); freq = roundl(freq / ts) * ts; SNPRINTF(fbuf, sizeof(fbuf), "%010"PRIll, (int64_t)freq); memcpy(buf + 5, fbuf, 10); retval = kenwood_simple_transaction(rig, buf, 52); return retval; } static int thd72_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; int tsindex; shortfreq_t ts; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } tsindex = buf[16] - '0'; ts = thd72tuningstep[tsindex]; rig_debug(RIG_DEBUG_VERBOSE, "%s: tsindex=%d, stepsize=%d\n", __func__, tsindex, (int)ts); sscanf(buf + 5, "%"SCNfreq, freq); return RIG_OK; } static int thd72_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int val; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (mode) { case RIG_MODE_FM: val = 0; break; case RIG_MODE_FMN: val = 1; break; case RIG_MODE_AM: val = 2; break; default: return -RIG_EINVAL; } return thd72_set_freq_item(rig, vfo, 51, val); } static int thd72_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval, modeinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_item(rig, vfo, 51, 2, &modeinx); if (retval != RIG_OK) { return retval; } *mode = thd72_mode_table[modeinx]; *width = thd72_width_table[modeinx]; return RIG_OK; } static int thd72_set_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (rptr_shift) { case RIG_RPT_SHIFT_NONE: rsinx = 0; break; case RIG_RPT_SHIFT_PLUS: rsinx = 1; break; case RIG_RPT_SHIFT_MINUS: rsinx = 2; break; default: return -RIG_EINVAL; } return thd72_set_freq_item(rig, vfo, 18, rsinx); } static int thd72_get_rptr_shft(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int retval, rsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_item(rig, vfo, 18, 3, &rsinx); if (retval != RIG_OK) { return retval; } /* rsinx == 3 indicates split mode? */ *rptr_shift = (rsinx == 3) ? RIG_RPT_SHIFT_NONE : thd72_rshf_table[rsinx]; return RIG_OK; } static int thd72_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t offs) { int retval; char boff[9], buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } SNPRINTF(boff, sizeof(boff), "%08ld", offs); memcpy(buf + 42, boff, 8); retval = kenwood_simple_transaction(rig, buf, 52); return retval; } static int thd72_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *offs) { int retval; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } sscanf(buf + 42, "%ld", offs); return RIG_OK; } static int thd72_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int tsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (tsinx = 0; tsinx < 10; tsinx++) { if (thd72tuningstep[tsinx] >= ts) { thd72_set_freq_item(rig, vfo, 16, tsinx); return RIG_OK; } } return -RIG_EINVAL; } static int thd72_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int retval, tsinx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_item(rig, vfo, 16, 9, &tsinx); if (retval != RIG_OK) { return retval; } *ts = thd72tuningstep[tsinx]; return RIG_OK; } static int thd72_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[22] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 30, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd72_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[22] == '0') /* no tone */ { *tone = 0; } else { sscanf(buf + 30, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } static int thd72_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int retval, cinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); cinx = 0; /* default */ if (code != 0) { for (cinx = 0; cinx < 104; cinx++) { if (code == thd72dcs_list[cinx]) { break; } } if (cinx >= 104) { return -RIG_EINVAL; } } retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[26] = (code == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%03d", cinx); memcpy(buf + 36, tmp, 3); return kenwood_simple_transaction(rig, buf, 52); } static int thd72_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int retval, cinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[26] == '0') /* no tone */ { *code = 0; } else { sscanf(buf + 36, "%d", &cinx); *code = thd72dcs_list[cinx]; } return RIG_OK; } static int thd72_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int retval, tinx; char buf[64], tmp[4]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tinx = 0; /* default */ if (tone != 0) { for (tinx = 0; tinx < 42; tinx++) { if (tone == kenwood42_ctcss_list[tinx]) { break; } } if (tinx >= 42) { return -RIG_EINVAL; } } retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } buf[24] = (tone == 0) ? '0' : '1'; SNPRINTF(tmp, sizeof(tmp), "%02d", tinx); memcpy(buf + 33, tmp, 2); return kenwood_simple_transaction(rig, buf, 52); } static int thd72_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int retval, tinx; char buf[64]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_get_freq_info(rig, vfo, buf); if (retval != RIG_OK) { return retval; } if (buf[24] == '0') /* no tsql */ { *tone = 0; } else { sscanf(buf + 33, "%d", &tinx); if (tinx >= 0 && tinx <= 41) { *tone = kenwood42_ctcss_list[tinx]; } else { return -RIG_EINVAL; } } return RIG_OK; } static int thd72_get_menu_info(RIG *rig, char *buf) { int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "MU", buf, 41); if (retval != RIG_OK) { return retval; } if (strlen(buf) != 40) { return -RIG_ERJCTED; } return RIG_OK; } /* each menu item is a single hex digit */ static int thd72_get_menu_item(RIG *rig, int item, int hi, int *val) { int retval, lval; char c, buf[48]; retval = thd72_get_menu_info(rig, buf); if (retval != RIG_OK) { return retval; } c = buf[3 + 2 * item]; /* "MU 0,1,2 ... */ if (c >= '0' && c <= '9') { lval = c - '0'; } else if (c >= 'A' && c <= 'F') { lval = c - 'A' + 10; } else { return -RIG_EPROTO; } if (lval > hi) { return -RIG_EPROTO; } *val = lval; return RIG_OK; } static int thd72_set_menu_item(RIG *rig, int item, int val) { int retval; char c, buf[48]; retval = thd72_get_menu_info(rig, buf); if (retval != RIG_OK) { return retval; } if (val < 10) { c = val + '0'; } else { c = val - 10 + 'A'; } buf[3 + 2 * item] = c; return kenwood_simple_transaction(rig, buf, 40); } static int thd72_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int retval, lvl; char c, lvlc, cmd[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called VFO=%s, level=%s, val=%g\n", __func__, rig_strvfo(vfo), rig_strlevel(level), val.f); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: if (val.f <= 0.01) { lvlc = '2'; } else if (val.f <= 0.10) { lvlc = '1'; } else { lvlc = '0'; } SNPRINTF(cmd, sizeof(cmd), "PC %c,%c", c, lvlc); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_VOXGAIN: return thd72_set_menu_item(rig, 8, (int)(val.f * 10.0 - 0.5)); case RIG_LEVEL_VOXDELAY: if (val.i > 20000) { lvl = 6; } else if (val.i > 10000) { lvl = val.i / 10000 + 3; } else { lvl = val.i / 2500; } return thd72_set_menu_item(rig, 9, lvl); case RIG_LEVEL_SQL: lvlc = '0' + (int)(val.f * 5); SNPRINTF(cmd, sizeof(cmd), "PC %c,%c", c, lvlc); return kenwood_simple_transaction(rig, cmd, 6); case RIG_LEVEL_BALANCE: /* FIXME - is balance 0.0 .. 1.0 or -1.0 .. 1.0? */ lvl = (int)(val.f * 4.0); return thd72_set_menu_item(rig, 13, lvl); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } static int thd72_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, v, l; char c, cmd[10], buf[48]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } switch (level) { case RIG_LEVEL_RFPOWER: SNPRINTF(cmd, sizeof(cmd), "PC %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "PC %d,%d", &v, &l); if (retval != 2 || l < 0 || l > 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } switch (l) { case 0: val->f = 1.00; break; /* 5.0 W */ case 1: val->f = 0.10; break; /* 500 mW */ case 2: val->f = 0.01; break; /* 50 mW */ } break; case RIG_LEVEL_VOXGAIN: retval = thd72_get_menu_item(rig, 8, 9, &l); if (retval != RIG_OK) { return retval; } /* FIXME - if VOX is off, what do we return */ val->f = l / 9.0; break; case RIG_LEVEL_VOXDELAY: retval = thd72_get_menu_item(rig, 9, 7, &l); if (retval != RIG_OK) { return retval; } /* FIXME - if VOX is off, what do we return */ val->i = thd72voxdelay[l]; break; case RIG_LEVEL_SQL: SNPRINTF(cmd, sizeof(cmd), "SQ %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "SQ %d,%d", &v, &l); if (retval != 2 || l < 0 || l >= 6) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } val->f = thd72sqlevel[l]; break; case RIG_LEVEL_BALANCE: retval = thd72_get_menu_item(rig, 13, 4, &l); if (retval != RIG_OK) { return retval; } /* FIXME - is balance 0.0 .. 1.0 or -1.0 .. 1.0? */ val->f = (float)(l) / 4.0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } static int thd72_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int retval; char c; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_AIP: retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } return thd72_set_menu_item(rig, c == '0' ? 5 : 6, status); case RIG_FUNC_ARO: return thd72_set_menu_item(rig, 18, status); case RIG_FUNC_TONE: return thd72_set_freq_item(rig, vfo, 22, status); case RIG_FUNC_TSQL: return thd72_set_freq_item(rig, vfo, 24, status); default: return -RIG_EINVAL; } return RIG_OK; } static int thd72_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval, f = -1; char c; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (func) { case RIG_FUNC_AIP: retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } retval = thd72_get_menu_item(rig, c == '0' ? 5 : 6, 1, &f); break; case RIG_FUNC_ARO: retval = thd72_get_menu_item(rig, 18, 1, &f); break; case RIG_FUNC_TONE: retval = thd72_get_freq_item(rig, vfo, 22, 1, &f); break; case RIG_FUNC_TSQL: retval = thd72_get_freq_item(rig, vfo, 24, 1, &f); break; default: retval = -RIG_EINVAL; } if (retval != RIG_OK) { return retval; } *status = f; return RIG_OK; } static int thd72_set_parm(RIG *rig, setting_t parm, value_t val) { int l; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_APO: if (val.i == 0) { l = 0; } else if (val.i <= 15) { l = 1; } else if (val.i <= 30) { l = 2; } else { l = 3; } return thd72_set_menu_item(rig, 3, l); case RIG_PARM_TIME: default: return -RIG_EINVAL; } return RIG_OK; } static int thd72_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval, l, hh, mm, ss; char buf[48]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_APO: retval = thd72_get_menu_item(rig, 3, 3, &l); if (retval != RIG_OK) { return retval; } val->i = thd72apo[l]; break; case RIG_PARM_TIME: retval = kenwood_transaction(rig, "RT", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 11, "%2d%2d%2d", &hh, &mm, &ss); val->i = ss + 60 * (mm + 60 * hh); break; default: return -RIG_EINVAL; } return RIG_OK; } static int thd72_set_mem(RIG *rig, vfo_t vfo, int ch) { int retval; char c, cmd[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c,%03d", c, ch); return kenwood_simple_transaction(rig, cmd, 10); } static int thd72_get_mem(RIG *rig, vfo_t vfo, int *ch) { int retval; char c, cmd[10], buf[10]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = thd72_vfoc(rig, vfo, &c); if (retval != RIG_OK) { return retval; } SNPRINTF(cmd, sizeof(cmd), "MR %c", c); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } sscanf(buf + 5, "%d", ch); return RIG_OK; } static int thd72_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return -RIG_EINVAL; } static int thd72_parse_channel(int kind, const char *buf, channel_t *chan) { int tmp; int n; char c; const char *data; if (kind == 0) { data = buf + 5; } else { data = buf + 7; } n = sscanf(data, "%"SCNfreq, &chan->freq); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning %s\n", __func__, data); return -RIG_EPROTO; } c = data[46]; // mode if (c >= '0' && c <= '2') { chan->mode = thd72_mode_table[c - '0']; chan->width = thd72_width_table[c - '0']; } c = data[11]; // tuning step if (c >= '0' && c <= '9') { chan->tuning_step = thd72tuningstep[c - '0']; } c = data[13]; // repeater shift if (c >= '0' && c <= '2') { chan->rptr_shift = thd72_rshf_table[c - '0']; } n = sscanf(data + 37, "%ld", &chan->rptr_offs); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[37]%s\n", __func__, data); return -RIG_EPROTO; } c = data[17]; // Tone status if (c != '0') { n = sscanf(data + 25, "%d", &tmp); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[25]%s\n", __func__, data); return -RIG_EPROTO; } if (tmp > 0 && tmp < 42) { chan->ctcss_tone = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_tone = 0; } c = data[19]; // TSQL status if (c != '0') { n = sscanf(data + 28, "%d", &tmp); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[28]%s\n", __func__, data); return -RIG_EPROTO; } if (tmp > 0 && tmp < 42) { chan->ctcss_sql = kenwood42_ctcss_list[tmp]; } } else { chan->ctcss_sql = 0; } c = data[21]; // DCS status if (c != '0') { n = sscanf(data + 31, "%d", &tmp); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: error scanning data[31]%s\n", __func__, data); return -RIG_EPROTO; } chan->dcs_code = tmp; } else { chan->dcs_code = 0; } return RIG_OK; } static int thd72_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int retval; char buf[72]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (chan->vfo == RIG_VFO_MEM) /* memory channel */ { int len; char cmd[16]; SNPRINTF(cmd, sizeof(cmd), "ME %03d", chan->channel_num); retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = thd72_parse_channel(1, buf, chan); if (retval != RIG_OK) { return retval; } cmd[1] = 'N'; /* change ME to MN */ retval = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } len = strlen(buf); memcpy(chan->channel_desc, buf + 7, len - 7); } else /* current channel */ { retval = thd72_get_freq_info(rig, chan->vfo, buf); if (retval != RIG_OK) { return retval; } return thd72_parse_channel(0, buf, chan); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } #ifdef false /* not working */ #define CMD_SZ 5 #define BLOCK_SZ 256 #define BLOCK_COUNT 256 #define CHAN_PER_BLOCK 4 static int thd72_get_block(RIG *rig, int block_num, char *block) { hamlib_port_t *rp = RIGPORT(rig); char cmd[CMD_SZ] = "R\0\0\0\0"; char resp[CMD_SZ]; int ret; /* fetching block i */ cmd[2] = block_num & 0xff; ret = write_block(rp, cmd, CMD_SZ); if (ret != RIG_OK) { return ret; } /* read response first */ ret = read_block(rp, resp, CMD_SZ); if (ret != CMD_SZ) { return ret; } if (resp[0] != 'W' || memcmp(cmd + 1, resp + 1, CMD_SZ - 1)) { return -RIG_EPROTO; } /* read block */ ret = read_block(rp, block, BLOCK_SZ); if (ret != BLOCK_SZ) { return ret; } ret = write_block(rp, "\006", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } return RIG_OK; } #ifdef XXREMOVEDXX int thd72_get_chan_all_cb(RIG *rig, chan_cb_t chan_cb, rig_ptr_t arg) { int i, j, ret; hamlib_port_t *rp = RIGPORT(rig); channel_t *chan; chan_t *chan_list = STATE(rig)->chan_list; int chan_next = chan_list[0].start; char block[BLOCK_SZ]; char resp[CMD_SZ]; ret = kenwood_transaction(rig, "0M PROGRAM", resp, CMD_SZ); if (ret != RIG_OK) { return ret; } if (strlen(resp) != 2 || memcmp(resp, "0M", 2)) { return -RIG_EPROTO; } rp->parm.serial.rate = 57600; serial_setup(rp); hl_usleep(100 * 1000); /* let the pcr settle */ rig_flush(rp); /* flush any remaining data */ ret = ser_set_rts(rp, 1); /* setRTS or Hardware flow control? */ if (ret != RIG_OK) { return ret; } /* * setting chan to NULL means the application * has to provide a struct where to store data * future data for channel channel_num */ chan = NULL; ret = chan_cb(rig, &chan, chan_next, chan_list, arg); if (ret != RIG_OK) { return ret; } if (chan == NULL) { return -RIG_ENOMEM; } for (i = 0; i < BLOCK_COUNT; i++) { ret = thd72_get_block(rig, i, block); if (ret != RIG_OK) { return ret; } /* * Most probably, there's 64 bytes per channel (256*256 / 1000+) */ for (j = 0; j < CHAN_PER_BLOCK; j++) { const char *block_chan = block + j * (BLOCK_SZ / CHAN_PER_BLOCK); memset(chan, 0, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; chan->channel_num = i * CHAN_PER_BLOCK + j; /* What are the extra 64 channels ? */ if (chan->channel_num >= 1000) { break; } /* non-empty channel ? */ // if (block_chan[0] != 0xff) { // since block_chan is *signed* char, this maps to -1 if (block_chan[0] != -1) { memcpy(chan->channel_desc, block_chan, 8); /* TODO: chop off trailing chars */ chan->channel_desc[8] = '\0'; /* TODO: parse block and fill in chan */ } /* notify the end? */ chan_next = chan_next < chan_list[i].end ? chan_next + 1 : chan_next; /* * provide application with channel data, * and ask for a new channel structure */ chan_cb(rig, &chan, chan_next, chan_list, arg); } } ret = write_block(rp, "E", 1); if (ret != RIG_OK) { return ret; } ret = read_block(rp, resp, 1); if (ret != 1) { return ret; } if (resp[0] != 0x06) { return -RIG_EPROTO; } /* setRTS?? getCTS needed? */ ret = ser_set_rts(rp, 1); if (ret != RIG_OK) { return ret; } return RIG_OK; } #endif #endif /* none working stuff */ /* * th-d72a rig capabilities. */ struct rig_caps thd72a_caps = { RIG_MODEL(RIG_MODEL_THD72A), .model_name = "TH-D72A", .mfg_name = "Kenwood", .version = TH_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD | RIG_FLAG_APRS | RIG_FLAG_TNC | RIG_FLAG_DXCLUSTER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .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, .has_get_func = THD72_FUNC_ALL, .has_set_func = THD72_FUNC_ALL, .has_get_level = THD72_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THD72_LEVEL_ALL), .has_get_parm = THD72_PARMS, .has_set_parm = THD72_PARMS, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = { [PARM_TIME] = {.min = {.i = 0}, .max = {.i = 86399}, .step = {.i = 1}}, [PARM_APO] = { .min = { .i = 1 }, .max = { .i = 1439} }, }, .ctcss_list = kenwood42_ctcss_list, .dcs_list = thd72dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THD72_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, /* TBC */ .chan_list = { { 0, 999, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* TBC MEM */ RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), THD72_MODES, -1, -1, THD72_VFO}, {MHz(320), MHz(524), THD72_MODES, -1, -1, THD72_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), THD72_MODES_TX, W(0.05), W(5), THD72_VFO}, {MHz(430), MHz(440), THD72_MODES_TX, W(0.05), W(5), THD72_VFO}, RIG_FRNG_END, }, .tuning_steps = { {THD72_MODES, kHz(5)}, {THD72_MODES, kHz(6.25)}, {THD72_MODES, kHz(8.33)}, {THD72_MODES, kHz(10)}, {THD72_MODES, kHz(12.5)}, {THD72_MODES, kHz(15)}, {THD72_MODES, kHz(20)}, {THD72_MODES, kHz(25)}, {THD72_MODES, kHz(30)}, {THD72_MODES, kHz(50)}, RIG_TS_END, }, .filters = { /* mode/filter list, remember: order matters! */ {RIG_MODE_FM, kHz(14)}, {RIG_MODE_FMN, kHz(7)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .priv = (void *)& thd72_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = thd72_open, .set_freq = thd72_set_freq, .get_freq = thd72_get_freq, .set_mode = thd72_set_mode, .get_mode = thd72_get_mode, .set_vfo = thd72_set_vfo, .get_vfo = thd72_get_vfo, .set_ptt = thd72_set_ptt, .set_split_vfo = thd72_set_split_vfo, .get_split_vfo = thd72_get_split_vfo, .set_rptr_shift = thd72_set_rptr_shft, .get_rptr_shift = thd72_get_rptr_shft, .set_rptr_offs = thd72_set_rptr_offs, .get_rptr_offs = thd72_get_rptr_offs, .set_ts = thd72_set_ts, .get_ts = thd72_get_ts, .set_ctcss_tone = thd72_set_ctcss_tone, .get_ctcss_tone = thd72_get_ctcss_tone, .set_dcs_code = thd72_set_dcs_code, .get_dcs_code = thd72_get_dcs_code, .set_ctcss_sql = thd72_set_ctcss_sql, .get_ctcss_sql = thd72_get_ctcss_sql, .set_level = thd72_set_level, .get_level = thd72_get_level, .set_func = thd72_set_func, .get_func = thd72_get_func, .set_parm = thd72_set_parm, .get_parm = thd72_get_parm, .set_mem = thd72_set_mem, .get_mem = thd72_get_mem, .set_channel = thd72_set_channel, .get_channel = thd72_get_channel, //.get_chan_all_cb = thd72_get_chan_all_cb, this doesn't work yet .get_info = th_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/tmv7.c0000644000175000017500000005305514752216205013367 00000000000000/* * Hamlib Kenwood backend - TM-V7 description * Copyright (c) 2004-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "kenwood.h" #include "th.h" #include "misc.h" #include "num_stdio.h" #if 1 #define RIG_ASSERT(x) if (!(x)) { rig_debug(RIG_DEBUG_ERR, "Assertion failed on line %i\n",__LINE__); abort(); } #else #define RIG_ASSERT(x) #endif #define TMV7_FUNC_ALL (\ RIG_FUNC_TBURST \ ) #define TMV7_LEVEL_ALL (\ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_SQL| \ RIG_LEVEL_AF| \ RIG_LEVEL_RFPOWER\ ) #define TMV7_CHANNEL_CAPS \ .freq=1,\ .tx_freq=1,\ .mode=1,\ .tuning_step=1,\ .rptr_shift=1,\ .ctcss_tone=1,\ .ctcss_sql=1,\ .channel_desc=1 #ifndef RIG_TONEMAX #define RIG_TONEMAX 38 #endif #define RIG_VFO_A_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TO_VFO) #define ACKBUF_LEN 128 static rmode_t tmv7_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_AM, }; static struct kenwood_priv_caps tmv7_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = tmv7_mode_table, }; /* tmv7 procs */ static int tmv7_decode_event(RIG *rig); static int tmv7_set_vfo(RIG *rig, vfo_t vfo); static int tmv7_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int tmv7_get_powerstat(RIG *rig, powerstat_t *status); static int tmv7_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int tmv7_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); /* * tm-v7 rig capabilities. */ struct rig_caps tmv7_caps = { RIG_MODEL(RIG_MODEL_TMV7), .model_name = "TM-V7", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_MOBILE, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 1, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_set_func = TMV7_FUNC_ALL, .has_get_level = TMV7_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TMV7_LEVEL_ALL), .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_VFO_A_OP, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, .chan_list = { { 1, 90, RIG_MTYPE_MEM, {TMV7_CHANNEL_CAPS}}, /* normal MEM VHF */ { 101, 190, RIG_MTYPE_MEM, {TMV7_CHANNEL_CAPS}}, /* normal MEM UHF */ { 201, 206, RIG_MTYPE_EDGE, {TMV7_CHANNEL_CAPS}}, /* L MEM */ { 211, 216, RIG_MTYPE_EDGE, {TMV7_CHANNEL_CAPS}}, /* U MEM */ { 221, 222, RIG_MTYPE_CALL, {TMV7_CHANNEL_CAPS}}, /* Call V/U */ RIG_CHAN_END, }, .rx_range_list1 = { {MHz(118), MHz(174), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_A}, {MHz(300), MHz(470), RIG_MODE_FM, -1, -1, RIG_VFO_B}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(118), MHz(174), RIG_MODE_FM, W(5), W(50), RIG_VFO_A}, {MHz(300), MHz(470), RIG_MODE_FM, W(5), W(35), RIG_VFO_B}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(118), MHz(174), RIG_MODE_AM | RIG_MODE_FM, -1, -1, RIG_VFO_A}, {MHz(300), MHz(470), RIG_MODE_FM, -1, -1, RIG_VFO_B}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(118), MHz(174), RIG_MODE_FM, W(5), W(50), RIG_VFO_A}, {MHz(300), MHz(470), RIG_MODE_FM, W(5), W(35), RIG_VFO_B}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(50)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .str_cal = { 4, { {0, -60 }, {1, -30,}, {5, 0}, {7, 20}}}, /* rought guess */ .priv = (void *)& tmv7_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = kenwood_open, .rig_close = kenwood_close, .set_freq = th_set_freq, .get_freq = th_get_freq, .get_mode = tmv7_get_mode, .set_vfo = tmv7_set_vfo, .get_vfo = th_get_vfo, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_channel = tmv7_set_channel, .get_channel = tmv7_get_channel, .set_trn = th_set_trn, .get_trn = th_get_trn, .set_func = th_set_func, .get_func = th_get_func, .get_level = th_get_level, .set_level = th_set_level, .get_info = th_get_info, .get_powerstat = tmv7_get_powerstat, .vfo_op = th_vfo_op, .set_ptt = th_set_ptt, .get_dcd = th_get_dcd, .decode_event = tmv7_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* --------------------------------------------------------------------- */ int tmv7_decode_event(RIG *rig) { char asyncbuf[ACKBUF_LEN]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, NULL, asyncbuf, sizeof(asyncbuf)); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__); if (asyncbuf[0] == 'B' && asyncbuf[1] == 'U' && asyncbuf[2] == 'F') { freq_t freq, offset; int step, shift, rev, tone, ctcss, tonefq, ctcssfq; retval = num_sscanf(asyncbuf, "BUF 0,%"SCNfreq",%d,%d,%d,%d,%d,,%d,,%d,%"SCNfreq, &freq, &step, &shift, &rev, &tone, &ctcss, &tonefq, &ctcssfq, &offset); if (retval != 11) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BUF message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } rig_debug(RIG_DEBUG_TRACE, "%s: Buffer (freq %"PRIfreq" Hz)\n", __func__, freq); /* Callback execution */ if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, RIG_VFO_A, rig->callbacks.vfo_arg); } if (rig->callbacks.freq_event) { rig->callbacks.freq_event(rig, RIG_VFO_A, freq, rig->callbacks.freq_arg); } /* if (rig->callbacks.mode_event) { rig->callbacks.mode_event(rig, RIG_VFO_A, mode, RIG_PASSBAND_NORMAL, rig->callbacks.mode_arg); } */ /* --------------------------------------------------------------------- */ } else if (asyncbuf[0] == 'S' && asyncbuf[1] == 'M') { int lev; retval = sscanf(asyncbuf, "SM 0,%d", &lev); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected SM message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } rig_debug(RIG_DEBUG_TRACE, "%s: Signal strength event - signal = %.3f\n", __func__, (float)(lev / 5.0)); /* Callback execution */ #if STILLHAVETOADDCALLBACK if (rig->callbacks.strength_event) rig->callbacks.strength_event(rig, RIG_VFO_0, (float)(lev / 5.0), rig->callbacks.strength_arg); #endif /* --------------------------------------------------------------------- */ } else if (asyncbuf[0] == 'B' && asyncbuf[1] == 'Y') { int busy; retval = sscanf(asyncbuf, "BY 0,%d", &busy); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BY message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } rig_debug(RIG_DEBUG_TRACE, "%s: Busy event - status = '%s'\n", __func__, (busy == 0) ? "OFF" : "ON"); return -RIG_ENIMPL; /* This event does not have a callback. */ /* --------------------------------------------------------------------- */ } else if (asyncbuf[0] == 'V' && asyncbuf[1] == 'M' && asyncbuf[2] == 'C') { vfo_t bandmode; retval = sscanf(asyncbuf, "VMC 0,%u", &bandmode); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VMC message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } switch (bandmode) { case 0: bandmode = RIG_VFO_VFO; break; case 2: bandmode = RIG_VFO_MEM; break; /* case 3: bandmode = RIG_VFO_CALL; break; */ default: bandmode = RIG_VFO_CURR; break; } rig_debug(RIG_DEBUG_TRACE, "%s: Mode of Band event - %u\n", __func__, bandmode); /* TODO: This event does not have a callback! */ return -RIG_ENIMPL; /* --------------------------------------------------------------------- */ } else { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf); return -RIG_ENIMPL; } return RIG_OK; } /* --------------------------------------------------------------------- */ int tmv7_set_vfo(RIG *rig, vfo_t vfo) { char vfobuf[16], ackbuf[ACKBUF_LEN]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,0"); break; case RIG_VFO_B: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 1,0"); break; case RIG_VFO_MEM: SNPRINTF(vfobuf, sizeof(vfobuf), "BC"); retval = kenwood_transaction(rig, vfobuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "VMC %c,2", ackbuf[3]); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: bad return \n", __func__); return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: next %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: SNPRINTF(vfobuf, sizeof(vfobuf), "BC 0,0"); break; case RIG_VFO_B: SNPRINTF(vfobuf, sizeof(vfobuf), "BC 1,1"); break; case RIG_VFO_MEM: return RIG_OK; default: return RIG_OK; } rig_debug(RIG_DEBUG_TRACE, "%s: next2\n", __func__); retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* --------------------------------------------------------------------- */ int tmv7_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char ackbuf[ACKBUF_LEN]; int retval; int step; freq_t freq; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_CURR: break; case RIG_VFO_A: break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } /* try to guess from frequency */ retval = kenwood_transaction(rig, "FQ", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } num_sscanf(ackbuf, "FQ %"SCNfreq",%d", &freq, &step); if (freq < MHz(137)) { *mode = RIG_MODE_AM; *width = kHz(9); } else { *mode = RIG_MODE_FM; *width = kHz(12); } return RIG_OK; } int tmv7_get_powerstat(RIG *rig, powerstat_t *status) { /* dummy func to make sgcontrol happy */ *status = RIG_POWER_ON; return RIG_OK; } /* --------------------------------------------------------------------- */ int tmv7_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { char membuf[64], ackbuf[ACKBUF_LEN]; int retval; freq_t freq; char req[32], scf[128]; int step, shift, rev, tone, ctcss, tonefq, ctcssfq; if (chan->channel_num < 100) { SNPRINTF(req, sizeof(req), "MR 0,0,%03d", chan->channel_num); } else if (chan->channel_num < 200) { SNPRINTF(req, sizeof(req), "MR 1,0,%03d", chan->channel_num - 100); } else if (chan->channel_num < 204) { SNPRINTF(req, sizeof(req), "MR 0,0,L%01d", chan->channel_num - 200); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "L%01d/V", chan->channel_num - 200); } else if (chan->channel_num < 211) { SNPRINTF(req, sizeof(req), "MR 1,0,L%01d", chan->channel_num - 203); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "L%01d/U", chan->channel_num - 203); } else if (chan->channel_num < 214) { SNPRINTF(req, sizeof(req), "MR 0,0,U%01d", chan->channel_num - 210); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "U%01d/V", chan->channel_num - 210); } else if (chan->channel_num < 220) { SNPRINTF(req, sizeof(req), "MR 1,0,U%01d", chan->channel_num - 213); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "U%01d/U", chan->channel_num - 213); } else if (chan->channel_num < 223) { if (chan->channel_num == 221) { SNPRINTF(req, sizeof(req), "CR 0,0"); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call V"); } if (chan->channel_num == 222) { SNPRINTF(req, sizeof(req), "CR 1,0"); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call U"); } } else { return -RIG_EINVAL; } SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } strcpy(scf, req); strcat(scf, ",%"SCNfreq",%d,%d,%d,%d,0,%d,%d,000,%d,,0"); retval = num_sscanf(ackbuf, scf, &freq, &step, &shift, &rev, &tone, &ctcss, &tonefq, &ctcssfq); chan->freq = freq; chan->vfo = RIG_VFO_MEM; chan->tuning_step = STATE(rig)->tuning_steps[step].ts; if (freq < MHz(138)) { chan->mode = RIG_MODE_AM; } else { chan->mode = RIG_MODE_FM; } switch (shift) { case 0 : chan->rptr_shift = RIG_RPT_SHIFT_NONE; break; case 1 : chan->rptr_shift = RIG_RPT_SHIFT_PLUS; break; case 2 : chan->rptr_shift = RIG_RPT_SHIFT_MINUS; break; } if (tone) { chan->ctcss_tone = rig->caps->ctcss_list[tonefq == 1 ? 0 : tonefq - 2]; } else { chan->ctcss_tone = 0; } if (ctcss) { chan->ctcss_sql = rig->caps->ctcss_list[ctcssfq == 1 ? 0 : ctcssfq - 2]; } else { chan->ctcss_sql = 0; } chan->tx_freq = RIG_FREQ_NONE; if (chan->channel_num < 223 && shift == 0) { req[5] = '1'; SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval == RIG_OK) { strcpy(scf, req); strcat(scf, ",%"SCNfreq",%d"); num_sscanf(ackbuf, scf, &freq, &step); chan->tx_freq = freq; } } if (chan->channel_num < 200) { if (chan->channel_num < 100) { SNPRINTF(membuf, sizeof(membuf), "MNA 0,%03d", chan->channel_num); } else { SNPRINTF(membuf, sizeof(membuf), "MNA 1,%03d", chan->channel_num - 100); } retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } memcpy(chan->channel_desc, &ackbuf[10], 7); } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } /* --------------------------------------------------------------------- */ int tmv7_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char membuf[ACKBUF_LEN]; int retval; char req[64]; long freq; int step, shift, tone, ctcss, tonefq, ctcssfq; freq = (long)chan->freq; for (step = 0; STATE(rig)->tuning_steps[step].ts != 0; step++) if (chan->tuning_step == STATE(rig)->tuning_steps[step].ts) { break; } switch (chan->rptr_shift) { case RIG_RPT_SHIFT_NONE : shift = 0; break; case RIG_RPT_SHIFT_PLUS: shift = 1; break; case RIG_RPT_SHIFT_MINUS: shift = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: not supported shift\n", __func__); return -RIG_EINVAL; } if (chan->ctcss_tone == 0) { tone = 0; tonefq = 9; } else { tone = 1; for (tonefq = 0; rig->caps->ctcss_list[tonefq] != 0; tonefq++) { if (rig->caps->ctcss_list[tonefq] == chan->ctcss_tone) { break; } } tonefq = tonefq == 0 ? 1 : tonefq + 2; } if (chan->ctcss_sql == 0) { ctcss = 0; ctcssfq = 9; } else { ctcss = 1; for (ctcssfq = 0; rig->caps->ctcss_list[ctcssfq] != 0; ctcssfq++) { if (rig->caps->ctcss_list[ctcssfq] == chan->ctcss_sql) { break; } } ctcssfq = ctcssfq == 0 ? 1 : ctcssfq + 2; } if (chan->channel_num < 100) { SNPRINTF(req, sizeof(req), "MW 0,0,%03d", chan->channel_num); } else if (chan->channel_num < 200) { SNPRINTF(req, sizeof(req), "MW 1,0,%03d", chan->channel_num - 100); } else if (chan->channel_num < 204) { SNPRINTF(req, sizeof(req), "MW 0,0,L%01d", chan->channel_num - 200); } else if (chan->channel_num < 211) { SNPRINTF(req, sizeof(req), "MW 1,0,L%01d", chan->channel_num - 203); } else if (chan->channel_num < 214) { SNPRINTF(req, sizeof(req), "MW 0,0,U%01d", chan->channel_num - 210); } else if (chan->channel_num < 220) { SNPRINTF(req, sizeof(req), "MW 1,0,U%01d", chan->channel_num - 213); } else if (chan->channel_num < 223) { if (chan->channel_num == 221) { SNPRINTF(req, sizeof(req), "CW 0,0"); } if (chan->channel_num == 222) { SNPRINTF(req, sizeof(req), "CW 1,0"); } } else { return -RIG_EINVAL; } if (chan->channel_num < 221) { SNPRINTF(membuf, sizeof(membuf), "%s,%011ld,%01d,%01d,0,%01d,%01d,0,%02d,000,%02d,0,0", req, (long)freq, step, shift, tone, ctcss, tonefq, ctcssfq); } else { SNPRINTF(membuf, sizeof(membuf), "%s,%011ld,%01d,%01d,0,%01d,%01d,0,%02d,000,%02d,", req, (long)freq, step, shift, tone, ctcss, tonefq, ctcssfq); } retval = kenwood_transaction(rig, membuf, NULL, 0); if (retval != RIG_OK) { return retval; } if (chan->tx_freq != RIG_FREQ_NONE) { req[5] = '1'; SNPRINTF(membuf, sizeof(membuf), "%s,%011"PRIll",%01d", req, (int64_t)chan->tx_freq, step); retval = kenwood_transaction(rig, membuf, NULL, 0); if (retval != RIG_OK) { return retval; } } if (chan->channel_num < 200) { if (chan->channel_num < 100) { SNPRINTF(membuf, sizeof(membuf), "MNA 0,%03d,%s", chan->channel_num, chan->channel_desc); } else { SNPRINTF(membuf, sizeof(membuf), "MNA 1,%03d,%s", chan->channel_num - 100, chan->channel_desc); } retval = kenwood_transaction(rig, membuf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } hamlib-4.6.2/rigs/kenwood/ts940.c0000644000175000017500000001354214752216205013352 00000000000000/* * Hamlib Kenwood backend - TS940 description * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "bandplan.h" #include "kenwood.h" #define TS940_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_CW|RIG_MODE_SSB) #define TS940_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS940_AM_TX_MODES RIG_MODE_AM #define TS940_FUNC_ALL RIG_FUNC_LOCK #define TS940_LEVEL_ALL RIG_LEVEL_NONE #define TS940_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS940_ANTS (0) #define TS940_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS940_SCAN_OPS (RIG_SCAN_VFO) /* memory capabilities */ #define TS940_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ } static rmode_t ts940_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_NONE, [7] = RIG_MODE_NONE, [8] = RIG_MODE_NONE, [9] = RIG_MODE_NONE }; static struct kenwood_priv_caps ts940_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = ts940_mode_table, .tone_table_base = 1, }; /* * ts940 rig capabilities. * written from specs: * http://www.qsl.net/sm7vhs/radio/kenwood/ts940/specs.htm * * TODO: protocol to be check with manual! */ struct rig_caps ts940_caps = { RIG_MODEL(RIG_MODEL_TS940), .model_name = "TS-940S", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .timeout = 600, .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = TS940_FUNC_ALL, .has_get_level = TS940_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS940_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { RIG_DBLST_END, }, /* TBC */ .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = TS940_VFO_OPS, .scan_ops = TS940_SCAN_OPS, .transceive = RIG_TRN_RIG, // Unknown AGC levels .bank_qty = 0, .chan_desc_sz = 0, /* four banks of 10 memories */ .chan_list = { { 0, 0, RIG_MTYPE_EDGE, TS940_MEM_CAP}, /* TBC */ { 1, 8, RIG_MTYPE_MEM, TS940_MEM_CAP}, /* TBC */ { 9, 9, RIG_MTYPE_EDGE, TS940_MEM_CAP}, /* TBC */ RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS940_ALL_MODES, -1, -1, TS940_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS940_OTHER_TX_MODES, W(5), W(250), TS940_VFO, TS940_ANTS), FRQ_RNG_HF(1, TS940_AM_TX_MODES, W(4), W(140), TS940_VFO, TS940_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS940_ALL_MODES, -1, -1, TS940_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS940_OTHER_TX_MODES, W(5), W(250), TS940_VFO, TS940_ANTS), FRQ_RNG_HF(2, TS940_AM_TX_MODES, W(4), W(140), TS940_VFO, TS940_ANTS), /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TS940_ALL_MODES, 10}, {TS940_ALL_MODES, kHz(100)}, {TS940_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts940_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split, .get_split_vfo = kenwood_get_split_vfo_if, .set_ptt = kenwood_set_ptt, .get_ptt = kenwood_get_ptt, .set_func = kenwood_set_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .set_trn = kenwood_set_trn, .scan = kenwood_scan, .set_channel = kenwood_set_channel, .get_channel = kenwood_get_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/ts450s.c0000644000175000017500000002163414752216205013532 00000000000000/* * Hamlib Kenwood backend - TS450S description * Copyright (c) 2000-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #include "bandplan.h" #define TS450S_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS450S_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS450S_AM_TX_MODES RIG_MODE_AM #define TS450S_FUNC_ALL (RIG_FUNC_LOCK|RIG_FUNC_AIP|RIG_FUNC_TONE) #define TS450S_LEVEL_ALL (RIG_LEVEL_STRENGTH|RIG_LEVEL_CWPITCH|RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define TS450S_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS450S_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS450S_SCAN_OPS (RIG_SCAN_VFO) #define TS450S_CHANNEL_CAPS { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .funcs=RIG_FUNC_TONE, \ .flags=RIG_CHFLAG_SKIP \ } static struct kenwood_priv_caps ts450_priv_caps = { .cmdtrm = EOM_KEN, }; static const struct confparams ts450_ext_parms[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; int ts450_open(RIG *rig) { int err; int maxtries; err = kenwood_open(rig); if (err != RIG_OK) { return err; } maxtries = RIGPORT(rig)->retry; /* no retry for this command that may be missing */ RIGPORT(rig)->retry = 0; err = kenwood_simple_transaction(rig, "TO", 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: tone unit not detected\n", __func__); STATE(rig)->has_set_func &= ~RIG_FUNC_TONE; STATE(rig)->has_get_func &= ~RIG_FUNC_TONE; } RIGPORT(rig)->retry = maxtries; return RIG_OK; } /* * ts450s rig capabilities. * Notice that some rigs share the same functions. * RIT: Variable Range ±9.99 kHz * * TODO: protocol to be checked with manual (identical to TS690) * - get_channel/set_channel: MR/MW * - how to set_split in vfo mode? * - ... * * specs: http://www.qsl.net/sm7vhs/radio/kenwood/ts450/specs.htm * infos comes from http://www.cnham.com/ts450/ts_450_ex_control.pdf */ struct rig_caps ts450s_caps = { RIG_MODEL(RIG_MODEL_TS450S), .model_name = "TS-450S", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 10, .timeout = 1000, .retry = 10, .has_get_func = TS450S_FUNC_ALL, .has_set_func = TS450S_FUNC_ALL, .has_get_level = TS450S_LEVEL_ALL | RIG_LEVEL_RFPOWER, .has_set_level = RIG_LEVEL_SET(TS450S_LEVEL_ALL), .has_get_parm = 0, .has_set_parm = 0, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .extparms = ts450_ext_parms, .ctcss_list = NULL, /* hw dip-switch */ .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, /* can't be controlled */ .max_rit = Hz(9999), .max_xit = Hz(9999), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = TS450S_VFO_OPS, .scan_ops = TS450S_SCAN_OPS, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS450S_CHANNEL_CAPS }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE, TS450S_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { { kHz(500), MHz(30), TS450S_ALL_MODES, -1, -1, TS450S_VFO }, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS450S_OTHER_TX_MODES, W(5), W(100), TS450S_VFO, 0), FRQ_RNG_HF(1, TS450S_AM_TX_MODES, W(2), W(40), TS450S_VFO, 0), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS450S_ALL_MODES, -1, -1, TS450S_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, /* 40W class */ {kHz(3500), MHz(4) - 1, TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(3500), MHz(4) - 1, TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(7), kHz(7300), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(7), kHz(7300), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {kHz(10100), kHz(10150), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(10100), kHz(10150), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(14), kHz(14350), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(14), kHz(14350), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {kHz(18068), kHz(18168), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(18068), kHz(18168), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(21), kHz(21450), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(21), kHz(21450), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {kHz(24890), kHz(24990), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {kHz(24890), kHz(24990), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, {MHz(28), kHz(29700), TS450S_OTHER_TX_MODES, 5000, 100000, TS450S_VFO}, {MHz(28), kHz(29700), TS450S_AM_TX_MODES, 2000, 40000, TS450S_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { { TS450S_ALL_MODES, 1 }, { TS450S_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12) }, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, Hz(500)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR, kHz(6)}, RIG_FLT_END, }, .priv = (void *)& ts450_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = ts450_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .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_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .scan = kenwood_scan, .get_channel = kenwood_get_channel, .set_channel = kenwood_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/ts990s.c0000644000175000017500000006305614752216205013547 00000000000000/* * Hamlib Kenwood backend - TS990s description * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2015 modified from ts2000.c by Bill Somerville G4WJS * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "ts990s.h" #include "cal.h" #define TS990S_AM_MODES RIG_MODE_AM #define TS990S_FM_MODES (RIG_MODE_FM|RIG_MODE_FMN) #define TS990S_OTHER_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB|RIG_MODE_USBD1|RIG_MODE_USBD2|RIG_MODE_USBD3|RIG_MODE_LSBD1|RIG_MODE_LSBD2|RIG_MODE_LSBD3) #define TS990S_HP_MODES (TS990S_OTHER_MODES|TS990S_FM_MODES) #define TS990S_ALL_MODES (TS990S_OTHER_MODES|TS990S_AM_MODES|TS990S_FM_MODES) #define TS990S_VFOS (RIG_VFO_MAIN|RIG_VFO_SUB) #define TS2000_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_BC|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_COMP) #define TS2000_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_COMP|RIG_LEVEL_AGC|RIG_LEVEL_BKINDL|RIG_LEVEL_METER|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR) #define TS990S_VFO_OP (RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_TUNE) #define TS990S_SCAN_OP (RIG_SCAN_VFO) #define TS990S_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) // Measurements from Wolfgang OE1MWW #define TS990S_STR_CAL {7, {\ {0x00, -54},\ {0x04, -48},\ {0x0B, -36},\ {0x13, -24},\ {0x1B, -12},\ {0x23, 0},\ {0x46, 60}}\ } #define TS990S_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 7, 1.5f }, \ { 36, 3.0f }, \ { 43, 6.0f }, \ { 70, 10.0f } \ } } /* memory capabilities */ #define TS990S_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* prototypes */ static int ts990s_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ts990s_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); static rmode_t ts990s_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_RTTY, [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, [9] = RIG_MODE_RTTYR, [10] = RIG_MODE_NONE, /* A */ [11] = RIG_MODE_NONE, /* B */ [12] = RIG_MODE_LSBD1, /* C */ [13] = RIG_MODE_USBD1, /* D */ [14] = RIG_MODE_PKTFM, /* E */ [15] = RIG_MODE_NONE, /* F */ [16] = RIG_MODE_LSBD2, /* G */ [17] = RIG_MODE_USBD2, /* H */ [18] = RIG_MODE_PKTFM, /* I */ [19] = RIG_MODE_NONE, /* J */ [20] = RIG_MODE_LSBD3, /* K */ [21] = RIG_MODE_USBD3, /* L */ [22] = RIG_MODE_PKTFM, /* M */ [23] = RIG_MODE_NONE, /* N */ }; static struct kenwood_priv_caps ts990s_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = ts990s_mode_table, .tone_table_base = 0, }; /* * ts990s rig capabilities. * * part of infos comes from http://www.kenwood.net/ */ struct rig_caps ts990s_caps = { RIG_MODEL(RIG_MODEL_TS990S), .model_name = "TS-990S", .mfg_name = "Kenwood", .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 = 4800, .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, /* ms */ .timeout = 500, .retry = 10, .has_get_func = TS2000_FUNC_ALL, .has_set_func = TS2000_FUNC_ALL, .has_get_level = TS2000_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS2000_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #define NO_LVL_CWPITCH #define NO_LVL_COMP #include "level_gran_kenwood.h" #undef NO_LVL_ATT #undef NO_LVL_CWPITCH #undef NO_LVL_COMP [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 1100 }, .step = { .i = 10 } }, [LVL_COMP] = { .min = { .f = 0.0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, }, .parm_gran = {}, .vfo_ops = TS990S_VFO_OP, .scan_ops = TS990S_SCAN_OP, .ctcss_list = kenwood42_ctcss_list, .preamp = { 20, RIG_DBLST_END, }, .attenuator = { 6, 12, 18, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_ON }, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TS990S_MEM_CAP }, { 1, 6, RIG_MTYPE_VOICE }, { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TS990S_ALL_MODES, -1, -1, TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(1830), kHz(1850), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), kHz(3800), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), kHz(3800), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7100), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7100), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(50.2), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(50.2), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TS990S_ALL_MODES, -1, -1, TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(1800), MHz(2), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), MHz(4), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(3500), MHz(4), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7300), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(7), kHz(7300), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(10.1), MHz(10.15), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(14), kHz(14350), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(18068), kHz(18168), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(21), kHz(21450), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {kHz(24890), kHz(24990), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(28), kHz(29700), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(54), TS990S_HP_MODES, W(5), W(200), TS990S_VFOS, TS990S_ANTS}, {MHz(50), MHz(54), TS990S_AM_MODES, W(5), W(50), TS990S_VFOS, TS990S_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS990S_OTHER_MODES, 1}, {TS990S_OTHER_MODES, kHz(0.5)}, {TS990S_OTHER_MODES, kHz(1)}, {TS990S_OTHER_MODES, kHz(2.5)}, {TS990S_OTHER_MODES, kHz(5)}, {TS990S_OTHER_MODES, kHz(10)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(5)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(6.25)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(10)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(12.5)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(15)}, {(TS990S_AM_MODES | TS990S_FM_MODES), kHz(20)}, {TS990S_ALL_MODES, MHz(1)}, {TS990S_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.6)}, /* default normal */ {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.0)}, /* default narrow - arbitrary choice */ {RIG_MODE_SSB | TS990S_FM_MODES, kHz(3.2)}, /* default wide - arbitrary choice */ {RIG_MODE_SSB | TS990S_FM_MODES, kHz(4.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(3.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(2.4)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.8)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.4)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.2)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(1.0)}, {RIG_MODE_SSB | TS990S_FM_MODES, kHz(0.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, /* default normal */ {RIG_MODE_CW | RIG_MODE_CWR, Hz(250)}, /* default narrow - arbitrary choice */ {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.0)}, /* default wide - arbitrary choice */ {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.5)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.0)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1.5)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, /* default normal */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, /* default narrow - arbitrary choice */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, /* default wide - arbitrary choice */ {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(400)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_AM, kHz(5)}, /* default normal */ {RIG_MODE_AM, kHz(2.5)}, /* default narrow - arbitrary choice */ {RIG_MODE_AM, kHz(4)}, {RIG_MODE_AM, kHz(3)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.6)}, /* default normal */ {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(500)}, /* default narrow - arbitrary choice */ {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(13)}, /* default wide - arbitrary choice */ {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.8)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.4)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.2)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.0)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.5)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(1.0)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(600)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(400)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(300)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(200)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(150)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(100)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(80)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, Hz(50)}, RIG_FLT_END, }, .str_cal = TS990S_STR_CAL, .swr_cal = TS990S_SWR_CAL, .priv = (void *)& ts990s_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit_new, .get_rit = kenwood_get_rit_new, .set_xit = kenwood_set_rit_new, // Use same routines as for rit .get_xit = kenwood_get_rit_new, // Same .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo_main_sub, .get_vfo = kenwood_get_vfo_main_sub, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = ts990s_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = ts990s_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .stop_morse = kenwood_stop_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .get_clock = kenwood_get_clock, .set_clock = kenwood_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * ts990s_get_level * Assumes rig!=NULL, val!=NULL */ int ts990s_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; int lvl, retval = RIG_OK; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { return retval; } } switch (level) { case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", lvlbuf, sizeof(lvlbuf), 4); if (retval != RIG_OK) { return retval; } switch (vfo) { case RIG_VFO_MAIN: val->i = '1' == lvlbuf[2] ? STATE(rig)->preamp[0] : 0; break; case RIG_VFO_SUB: val->i = '1' == lvlbuf[3] ? STATE(rig)->preamp[0] : 0; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } break; case RIG_LEVEL_ATT: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "RA%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 4); if (retval != RIG_OK) { return retval; } if ('0' == lvlbuf[3]) { val->i = 0; } else { val->i = STATE(rig)->attenuator[lvlbuf[3] - '1']; } } break; case RIG_LEVEL_VOXDELAY: retval = kenwood_safe_transaction(rig, "VD0", lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->i = lvl * 3 / 2; /* 150ms units converted to 100ms units */ break; case RIG_LEVEL_AF: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "AG%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; } break; case RIG_LEVEL_RF: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "RG%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; } break; case RIG_LEVEL_SQL: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "SQ%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; } break; case RIG_LEVEL_RFPOWER: retval = kenwood_safe_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 200.0; /* TODO: should we detect AM and scale? */ break; case RIG_LEVEL_MICGAIN: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_KEYSPD: retval = kenwood_safe_transaction(rig, "KS", lvlbuf, sizeof(lvlbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl; break; case RIG_LEVEL_COMP: retval = kenwood_safe_transaction(rig, "PL", lvlbuf, sizeof(lvlbuf), 8); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); lvl = lvl / 1000; /* report input level */ val->f = lvl / 255.0; break; case RIG_LEVEL_AGC: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "GC%c", v); if (RIG_OK != (retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 4))) { return retval; } switch (lvlbuf[3]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_SLOW; break; case '2': val->i = RIG_AGC_MEDIUM; break; case '3': val->i = RIG_AGC_FAST; break; } } break; case RIG_LEVEL_BKINDL: retval = kenwood_safe_transaction(rig, "SD", lvlbuf, sizeof(lvlbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_SWR: retval = get_kenwood_meter_reading(rig, '2', &lvl); if (retval != RIG_OK) { return retval; } val->f = rig_raw2val_float(lvl, &rig->caps->swr_cal); val->f = round(val->f * 10) / 10.0; // 1 decimal place precision break; case RIG_LEVEL_METER: retval = kenwood_safe_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf), 7); if (retval != RIG_OK) { return retval; } switch (lvlbuf[2]) { case '1': val->i = RIG_METER_ALC; break; case '2': val->i = RIG_METER_SWR; break; case '3': val->i = RIG_METER_COMP; break; case '4': val->i = RIG_METER_IC; break; case '5': val->i = RIG_METER_VDD; break; default: val->i = RIG_METER_NONE; break; } break; case RIG_LEVEL_VOXGAIN: retval = get_kenwood_level(rig, "VG00", &val->f, NULL); if (retval != RIG_OK) { return retval; } break; case RIG_LEVEL_ANTIVOX: retval = get_kenwood_level(rig, "VG00", &val->f, NULL); if (retval != RIG_OK) { return retval; } val->f = val->f * 255. / 20.; break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: { char v; char cmd[4]; switch (vfo) { case RIG_VFO_MAIN: v = '0'; break; case RIG_VFO_SUB: v = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), "SM%c", v); retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), 7); if (retval != RIG_OK) { return retval; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 3, "%d", &val->i); /* TS-990s returns values from 0 - 70 */ /* so scale the value */ if (level == RIG_LEVEL_STRENGTH) { val->i = (val->i * 54. / 70.) - 54; } } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return retval; } /* * Gets split VFO status * */ static int ts990s_get_split_vfo(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { char buf[4]; int retval; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; if (RIG_OK == (retval = kenwood_safe_transaction(rig, "TB", buf, sizeof(buf), 3))) { if ('1' == buf[2]) { *split = RIG_SPLIT_ON; *txvfo = RIG_VFO_SUB; } else { *split = RIG_SPLIT_OFF; *txvfo = RIG_VFO_MAIN; } priv->tx_vfo = rs->tx_vfo = *txvfo; } return retval; } hamlib-4.6.2/rigs/kenwood/README.k20000644000175000017500000000273514752216205013520 00000000000000Elecraft K2 notes and Hamlib errata by Nate Bargmann, N0NB. The K2 shares some backend code with the K3. This code can be found in elecraft.[c|h] while any K2 specific is found in k2.c As always, comments and bug reports should be submitted to hamlib-developer@lists.sourceforge.net elecraft_open() =============== The kenwood_open() function fails for the Elecraft radios as the function checks the backend to be certain the ID from the radio matches the backend that called the function. As the ID command of the Elecraft radios returns "017" which corresponds to the TS-570, the backend test fails. Rather than muck up a working function, I chose to implement an independent elecraft_open which not only checks for the existence of a connected radio that returns an ID of "017", it also checks for K2 or K3 extensions and sets a pair of private variables that may be used later for advanced functions. This way the backend should be able to reliably test for either a K2 or K3 (needs more testing with the K2). This function also probes the K2 for the RTTY option and then installed filters and bandwidths. This information is stored in a structure and used later. The probe adds about 10 seconds to the rig_open. kenwood_get/set_ext_parms() =========================== These functions are used to get and set RIT/XIT on and off. The special token names of 'rit' and 'xit' are used with the P/p commands of rigctl[d] for the 'parm'. Set/returned value is 0 or 1 for off or on. hamlib-4.6.2/rigs/kenwood/ts990s.h0000644000175000017500000000172114752216205013543 00000000000000/* * Hamlib Kenwood backend - main header * Copyright (c) 2015 by Bill Somerville G4WJS * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef TS990S_H__ #define TS990S_H__ #include "hamlib/rig.h" extern struct rig_caps ts990s_caps; #endif hamlib-4.6.2/rigs/kenwood/ts850.c0000644000175000017500000003564414752216205013361 00000000000000/* * Hamlib Kenwood backend - TS850 description * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include #include "kenwood.h" #define TS850_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS850_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS850_AM_TX_MODES (RIG_MODE_AM) #define TS850_FUNC_ALL (RIG_FUNC_AIP|RIG_FUNC_LOCK) #define TS850_LEVEL_GET (RIG_LEVEL_SWR|RIG_LEVEL_COMP|RIG_LEVEL_ALC|RIG_LEVEL_CWPITCH|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_SLOPE_HIGH) #define TS850_LEVEL_SET (RIG_LEVEL_CWPITCH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_SLOPE_HIGH) #define TS850_VFO (RIG_VFO_A|RIG_VFO_B) #define TS850_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS850_CHANNEL_CAPS \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .flags=RIG_CHFLAG_SKIP, \ .ctcss_tone=1 #define TS850_STR_CAL { 4, \ { \ { 0, -54 }, \ { 15, 0 }, \ { 22,30 }, \ { 30, 66}, \ } } static struct kenwood_priv_caps ts850_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* forward definitions */ static int ts850_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); static int ts850_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); static int ts850_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ts850_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static const struct confparams ts850_ext_parms[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; /* * ts850 rig capabilities. * Notice that some rigs share the same functions. */ struct rig_caps ts850_caps = { RIG_MODEL(RIG_MODEL_TS850), .model_name = "TS-850", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 100, .timeout = 500, .retry = 10, .has_get_func = TS850_FUNC_ALL, .has_set_func = TS850_FUNC_ALL, .has_get_level = TS850_LEVEL_GET, .has_set_level = TS850_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_CWPITCH #include "level_gran_kenwood.h" #undef NO_LVL_CWPITCH [LVL_CWPITCH] = { .min = { .i = 400 }, .max = { .i = 1000 }, .step = { .i = 50 } }, }, .parm_gran = {}, .extparms = ts850_ext_parms, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(1.27), .max_xit = kHz(1.27), .max_ifshift = Hz(0), .vfo_ops = TS850_VFO_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // No AGC levels .bank_qty = 0, .chan_desc_sz = 3, .chan_list = { { 0, 89, RIG_MTYPE_MEM, {TS850_CHANNEL_CAPS}}, { 90, 99, RIG_MTYPE_EDGE, {TS850_CHANNEL_CAPS}}, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(100), MHz(30), TS850_ALL_MODES, -1, -1, TS850_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, /* 40W class */ {kHz(3500), kHz(3800), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(3500), kHz(3800), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(7), kHz(7100), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(7), kHz(7100), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(10100), kHz(10150), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(10100), kHz(10150), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(14), kHz(14350), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(14), kHz(14350), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(18068), kHz(18168), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(18068), kHz(18168), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(21), kHz(21450), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(21), kHz(21450), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(24890), kHz(24990), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(24890), kHz(24990), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(28), kHz(29700), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(28), kHz(29700), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS850_ALL_MODES, -1, -1, TS850_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, /* 40W class */ {kHz(3500), MHz(4) - 1, TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(3500), MHz(4) - 1, TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(7), kHz(7300), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(7), kHz(7300), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(10100), kHz(10150), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(10100), kHz(10150), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(14), kHz(14350), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(14), kHz(14350), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(18068), kHz(18168), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(18068), kHz(18168), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(21), kHz(21450), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(21), kHz(21450), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {kHz(24890), kHz(24990), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {kHz(24890), kHz(24990), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, {MHz(28), kHz(29700), TS850_OTHER_TX_MODES, W(5), W(100), TS850_VFO}, {MHz(28), kHz(29700), TS850_AM_TX_MODES, W(2), W(40), TS850_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS850_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {TS850_ALL_MODES, kHz(12)}, {TS850_ALL_MODES, kHz(6)}, {TS850_ALL_MODES, kHz(2.7)}, {TS850_ALL_MODES, Hz(500)}, {TS850_ALL_MODES, Hz(250)}, RIG_FLT_END, }, .str_cal = TS850_STR_CAL, .priv = (void *)& ts850_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts850_set_rit, .get_rit = kenwood_get_rit, .set_xit = ts850_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = kenwood_set_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt_safe, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = ts850_get_level, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .get_channel = kenwood_get_channel, .set_channel = ts850_set_channel, .set_trn = kenwood_set_trn, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ int ts850_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[50]; unsigned char c; int retval, i; if (rit == 0) { retval = kenwood_transaction(rig, "RT0", NULL, 0); if (retval != RIG_OK) { return retval; } } else { retval = kenwood_transaction(rig, "RT1", NULL, 0); if (retval != RIG_OK) { return retval; } } if (rit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 20)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } int ts850_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { char buf[50]; unsigned char c; int retval, i; if (xit == 0) { retval = kenwood_transaction(rig, "XT0", NULL, 0); if (retval != RIG_OK) { return retval; } } else { retval = kenwood_transaction(rig, "XT1", NULL, 0); if (retval != RIG_OK) { return retval; } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } if (xit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); for (i = 0; i < labs(lrint(xit / 20)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } static char mode_to_char(rmode_t mode) { switch (mode) { case RIG_MODE_CW: return (MD_CW); case RIG_MODE_CWR: return (MD_CWR); case RIG_MODE_USB: return (MD_USB); case RIG_MODE_LSB: return (MD_LSB); case RIG_MODE_FM: return (MD_FM); case RIG_MODE_AM: return (MD_AM); case RIG_MODE_RTTY: return (MD_FSK); case RIG_MODE_RTTYR: return (MD_FSKR); default: rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); } return (RIG_MODE_NONE); } int ts850_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; int i, retval; if (vfo != RIG_VFO_CURR) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RAWSTR: retval = kenwood_transaction(rig, "SM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); break; case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->i = atoi(&lvlbuf[2]); //val->i = (val->i * 4) - 54; Old approximate way of doing it. val->i = (int)rig_raw2val(val->i, &rig->caps->str_cal); break; case RIG_LEVEL_SWR: retval = kenwood_transaction(rig, "RM1", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } i = atoi(&lvlbuf[3]); if (i == 30) { val->f = 150.0; /* infinity :-) */ } else { val->f = 60.0 / (30.0 - (float)i) - 1.0; } break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "RM2", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; case RIG_LEVEL_ALC: retval = kenwood_transaction(rig, "RM3", NULL, 0); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } val->f = (float)atoi(&lvlbuf[3]) / 30.0; break; default: return kenwood_get_level(rig, vfo, level, val); } return retval; // Never gets here. } int ts850_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char cmdbuf[30]; int retval; int num, freq, tx_freq, tone; char mode, tx_mode, tones; num = chan->channel_num; freq = (int)chan->freq; mode = mode_to_char(chan->mode); if (chan->split == RIG_SPLIT_ON) { tx_freq = (int)chan->tx_freq; tx_mode = mode_to_char(chan->tx_mode); } else { tx_freq = 0; tx_mode = '\0'; } for (tone = 1; rig->caps->ctcss_list[tone - 1] != 0 && tone < 39; tone++) { if (rig->caps->ctcss_list[tone - 1] == chan->ctcss_tone) { break; } } if (chan->ctcss_tone != 0) { tones = '1'; } else { tones = '0'; tone = 0; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW0 %02d%011d%c0%c%02d ", num, freq, mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW1 %02d%011d%c0%c%02d ", num, tx_freq, tx_mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } hamlib-4.6.2/rigs/kenwood/ts930.c0000644000175000017500000001332514752216205013350 00000000000000/* * Hamlib Kenwood backend - TS930 description * Copyright (c) 2000-2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #define TS930_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TS930_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TS930_AM_TX_MODES RIG_MODE_AM /* FIXME: TBC */ #define TS930_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_LOCK) #define TS930_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_AGC) #define TS930_VFO (RIG_VFO_A|RIG_VFO_B) #define TS930_ANTS (0) static struct kenwood_priv_caps ts930_priv_caps = { .cmdtrm = EOM_KEN, }; /* * ts930 rig capabilities. * Notice that some rigs share the same functions. * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts930_caps = { RIG_MODEL(RIG_MODEL_TS930), .model_name = "TS-930", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = TS930_FUNC_ALL, .has_set_func = TS930_FUNC_ALL, .has_get_level = TS930_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS930_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #include "level_gran_kenwood.h" #undef NO_LVL_ATT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 18 }, .step = { .i = 6 } }, }, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* FIXME: preamp list */ .attenuator = { 6, 12, 18, RIG_DBLST_END, }, /* TBC */ .max_rit = kHz(9.99), .max_xit = kHz(9.99), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // AGC levels unknown .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(150), MHz(30), TS930_ALL_MODES, -1, -1, TS930_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS930_OTHER_TX_MODES, W(5), W(250), TS930_VFO, TS930_ANTS), FRQ_RNG_HF(1, TS930_AM_TX_MODES, W(4), W(80), TS930_VFO, TS930_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(150), MHz(30), TS930_ALL_MODES, -1, -1, TS930_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(1, TS930_OTHER_TX_MODES, W(5), W(250), TS930_VFO, TS930_ANTS), FRQ_RNG_HF(1, TS930_AM_TX_MODES, W(4), W(80), TS930_VFO, TS930_ANTS), /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TS930_ALL_MODES, 50}, {TS930_ALL_MODES, 100}, {TS930_ALL_MODES, kHz(1)}, {TS930_ALL_MODES, kHz(5)}, {TS930_ALL_MODES, kHz(9)}, {TS930_ALL_MODES, kHz(10)}, {TS930_ALL_MODES, 12500}, {TS930_ALL_MODES, kHz(20)}, {TS930_ALL_MODES, kHz(25)}, {TS930_ALL_MODES, kHz(100)}, {TS930_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_AM, kHz(2.7)}, RIG_FLT_END, }, .priv = (void *)& ts930_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, // we don't know the ID for this rig .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/th.c0000644000175000017500000016505414752216205013110 00000000000000/* * Hamlib Kenwood backend - TH handheld primitives * Copyright (c) 2001-2010 by Stephane Fillod * Copyright (C) 2010 by Alessandro Zummo * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include /* String function definitions */ #include "hamlib/rig.h" #include "kenwood.h" #include "th.h" #include "misc.h" #include "num_stdio.h" /* Note: Currently the code assumes the command termination is a * single character. */ #define ACKBUF_LEN 64 /* * th_decode_event is called by sa_sigio, when some asynchronous * data has been received from the rig. */ int th_decode_event(RIG *rig) { char asyncbuf[128]; int retval; int async_len; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, NULL, asyncbuf, sizeof(asyncbuf)); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__); async_len = strlen(asyncbuf); if (async_len > 3 && asyncbuf[0] == 'B' && asyncbuf[1] == 'U' && asyncbuf[2] == 'F') { vfo_t vfo; freq_t freq, offset; int mode; int step, shift, rev, tone, ctcss, tonefq, ctcssfq; retval = num_sscanf(asyncbuf, "BUF %u,%"SCNfreq",%X,%d,%d,%d,%d,,%d,,%d,%"SCNfreq",%d", &vfo, &freq, (unsigned int *)&step, &shift, &rev, &tone, &ctcss, &tonefq, &ctcssfq, &offset, &mode); if (retval != 11) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BUF message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } /* Calibration and conversions */ vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; mode = (mode == 0) ? RIG_MODE_FM : RIG_MODE_AM; rig_debug(RIG_DEBUG_TRACE, "%s: Buffer (vfo %u, freq %"PRIfreq" Hz, mode %d)\n", __func__, vfo, freq, mode); /* Callback execution */ if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg); } if (rig->callbacks.freq_event) { rig->callbacks.freq_event(rig, vfo, freq, rig->callbacks.freq_arg); } if (rig->callbacks.mode_event) { rig->callbacks.mode_event(rig, vfo, mode, RIG_PASSBAND_NORMAL, rig->callbacks.mode_arg); } } else if (async_len > 2 && asyncbuf[0] == 'S' && asyncbuf[1] == 'M') { vfo_t vfo; int lev; retval = sscanf(asyncbuf, "SM %u,%d", &vfo, &lev); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected SM message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } /* Calibration and conversions */ vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: Signal strength event - signal = %.3f\n", __func__, (float)(lev / 5.0)); /* Callback execution */ #if STILLHAVETOADDCALLBACK if (rig->callbacks.strength_event) rig->callbacks.strength_event(rig, vfo, (float)(lev / 5.0), rig->callbacks.strength_arg); #endif } else if (async_len > 2 && asyncbuf[0] == 'B' && asyncbuf[1] == 'Y') { vfo_t vfo; int busy; retval = sscanf(asyncbuf, "BY %u,%d", &vfo, &busy); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BY message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: Busy event - status = '%s'\n", __func__, (busy == 0) ? "OFF" : "ON"); return -RIG_ENIMPL; /* This event does not have a callback. */ } else if (async_len > 2 && asyncbuf[0] == 'B' && asyncbuf[1] == 'C') { vfo_t vfo; retval = sscanf(asyncbuf, "BC %u", &vfo); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BC message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } vfo = (vfo == 0) ? RIG_VFO_A : RIG_VFO_B; rig_debug(RIG_DEBUG_TRACE, "%s: VFO event - vfo = %u\n", __func__, vfo); if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg); } } else { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf); return -RIG_ENIMPL; } return RIG_OK; } static int kenwood_wrong_vfo(const char *func, vfo_t vfo) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO: %s\n", func, rig_strvfo(vfo)); return -RIG_ENTARGET; } /* * th_set_freq * Assumes rig!=NULL */ int th_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char buf[20]; int step; freq_t freq5, freq625, freq_sent; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } freq5 = round(freq / 5000) * 5000; freq625 = round(freq / 6250) * 6250; if (fabs(freq5 - freq) < fabs(freq625 - freq)) { step = 0; freq_sent = freq5; } else { step = 1; freq_sent = freq625; } /* Step needs to be at least 10kHz on higher band, otherwise 5 kHz */ step = freq_sent >= MHz(470) ? 4 : step; freq_sent = freq_sent >= MHz(470) ? (round(freq_sent / 10000) * 10000) : freq_sent; SNPRINTF(buf, sizeof(buf), "FQ %011"PRIll",%X\r", (int64_t) freq_sent, step); return kenwood_transaction(rig, buf, buf, strlen(buf)); } /* * th_get_freq * Assumes rig!=NULL, freq!=NULL */ int th_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char buf[20]; int retval, step; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } *freq = 0; retval = kenwood_safe_transaction(rig, "FQ", buf, sizeof(buf), 16); if (retval != RIG_OK) { return retval; } retval = num_sscanf(buf, "FQ %"SCNfreq",%x", freq, (unsigned *)&step); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } return RIG_OK; } /* * th_set_mode * Assumes rig!=NULL */ int th_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char kmode, mdbuf[8]; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } if (priv->mode_table) { kmode = rmode2kenwood(mode, priv->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: Unsupported Mode value '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } kmode += '0'; } else { switch (mode) { case RIG_MODE_FM: kmode = '0'; break; /* TH-D7A(G) modes */ case RIG_MODE_AM: kmode = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } } SNPRINTF(mdbuf, sizeof(mdbuf), "MD %c", kmode); return kenwood_transaction(rig, mdbuf, mdbuf, strlen(mdbuf)); } /* * th_get_mode * Assumes rig!=NULL, mode!=NULL */ int th_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[ACKBUF_LEN]; int retval; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } retval = kenwood_safe_transaction(rig, "MD", buf, sizeof(buf), 4); if (retval != RIG_OK) { return retval; } if (buf[3] < '0' || buf[3] > '9') { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } if (priv->mode_table) { *mode = kenwood2rmode(buf[3] - '0', priv->mode_table); if (*mode == RIG_MODE_NONE) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Mode (table)value '%c'\n", __func__, buf[3]); return -RIG_EINVAL; } } else { switch (buf[3]) { case '0': *mode = RIG_MODE_FM; break; /* TH-D7A(G) modes */ case '1': *mode = RIG_MODE_AM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Mode value '%c'\n", __func__, buf[3]); return -RIG_EINVAL; } } if (width) { *width = RIG_PASSBAND_NORMAL; } return RIG_OK; } /* * th_set_vfo * Apply to non-split models: TH-F7, TH-D7 * * Assumes rig!=NULL */ int th_set_vfo(RIG *rig, vfo_t vfo) { int retval; char cmd[8]; char cmdbuf[8]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* from thf7.c * The band must be active before selecting VFO or MEM. * The dilemma is whether MEM should be applied to Band A or Band B. * Remember, not all bands have the same capability * TODO: if (RIG_VFO_MEM) query current band with BC, then do appropriate VMC */ /* set band */ if (vfo != RIG_VFO_MEM) { switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: strncpy(cmd, "BC 0", sizeof(cmd)); break; case RIG_VFO_B: case RIG_VFO_SUB: strncpy(cmd, "BC 1", sizeof(cmd)); break; default: return kenwood_wrong_vfo(__func__, vfo); } return kenwood_transaction(rig, cmd, cmd, strlen(cmd)); } /* No "VMC" cmd on THD72A/THD74 */ if (rig->caps->rig_model == RIG_MODEL_THD72A || rig->caps->rig_model == RIG_MODEL_THD74) { return RIG_OK; } /* set vfo */ switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MAIN: strncpy(cmd, "VMC 0,0", sizeof(cmd)); break; case RIG_VFO_B: case RIG_VFO_SUB: strncpy(cmd, "VMC 1,0", sizeof(cmd)); break; case RIG_VFO_MEM: strncpy(cmd, "BC", sizeof(cmd)); retval = kenwood_transaction(rig, cmd, cmd, 7); if (retval != RIG_OK) { return retval; } if (rig->caps->rig_model == RIG_MODEL_THF7E || rig->caps->rig_model == RIG_MODEL_THF6A) { SNPRINTF(cmd, sizeof(cmd), "VMC %c,1", cmd[3]); } else { SNPRINTF(cmd, sizeof(cmd), "VMC %c,2", cmd[3]); } break; default: return kenwood_wrong_vfo(__func__, vfo); } return kenwood_transaction(rig, cmd, cmdbuf, strlen(cmd)); } int th_get_vfo_char(RIG *rig, vfo_t *vfo, char *vfoch) { char cmdbuf[10], buf[10], vfoc; int retval; size_t length; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_transaction(rig, "BC", buf, 7); if (retval != RIG_OK) { return retval; } length = strlen(buf); switch (length) { case 4: /*original case BC 0*/ vfoc = buf[3]; break; case 6: /*intended for D700 BC 0,0*/ if ((buf[0] == 'B') && (buf[1] == 'C') && (buf[2] == ' ') && (buf[4] == ',')) { vfoc = buf[3]; } else { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer format '%s'\n", __func__, buf); return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected answer length %d\n", __func__, (int)length); return -RIG_EPROTO; break; } switch (vfoc) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, buf[3]); return -RIG_EVFO; } /* No "VMC" on THD72A/THD74 */ if (rig->caps->rig_model == RIG_MODEL_THD72A || rig->caps->rig_model == RIG_MODEL_THD74) { *vfoch = '0'; /* FIXME: fake */ return RIG_OK; } /* Get mode of the VFO band */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "VMC %c", vfoc); retval = kenwood_safe_transaction(rig, cmdbuf, buf, 10, 7); if (retval != RIG_OK) { return retval; } *vfoch = buf[6]; return RIG_OK; } /* * th_get_vfo * Assumes rig!=NULL */ int th_get_vfo(RIG *rig, vfo_t *vfo) { char vfoch; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = th_get_vfo_char(rig, vfo, &vfoch); if (retval != RIG_OK) { return retval; } switch (vfoch) { case '0' : case '1' : break; case '2' : *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, vfoch); return -RIG_EVFO; } return RIG_OK; } /* * tm_set_vfo_bc2 * Apply to split-capable models (with BC command taking 2 args): TM-V7, TM-D700 * * Assumes rig!=NULL */ int tm_set_vfo_bc2(RIG *rig, vfo_t vfo) { struct rig_state *rs = STATE(rig); const struct kenwood_priv_data *priv = rs->priv; char cmd[16]; int vfonum, txvfonum, vfomode = 0; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: vfonum = 0; /* put back split mode when toggling */ txvfonum = (priv->split == RIG_SPLIT_ON && rs->tx_vfo == RIG_VFO_B) ? 1 : vfonum; break; case RIG_VFO_B: vfonum = 1; /* put back split mode when toggling */ txvfonum = (priv->split == RIG_SPLIT_ON && rs->tx_vfo == RIG_VFO_A) ? 0 : vfonum; break; case RIG_VFO_MEM: /* get current band */ SNPRINTF(cmd, sizeof(cmd), "BC"); retval = kenwood_transaction(rig, cmd, cmd, 7); if (retval != RIG_OK) { return retval; } txvfonum = vfonum = cmd[3] - '0'; vfomode = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %u\n", __func__, vfo); return -RIG_EVFO; } SNPRINTF(cmd, sizeof(cmd), "VMC %d,%d", vfonum, vfomode); retval = kenwood_transaction(rig, cmd, cmd, 8); if (retval != RIG_OK) { return retval; } if (vfo == RIG_VFO_MEM) { return RIG_OK; } SNPRINTF(cmd, sizeof(cmd), "BC %d,%d", vfonum, txvfonum); return kenwood_transaction(rig, cmd, cmd, 7); } int th_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char vfobuf[16]; int vfonum, txvfonum; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strvfo(vfo)); if (vfo == RIG_VFO_CURR) { retval = rig_get_vfo(rig, &vfo); if (retval != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: vfonum = 0; if (split == RIG_SPLIT_ON && txvfo != RIG_VFO_B) { return -RIG_EINVAL; } txvfonum = split == RIG_SPLIT_ON ? 1 : vfonum; break; case RIG_VFO_B: vfonum = 1; if (split == RIG_SPLIT_ON && txvfo != RIG_VFO_A) { return -RIG_EINVAL; } txvfonum = split == RIG_SPLIT_ON ? 0 : vfonum; break; default: return -RIG_EINVAL; } /* Set VFO mode. To be done for TX vfo also? */ SNPRINTF(vfobuf, sizeof(vfobuf), "VMC %d,0", vfonum); retval = kenwood_transaction(rig, vfobuf, vfobuf, strlen(vfobuf)); if (retval != RIG_OK) { return retval; } SNPRINTF(vfobuf, sizeof(vfobuf), "BC %d,%d", vfonum, txvfonum); retval = kenwood_transaction(rig, vfobuf, vfobuf, 7); if (retval != RIG_OK) { return retval; } /* Remember whether split is on, for th_set_vfo */ priv->split = split; return RIG_OK; } int th_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char buf[10]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* Get VFO band */ retval = kenwood_safe_transaction(rig, "BC", buf, 10, 6); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0': *txvfo = RIG_VFO_A; break; case '1': *txvfo = RIG_VFO_B; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected txVFO value '%c'\n", __func__, buf[5]); return -RIG_EPROTO; } *split = (buf[3] == buf[5]) ? RIG_SPLIT_OFF : RIG_SPLIT_ON; /* Remember whether split is on, for th_set_vfo */ priv->split = *split; return RIG_OK; } /* * th_set_trn * Assumes rig!=NULL */ int th_set_trn(RIG *rig, int trn) { char buf[5]; SNPRINTF(buf, sizeof(buf), "AI %c", RIG_TRN_RIG == trn ? '1' : '0'); return kenwood_transaction(rig, buf, buf, strlen(buf)); } /* * th_get_trn * Assumes rig!=NULL */ int th_get_trn(RIG *rig, int *trn) { char buf[ACKBUF_LEN]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "AI", buf, 5); if (retval != RIG_OK) { return retval; } if (strlen(buf) != 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_ERJCTED; } *trn = (buf[2] != '0') ? RIG_TRN_RIG : RIG_TRN_OFF; return RIG_OK; } /* * th_get_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int th_get_kenwood_func(RIG *rig, const char *cmd, int *status) { char buf[8]; int retval, len, expected; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); len = strlen(cmd); expected = len + 2; retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), expected); if (retval != RIG_OK) { return retval; } if (status) { *status = (buf[len + 1] == '0') ? 0 : 1; } return RIG_OK; }; /* * th_get_func * Assumes rig!=NULL, status!=NULL * * Assumes vfo == RIG_VFO_CURR, any other value is handled by the frontend. */ int th_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strfunc(func)); switch (func) { case RIG_FUNC_MUTE: return th_get_kenwood_func(rig, "MUTE", status); case RIG_FUNC_MON: return th_get_kenwood_func(rig, "MON", status); case RIG_FUNC_TONE: return th_get_kenwood_func(rig, "TO", status); case RIG_FUNC_TSQL: return th_get_kenwood_func(rig, "CT", status); case RIG_FUNC_REV: return th_get_kenwood_func(rig, "REV", status); case RIG_FUNC_ARO: return th_get_kenwood_func(rig, "ARO", status); case RIG_FUNC_AIP: return th_get_kenwood_func(rig, "AIP", status); case RIG_FUNC_LOCK: return th_get_kenwood_func(rig, "LK", status); case RIG_FUNC_BC: return th_get_kenwood_func(rig, "BC", status); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } } static int th_tburst(RIG *rig, vfo_t vfo, int status) { return kenwood_transaction(rig, (status == 1) ? "TT" : "RX", NULL, 0); } /* * th_set_kenwood_func * Assumes rig!=NULL, status!=NULL */ static int th_set_kenwood_func(RIG *rig, const char *cmd, int status) { #define BUFSZ 16 char buf[BUFSZ]; rig_debug(RIG_DEBUG_TRACE, "%s: cmd = %s, status = %d\n", __func__, cmd, status); strncpy(buf, cmd, BUFSZ - 2); buf[BUFSZ - 1] = '\0'; strncat(buf, status ? " 1" : " 0", BUFSZ - 1); return kenwood_transaction(rig, buf, NULL, 0); } /* * th_get_func * Assumes rig!=NULL, status!=NULL * * Assumes vfo == RIG_VFO_CURR, any other value is handled by the frontend. */ int th_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strfunc(func)); switch (func) { case RIG_FUNC_MUTE: return th_set_kenwood_func(rig, "MUTE", status); case RIG_FUNC_MON: return th_set_kenwood_func(rig, "MON", status); case RIG_FUNC_TONE: return th_set_kenwood_func(rig, "TO", status); case RIG_FUNC_TSQL: return th_set_kenwood_func(rig, "CT", status); case RIG_FUNC_REV: return th_set_kenwood_func(rig, "REV", status); case RIG_FUNC_ARO: return th_set_kenwood_func(rig, "ARO", status); case RIG_FUNC_AIP: return th_set_kenwood_func(rig, "AIP", status); case RIG_FUNC_LOCK: return th_set_kenwood_func(rig, "LK", status); case RIG_FUNC_BC: return th_set_kenwood_func(rig, "NSFT", status); case RIG_FUNC_TBURST: return th_tburst(rig, vfo, status); default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported function %s\n", __func__, rig_strfunc(func)); return -RIG_EINVAL; } return RIG_OK; } int th_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { rig_debug(RIG_DEBUG_TRACE, "%s: called (0x%04x)\n", __func__, scan); return th_set_kenwood_func(rig, "SC", scan == RIG_SCAN_STOP ? 0 : 1); } /* * th_get_parm * Assumes rig!=NULL, status!=NULL */ int th_get_parm(RIG *rig, setting_t parm, value_t *val) { char buf[16]; int ret, status; rig_debug(RIG_DEBUG_TRACE, "%s: called %s\n", __func__, rig_strparm(parm)); switch (parm) { case RIG_PARM_BEEP: ret = th_get_kenwood_func(rig, "BEP", &status); if (ret != RIG_OK) { return ret; } val->i = status ? 1 : 0; return RIG_OK; case RIG_PARM_APO: ret = kenwood_safe_transaction(rig, "APO", buf, sizeof(buf), 5); if (ret != RIG_OK) { return ret; } val->i = (buf[4] - '0') * 30; return RIG_OK; case RIG_PARM_BACKLIGHT: if (rig->caps->rig_model == RIG_MODEL_TMD700) { ret = kenwood_safe_transaction(rig, "DIM", buf, sizeof(buf), 4); if (ret != RIG_OK) { return ret; } val->f = buf[4] == '0' ? 0 : (float)(5 - (buf[4] - '0')) / 4.; } else { ret = th_get_kenwood_func(rig, "LMP", &status); if (ret != RIG_OK) { return ret; } val->f = status ? 1.0 : 0; } return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } int th_set_parm(RIG *rig, setting_t parm, value_t val) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (parm) { case RIG_PARM_BACKLIGHT: if (rig->caps->rig_model == RIG_MODEL_TMD700) { return th_set_kenwood_func(rig, "DIM", (val.f > 0) ? 1 : 0); /* FIXME */ } else { return th_set_kenwood_func(rig, "LMP", (val.f > 0) ? 1 : 0); } case RIG_PARM_BEEP: return th_set_kenwood_func(rig, "BEP", val.i); case RIG_PARM_APO: if (val.i > 30) { return kenwood_transaction(rig, "APO 2", NULL, 0); } else if (val.i > 0) { return kenwood_transaction(rig, "APO 1", NULL, 0); } else { return kenwood_transaction(rig, "APO 0", NULL, 0); } default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * th_get_level * Assumes rig!=NULL, val!=NULL */ int th_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char vch, buf[10], ackbuf[20]; int retval, v; unsigned int l; struct rig_state *rs = STATE(rig); vfo_t tvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tvfo = (vfo == RIG_VFO_CURR) ? rs->current_vfo : vfo; switch (tvfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: vch = '0'; break; case RIG_VFO_B: vch = '1'; break; default: return kenwood_wrong_vfo(__func__, vfo); } switch (level) { case RIG_LEVEL_RAWSTR: SNPRINTF(buf, sizeof(buf), "SM %c", vch); // XXX use kenwood_safe_transaction retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "SM %d,%u", &v, &l); if (retval != 2 || l < rig->caps->level_gran[LVL_RAWSTR].min.i || l > rig->caps->level_gran[LVL_RAWSTR].max.i) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } val->i = l; break; case RIG_LEVEL_SQL: SNPRINTF(buf, sizeof(buf), "SQ %c", vch); retval = kenwood_safe_transaction(rig, buf, ackbuf, 10, 7); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "SQ %d,%x", &v, &l); if (retval != 2 || l < rig->caps->level_gran[LVL_SQL].min.i || l > rig->caps->level_gran[LVL_SQL].max.i) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - rig->caps->level_gran[LVL_SQL].min.i) / (float)(rig->caps->level_gran[LVL_SQL].max.i - rig->caps->level_gran[LVL_SQL].min.i); break; case RIG_LEVEL_AF: SNPRINTF(buf, sizeof(buf), "AG %c", vch); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "AG %d,%x", &v, &l); if (retval != 2 || l < rig->caps->level_gran[LVL_AF].min.i || l > rig->caps->level_gran[LVL_AF].max.i) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - rig->caps->level_gran[LVL_AF].min.i) / (float)(rig->caps->level_gran[LVL_AF].max.i - rig->caps->level_gran[LVL_AF].min.i); break; case RIG_LEVEL_RFPOWER: SNPRINTF(buf, sizeof(buf), "PC %c", vch); retval = kenwood_transaction(rig, buf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } retval = sscanf(ackbuf, "PC %d,%u", &v, &l); if ((retval != 2) || l > 3) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, ackbuf); return -RIG_ERJCTED; } /* range [0.0 ... 1.0] */ val->f = (float)(l - rig->caps->level_gran[LVL_RFPOWER].min.i) / (float)(rig->caps->level_gran[LVL_RFPOWER].max.i - rig->caps->level_gran[LVL_RFPOWER].min.i); break; case RIG_LEVEL_BALANCE: retval = kenwood_safe_transaction(rig, "BAL", ackbuf, 10, 5); if (retval != RIG_OK) { return retval; } if (ackbuf[4] < '0' || ackbuf[4] > '8') { return -RIG_EPROTO; } val->f = (float)('4' - ackbuf[4]) / ('4' - '0'); break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "ATT", ackbuf, 10, 5); if (retval != RIG_OK) { return retval; } if (ackbuf[4] < '0' || ackbuf[4] > '8') { return -RIG_EPROTO; } if (ackbuf[4] == '0') { val->i = 0; } else { val->i = rs->attenuator[ackbuf[4] - '1']; } break; case RIG_LEVEL_VOXGAIN: retval = kenwood_safe_transaction(rig, "VXG", ackbuf, 10, 5); if (retval != RIG_OK) { return retval; } if (ackbuf[4] < '0' || ackbuf[4] > '9') { return -RIG_EPROTO; } val->f = (ackbuf[4] == '0') / 9; break; case RIG_LEVEL_VOXDELAY: /* "VXD" */ return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } int th_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char vch, buf[12]; vfo_t tvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tvfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (tvfo) { case RIG_VFO_A: case RIG_VFO_VFO: case RIG_VFO_MEM: vch = '0'; break; case RIG_VFO_B: vch = '1'; break; default: return kenwood_wrong_vfo(__func__, vfo); } switch (level) { case RIG_LEVEL_RFPOWER : SNPRINTF(buf, sizeof(buf), "PC %c,%01d", vch, (int)(val.f * (rig->caps->level_gran[LVL_RFPOWER].max.i - rig->caps->level_gran[LVL_RFPOWER].min.i)) + rig->caps->level_gran[LVL_RFPOWER].min.i); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_SQL : SNPRINTF(buf, sizeof(buf), "SQ %c,%02x", vch, (int)(val.f * (rig->caps->level_gran[LVL_SQL].max.i - rig->caps->level_gran[LVL_SQL].min.i)) + rig->caps->level_gran[LVL_SQL].min.i); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_AF : SNPRINTF(buf, sizeof(buf), "AG %c,%02x", vch, (int)(val.f * 32.0)); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_ATT : SNPRINTF(buf, sizeof(buf), "ATT %c", val.i ? '1' : '0'); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_BALANCE : SNPRINTF(buf, sizeof(buf), "BAL %c", '4' - (int)(val.f * ('4' - '0'))); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_VOXGAIN: SNPRINTF(buf, sizeof(buf), "VXG %d", (int)(val.f * 9)); return kenwood_transaction(rig, buf, NULL, 0); case RIG_LEVEL_VOXDELAY: /* "VXD" */ return -RIG_ENIMPL; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported level %s\n", __func__, rig_strlevel(level)); return -RIG_EINVAL; } } #ifndef RIG_TONEMAX #define RIG_TONEMAX 38 #endif /* * th_set_ctcss_tone * Assumes rig!=NULL, rig->caps->ctcss_list != NULL */ int th_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } i += (i == 0) ? 1 : 2; /* Correct for TH-D7A index anomaly */ SNPRINTF(tonebuf, sizeof(tonebuf), "TN %02d", i); return kenwood_transaction(rig, tonebuf, tonebuf, sizeof(tonebuf)); } /* * th_get_ctcss_tone * Assumes rig!=NULL, rig->caps!=NULL */ int th_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char buf[ACKBUF_LEN]; int retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; retval = kenwood_transaction(rig, "TN", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "TN %d", (int *)&tone_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } /* verify tone index for TH-7DA rig */ if (tone_idx == 0 || tone_idx == 2 || tone_idx > 39) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected CTCSS tone no (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } tone_idx -= (tone_idx == 1) ? 1 : 2; /* Correct for TH-D7A index anomaly */ *tone = caps->ctcss_list[tone_idx]; return RIG_OK; } /* * th_set_ctcss_sql * Assumes rig!=NULL, rig->caps->ctcss_list != NULL */ int th_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } i += (i == 0) ? 1 : 2; /* Correct for TH-D7A index anomaly */ SNPRINTF(tonebuf, sizeof(tonebuf), "CTN %02d", i); return kenwood_transaction(rig, tonebuf, tonebuf, sizeof(tonebuf)); } /* * thd7_get_ctcss_sql * Assumes rig!=NULL, rig->caps!=NULL */ int th_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char buf[ACKBUF_LEN]; int retval; unsigned int tone_idx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; retval = kenwood_transaction(rig, "CTN", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "CTN %d", (int *)&tone_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } /* verify tone index for TH-7DA rig */ if (tone_idx == 0 || tone_idx == 2 || tone_idx > 39) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected CTCSS no (%04u)\n", __func__, tone_idx); return -RIG_EPROTO; } tone_idx -= (tone_idx == 1) ? 1 : 2; /* Correct for TH-7DA index anomaly */ *tone = caps->ctcss_list[tone_idx]; return RIG_OK; } #ifndef RIG_CODEMAX #define RIG_CODEMAX 104 #endif /* * th_set_dcs_sql * Assumes rig!=NULL, rig->caps->dcs_list != NULL */ int th_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code) { struct rig_caps *caps; char codebuf[16]; int i, retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; if (code == 0) { SNPRINTF(codebuf, sizeof(codebuf), "DCS 0"); return kenwood_transaction(rig, codebuf, codebuf, sizeof(codebuf)); } for (i = 0; caps->dcs_list[i] != 0; i++) { if (caps->dcs_list[i] == code) { break; } } if (caps->dcs_list[i] != code) { return -RIG_EINVAL; } SNPRINTF(codebuf, sizeof(codebuf), "DCS 1"); if ((retval = kenwood_transaction(rig, codebuf, codebuf, sizeof(codebuf))) != RIG_OK) { return retval; } SNPRINTF(codebuf, sizeof(codebuf), "DCSN %04d", (i + 1) * 10); return kenwood_transaction(rig, codebuf, codebuf, sizeof(codebuf)); } /* * th_get_dcs_sql * Assumes rig!=NULL, rig->caps!=NULL */ int th_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code) { struct rig_caps *caps; char buf[ACKBUF_LEN]; int retval; unsigned int code_idx; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); caps = rig->caps; retval = kenwood_transaction(rig, "DCS", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "DCSN %d", (int *)&code_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } if (code_idx == 0) { *code = 0; /* disabled */ return RIG_OK; } retval = kenwood_transaction(rig, "DCSN", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } retval = sscanf(buf, "DCSN %d", (int *)&code_idx); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected reply '%s'\n", __func__, buf); return -RIG_EPROTO; } /* verify code index for TM-D700 rig */ if (code_idx <= 10 || code_idx > 1040) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected DCS no (%04u)\n", __func__, code_idx); return -RIG_EPROTO; } code_idx = (code_idx / 10) - 1; *code = caps->dcs_list[code_idx]; return RIG_OK; } const char * th_get_info(RIG *rig) { static char firmbuf[50]; int retval; size_t firm_len; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, "ID", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } firm_len = strlen(firmbuf); if (firm_len < 3) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s', len=%d\n", __func__, firmbuf, (int)firm_len); return NULL; } return &firmbuf[2]; } /* * th_set_mem * Assumes rig!=NULL */ int th_set_mem(RIG *rig, vfo_t vfo, int ch) { unsigned char vsel; char membuf[10]; int retval; vfo_t tvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); tvfo = (vfo == RIG_VFO_CURR) ? STATE(rig)->current_vfo : vfo; switch (tvfo) { case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_A: vsel = '0'; break; case RIG_VFO_B: vsel = '1'; break; default: return kenwood_wrong_vfo(__func__, vfo); } if ((retval = rig_set_vfo(rig, RIG_VFO_MEM)) != RIG_OK) { return retval; } SNPRINTF(membuf, sizeof(membuf), "MC %c,%03i", vsel, ch); return kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); } /* Get mem works only when the display is * in memory mode */ int th_get_mem(RIG *rig, vfo_t vfo, int *ch) { char *membuf, buf[10]; int retval; vfo_t tvfo, cvfo; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); /* store current VFO */ cvfo = STATE(rig)->current_vfo; /* check if we should switch VFO */ if (cvfo != RIG_VFO_MEM) { retval = rig_set_vfo(rig, RIG_VFO_MEM); if (retval != RIG_OK) { return retval; } } tvfo = (vfo == RIG_VFO_CURR) ? cvfo : vfo; switch (tvfo) { case RIG_VFO_VFO: case RIG_VFO_MEM: case RIG_VFO_A: membuf = "MC 0"; break; case RIG_VFO_B: membuf = "MC 1"; break; default: return kenwood_wrong_vfo(__func__, vfo); } retval = kenwood_safe_transaction(rig, membuf, buf, 10, 8); if (retval != RIG_OK) { return retval; } *ch = atoi(&buf[5]); /* switch back if appropriate */ if (cvfo != RIG_VFO_MEM) { retval = rig_set_vfo(rig, cvfo); if (retval != RIG_OK) { return retval; } } return RIG_OK; } int th_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char buf[3]; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); return kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", buf, sizeof(buf)); } int th_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char *cmd, buf[8]; int retval; if (vfo == RIG_VFO_CURR) { retval = th_get_vfo(rig, &vfo); if (retval != RIG_OK) { return retval; } } switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: case RIG_VFO_MAIN: cmd = "BY 0"; break; case RIG_VFO_B: case RIG_VFO_SUB: cmd = "BY 1"; break; default: return kenwood_wrong_vfo(__func__, vfo); } retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), 6); if (retval != RIG_OK) { return retval; } switch (buf[5]) { case '0' : *dcd = RIG_DCD_OFF; return RIG_OK; case '1' : *dcd = RIG_DCD_ON; return RIG_OK; default : rig_debug(RIG_DEBUG_ERR, "%s: unexpected reply '%s'\n", __func__, buf); } return -RIG_ERJCTED; } int th_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); if (vfo != RIG_VFO_CURR && vfo != STATE(rig)->current_vfo) { return kenwood_wrong_vfo(__func__, vfo); } switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", NULL, 0); case RIG_OP_TO_VFO: return kenwood_transaction(rig, "MSH", NULL, 0); default: return -RIG_EINVAL; } } /* get and set channel tested on thg71&thf7e */ /* must work on other th and tm kenwood rigs */ /* --------------------------------------------------------------------- */ int th_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { char membuf[64], ackbuf[ACKBUF_LEN]; int retval; freq_t freq, offset; char req[32], scf[128]; int step, shift, rev, tone, ctcss, tonefq, ctcssfq, dcs, dcscode, mode, lockout; const char *mr_extra; int channel_num; vfo_t vfotmp; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; const chan_t *chan_caps; if (chan->vfo == RIG_VFO_MEM) { chan_caps = rig_lookup_mem_caps(rig, chan->channel_num); if (!chan_caps) { return -RIG_ECONF; } } else { /* TODO: stuff channel_num (out of current freq) and chan_caps */ return -RIG_ENIMPL; } channel_num = chan->channel_num; vfotmp = chan->vfo; memset(chan, 0, sizeof(channel_t)); chan->channel_num = channel_num; chan->vfo = vfotmp; if (rig->caps->rig_model == RIG_MODEL_THF7E || rig->caps->rig_model == RIG_MODEL_THF6A) { mr_extra = ""; } else { mr_extra = "0, "; } channel_num -= chan_caps->startc; switch (chan_caps->type) { case RIG_MTYPE_MEM: if (chan_caps[1].type == RIG_MTYPE_PRIO) { /* Info */ SNPRINTF(req, sizeof(req), "MR %s0,I-%01d", mr_extra, channel_num); } else { SNPRINTF(req, sizeof(req), "MR %s0,%03d", mr_extra, channel_num); } break; case RIG_MTYPE_EDGE: if (chan_caps[1].type == RIG_MTYPE_EDGE) { SNPRINTF(req, sizeof(req), "MR %s0,L%01d", mr_extra, channel_num); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "L%01d", channel_num); } else { SNPRINTF(req, sizeof(req), "MR %s0,U%01d", mr_extra, channel_num); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "U%01d", channel_num); } break; case RIG_MTYPE_PRIO: if (chan_caps->startc == chan_caps->endc) { SNPRINTF(req, sizeof(req), "MR %s0,PR", mr_extra); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Pr"); } else { SNPRINTF(req, sizeof(req), "MR %s0,PR%01d", mr_extra, channel_num + 1); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Pr%01d", channel_num + 1); } break; case RIG_MTYPE_CALL: SNPRINTF(req, sizeof(req), "CR 0,%01d", channel_num); if (chan->channel_num == chan_caps->startc) { SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call V"); } else if (chan->channel_num == chan_caps->endc) { SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call U"); } else { SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "Call"); } break; case RIG_MTYPE_BAND: SNPRINTF(req, sizeof(req), "VR %01X", channel_num); SNPRINTF(chan->channel_desc, sizeof(chan->channel_desc), "BAND %01X", channel_num); break; default: return -RIG_EINVAL; } SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } /* * TODO: dcs/mode/lockout are not there on TH-G71 */ mode = RIG_MODE_NONE; rev = lockout = dcs = dcscode = 0; strcpy(scf, req); if (chan_caps->mem_caps.dcs_sql) { /* Step can be hexa * Lockout is optional on some channels */ strcat(scf, ",%"SCNfreq",%x,%d,%d,%d,%d,%d,%d,%d,%d,%"SCNfreq",%d,%d"); retval = num_sscanf(ackbuf, scf, &freq, &step, &shift, &rev, &tone, &ctcss, &dcs, &tonefq, &ctcssfq, &dcscode, &offset, &mode, &lockout); if (retval < 12) { rig_debug(RIG_DEBUG_WARN, "%s: sscanf failed %d\n", __func__, retval); return -RIG_EPROTO; } } else { strcat(scf, ",%"SCNfreq",%x,%d,%d,%d,%d,,%d,,%d,%"SCNfreq); retval = num_sscanf(ackbuf, scf, &freq, &step, &shift, &rev, &tone, &ctcss, &tonefq, &ctcssfq, &offset); if (retval != 9) { rig_debug(RIG_DEBUG_WARN, "%s: sscanf failed %d\n", __func__, retval); } } chan->funcs = rev ? RIG_FUNC_REV : 0; chan->flags = lockout ? RIG_CHFLAG_SKIP : 0; chan->freq = freq; chan->vfo = RIG_VFO_MEM; chan->tuning_step = STATE(rig)->tuning_steps[step].ts; if (priv->mode_table) { chan->mode = kenwood2rmode(mode, priv->mode_table); if (chan->mode == RIG_MODE_NONE) { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported Mode value '%d'\n", __func__, mode); return -RIG_EPROTO; } } else { /* No mode info (TH-G71, TMV7,..), * guess it from current freq */ chan->mode = (freq < MHz(136)) ? RIG_MODE_AM : RIG_MODE_FM; } chan->width = rig_passband_normal(rig, chan->mode); switch (shift) { case 0 : chan->rptr_shift = RIG_RPT_SHIFT_NONE; break; case 1 : chan->rptr_shift = RIG_RPT_SHIFT_PLUS; break; case 2 : chan->rptr_shift = RIG_RPT_SHIFT_MINUS; offset = -offset; break; default: rig_debug(RIG_DEBUG_ERR, "%s: not supported shift %d\n", __func__, shift); chan->rptr_shift = RIG_RPT_SHIFT_NONE; } chan->rptr_offs = offset; /* FIXME: ctcss_list for t[fm]*.c */ //chan->ctcss_tone=rig->caps->ctcss_list[tonefq==1?0:tonefq-2]; // chan->ctcss_sql=rig->caps->ctcss_list[ctcssfq==1?0:ctcssfq-2]; if (tone) { chan->ctcss_tone = rig->caps->ctcss_list[tonefq]; } else { chan->ctcss_tone = 0; } if (ctcss) { chan->ctcss_sql = rig->caps->ctcss_list[ctcssfq]; } else { chan->ctcss_sql = 0; } if (dcs) { chan->dcs_sql = chan->dcs_code = rig->caps->dcs_list[dcscode]; } else { chan->dcs_sql = chan->dcs_code = 0; } chan->tx_freq = RIG_FREQ_NONE; if (shift == RIG_RPT_SHIFT_NONE && ((chan_caps->type == RIG_MTYPE_MEM && chan_caps->startc == 0) || chan_caps->type == RIG_MTYPE_CALL)) { /* split ? */ req[3 + strlen(mr_extra)] = '1'; SNPRINTF(membuf, sizeof(membuf), "%s", req); retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval == RIG_OK) { strcpy(scf, req); strcat(scf, ",%"SCNfreq",%x"); retval = num_sscanf(ackbuf, scf, &freq, &step); chan->tx_freq = freq; chan->split = RIG_SPLIT_ON; } } /* If not set already by special channels.. */ if (chan->channel_desc[0] == '\0') { size_t ack_len; if (chan_caps[1].type == RIG_MTYPE_PRIO) { SNPRINTF(membuf, sizeof(membuf), "MNA %sI-%01d", mr_extra, channel_num); } else { SNPRINTF(membuf, sizeof(membuf), "MNA %s%03d", mr_extra, channel_num); } /* Get memory name */ retval = kenwood_transaction(rig, membuf, ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } ack_len = strlen(ackbuf); if (ack_len > rig->caps->chan_desc_sz) { ack_len = rig->caps->chan_desc_sz; } strncpy(chan->channel_desc, ackbuf + strlen(membuf) + 1, ack_len); chan->channel_desc[ack_len] = '\0'; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } static int find_tone_index(const tone_t *tone_list, tone_t tone) { int i; for (i = 0; tone_list[i] != 0; i++) { if (tone_list[i] == tone) { return i; } } return -1; } /* --------------------------------------------------------------------- */ int th_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char membuf[256]; int retval; char req[64]; char lockoutstr[8]; int channel_num, step, shift, rev, tone, ctcss, tonefq, ctcssfq, dcs, dcscode, lockout; const char *mr_extra; const struct kenwood_priv_caps *priv = (const struct kenwood_priv_caps *) rig->caps->priv; const chan_t *chan_caps; const char *channel_desc; channel_num = chan->channel_num; for (step = 0; STATE(rig)->tuning_steps[step].ts != 0; step++) if (chan->tuning_step <= STATE(rig)->tuning_steps[step].ts) { break; } switch (chan->rptr_shift) { case RIG_RPT_SHIFT_NONE : shift = 0; break; case RIG_RPT_SHIFT_PLUS: shift = 1; break; case RIG_RPT_SHIFT_MINUS: shift = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: not supported shift %d\n", __func__, chan->rptr_shift); return -RIG_EINVAL; } if (chan->ctcss_tone == 0) { tone = 0; tonefq = 8; } else { tone = 1; tonefq = find_tone_index(rig->caps->ctcss_list, chan->ctcss_tone); if (tonefq == -1) { return -RIG_EINVAL; } tonefq++; } if (chan->ctcss_sql == 0) { ctcss = 0; ctcssfq = 8; } else { ctcss = 1; ctcssfq = find_tone_index(rig->caps->ctcss_list, chan->ctcss_sql); if (tonefq == -1) { return -RIG_EINVAL; } ctcssfq++; } if (chan->dcs_code == 0 && chan->dcs_sql == 0) { dcs = 0; dcscode = 0; } else { dcs = 1; dcscode = find_tone_index(rig->caps->dcs_list, chan->dcs_sql); if (dcscode == -1) { return -RIG_EINVAL; } } if (chan->vfo == RIG_VFO_MEM) { chan_caps = rig_lookup_mem_caps(rig, chan->channel_num); if (!chan_caps) { return -RIG_ECONF; } channel_num -= chan_caps->startc; } else { return -RIG_ENIMPL; } if (rig->caps->rig_model == RIG_MODEL_THF7E || rig->caps->rig_model == RIG_MODEL_THF6A) { mr_extra = ""; } else { mr_extra = "0, "; } channel_desc = NULL; switch (chan_caps->type) { case RIG_MTYPE_MEM: if (chan_caps[1].type == RIG_MTYPE_PRIO) { /* Info */ SNPRINTF(req, sizeof(req), "MW %s0,I-%01d", mr_extra, channel_num); channel_desc = chan->channel_desc; } else { /* Regular */ SNPRINTF(req, sizeof(req), "MW %s0,%03d", mr_extra, channel_num); channel_desc = chan->channel_desc; } break; case RIG_MTYPE_EDGE: if (chan_caps[1].type == RIG_MTYPE_EDGE) { SNPRINTF(req, sizeof(req), "MW %s0,L%01d", mr_extra, channel_num); } else { SNPRINTF(req, sizeof(req), "MW %s0,U%01d", mr_extra, channel_num); } break; case RIG_MTYPE_PRIO: if (chan_caps->startc == chan_caps->endc) { SNPRINTF(req, sizeof(req), "MW %s0,PR", mr_extra); } else { SNPRINTF(req, sizeof(req), "MW %s0,PR%01d", mr_extra, channel_num + 1); } break; case RIG_MTYPE_CALL: SNPRINTF(req, sizeof(req), "CW 0,%01d", channel_num); break; case RIG_MTYPE_BAND: SNPRINTF(req, sizeof(req), "VW %01X", channel_num); break; default: return -RIG_EINVAL; } rev = (chan->funcs & RIG_FUNC_REV) ? 1 : 0; lockout = (chan->flags & RIG_CHFLAG_SKIP) ? 1 : 0; if (chan_caps->mem_caps.flags) { SNPRINTF(lockoutstr, sizeof(lockoutstr), ",%d", lockout); } else { strcpy(lockoutstr, ""); } if (chan_caps->mem_caps.flags && chan_caps->mem_caps.dcs_sql) { int mode; if (!priv->mode_table) { rig_debug(RIG_DEBUG_ERR, "%s: buggy backend, no mode_table '%d'\n", __func__, (int)chan->mode); return -RIG_ENIMPL; } mode = rmode2kenwood(chan->mode, priv->mode_table); if (mode == -1) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode value '%d'\n", __func__, (int)chan->mode); return -RIG_EINVAL; } /* Step can be hexa */ SNPRINTF(membuf, sizeof(membuf), "%8s,%011"PRIll",%X,%d,%d,%d,%d,%d,%02d,%02d,%03d,%09"PRIll",%d%10s", req, (int64_t)chan->freq, step, shift, rev, tone, ctcss, dcs, tonefq, ctcssfq, dcscode, (int64_t)labs((long)(chan->rptr_offs)), mode, lockoutstr ); } else { /* Without DCS,mode */ SNPRINTF(membuf, sizeof(membuf), "%s,%011"PRIll",%X,%d,%d,%d,%d,,%02d,,%02d,%09"PRIll"%s", req, (int64_t)chan->freq, step, shift, rev, tone, ctcss, tonefq, ctcssfq, (int64_t)labs((long)(chan->rptr_offs)), lockoutstr ); } retval = kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); if (retval != RIG_OK) { return retval; } /* split ? */ if (chan->tx_freq != RIG_FREQ_NONE && ((chan_caps->type == RIG_MTYPE_MEM && chan_caps->startc == 0) || chan_caps->type == RIG_MTYPE_CALL)) { req[3 + strlen(mr_extra)] = '1'; SNPRINTF(membuf, sizeof(membuf), "%s,%011"PRIll",%X", req, (int64_t)chan->tx_freq, step); retval = kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); if (retval != RIG_OK) { return retval; } } if (channel_desc) { /* Memory name */ /* TODO: check strlen(channel_desc) < rig->caps->chan_desc_sz */ if (chan_caps[1].type == RIG_MTYPE_PRIO) { SNPRINTF(membuf, sizeof(membuf), "MNA %sI-%01d,%s", mr_extra, channel_num, channel_desc); } else { SNPRINTF(membuf, sizeof(membuf), "MNA %s%03d,%s", mr_extra, channel_num, channel_desc); } retval = kenwood_transaction(rig, membuf, membuf, sizeof(membuf)); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * set the aerial/antenna to use */ int th_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char cmd[6]; rig_debug(RIG_DEBUG_TRACE, "%s: ant = %u\n", __func__, ant); switch (ant) { case RIG_ANT_1: strncpy(cmd, "ANT 0", sizeof(cmd)); break; case RIG_ANT_2: strncpy(cmd, "ANT 1", sizeof(cmd)); break; case RIG_ANT_3: strncpy(cmd, "ANT 2", sizeof(cmd)); break; default: return -RIG_EINVAL; } return kenwood_transaction(rig, cmd, cmd, sizeof(cmd)); } /* * get the aerial/antenna in use */ int th_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char buf[8]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s\n", __func__); retval = kenwood_safe_transaction(rig, "ANT", buf, sizeof(buf), 5); if (retval != RIG_OK) { return retval; } if (buf[4] < '0' || buf[4] > '9') { return -RIG_EPROTO; } *ant_curr = RIG_ANT_N(buf[4] - '0'); rig_debug(RIG_DEBUG_TRACE, "%s: ant = %u\n", __func__, *ant_curr); return RIG_OK; } /* TH-F7: 1 VFO, 2 Menu, 3 Full */ /* TM-D700: 1 Master! */ int th_reset(RIG *rig, reset_t reset) { switch (reset) { case RIG_RESET_VFO: return kenwood_transaction(rig, "SR 1", NULL, 0); case RIG_RESET_MASTER: return kenwood_transaction(rig, "SR 3", NULL, 0); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); return -RIG_EINVAL; } } hamlib-4.6.2/rigs/kenwood/level_gran_elecraft.h0000644000175000017500000000542314752216205016456 00000000000000 // Once included these values can be overridden in the back-end // Known variants are PREAMP, ATT, NB, CWPITCH, IF, NOTCHF, VOXDELAY, BKINDL, BKIN_DLYMS, RFPOWER_METER(255 or 100), RFPOWER_METER_WATTS(255 or 100) // cppcheck-suppress * /* raw data */ [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, /* levels with dB units */ #if !defined(NO_LVL_PREAMP) [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 10 } }, #endif #if !defined(NO_LVL_ATT) [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 10 }, .step = { .i = 10 } }, #endif [LVL_STRENGTH] = { .min = { .i = 0 }, .max = { .i = 60 }, .step = { .i = 0 } }, [LVL_NB] = { .min = { .f = 0 }, .max = { .f = 10 }, .step = { .f = 1 } }, /* levels with WPM units */ [LVL_KEYSPD] = { .min = { .i = 8 }, .max = { .i = 50 }, .step = { .i = 1 } }, /* levels with Hz units */ #if !defined(NO_LVL_CWPITCH) [LVL_CWPITCH] = { .min = { .i = 300 }, .max = { .i = 800 }, .step = { .i = 10 } }, #endif /* levels with time units */ #if !defined(NO_LVL_CWPITCH) [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = { .i = 50 } }, #endif /* levels with 0-1 values -- increment based on rig's range */ [LVL_NR] = { .min = { .f = 0 }, .max = { .f = 1 }, .step = { .f = 1.0f/10.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER] = { .min = { .f = .05 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_RFPOWER_METER] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0 }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, [LVL_SQL] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f/100.0f } }, [LVL_MICGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_MONITOR_GAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_COMP] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_VOXGAIN] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_ALC] = { .min = { .f = .0 }, .max = { .f = 1 }, .step = { .f = 1.0f/100.0f } }, [LVL_SWR] = { .min = { .f = 1.0 }, .max = { .f = 99.9 }, .step = { .f = 1.0f/10.0f } }, hamlib-4.6.2/rigs/kenwood/ic10.c0000644000175000017500000007130214752216205013221 00000000000000/* * Hamlib Kenwood backend - IC-10 interface for: * TS-940, TS-811, TS-711, TS-440, and R-5000 * * Copyright (c) 2000-2010 by Stephane Fillod and others * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include /* character class tests */ #include "hamlib/rig.h" #include "serial.h" #include "misc.h" #include "kenwood.h" #include "ic10.h" /**** * ic10_cmd_trim * gobbles up additional spaces at the end of a line * ****/ int ic10_cmd_trim(char *data, int data_len) { int i; rig_debug(RIG_DEBUG_TRACE, "%s: incoming data_len is '%d'\n", __func__, data_len); /* suck up additional spaces at end of the data buffer */ for (i = data_len; !isdigit((int)data[i - 1]); i--) { data_len = data_len - 1; rig_debug(RIG_DEBUG_TRACE, "%s: data['%d'] is '%c'\n", __func__, i - 1, data[i - 1]); rig_debug(RIG_DEBUG_TRACE, "%s: For i='%d' data_len is now '%d'\n", __func__, i, data_len); } rig_debug(RIG_DEBUG_TRACE, "%s: finished loop.. i='%d' data_len='%d' data[i-1]='%c'\n", __func__, i, data_len, data[i - 1]); return data_len; } /** * ic10_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL **/ int ic10_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; int retry_cmd = 0; struct hamlib_port *rp = RIGPORT(rig); if (cmd == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: cmd==NULL?\n", __func__); return -RIG_EARG; } rig_debug(RIG_DEBUG_TRACE, "%s: called cmd='%s', len=%d, data=%p, data_len=%p\n", __func__, cmd, cmd_len, data, data_len); transaction: rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } if (!data) { char buffer[50]; const struct kenwood_priv_data *priv = STATE(rig)->priv; if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { return retval; } // this should be the ID response retval = read_string(rp, (unsigned char *) buffer, sizeof(buffer), ";", 1, 0, 1); // might be ?; too if (buffer[0] == '?' && retry_cmd++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: retrying cmd #%d\n", __func__, retry_cmd); goto transaction; } if (strncmp("ID", buffer, 2) != 0) { rig_debug(RIG_DEBUG_ERR, "%s: expected ID response and got %s\n", __func__, buffer); return retval; } return RIG_OK; } retval = read_string(rp, (unsigned char *) data, 50, ";", 1, 0, 1); if (retval == -RIG_ETIMEOUT) { retval = 0; } if (retval < 0) { return retval; } *data_len = retval; return RIG_OK; } /* * Get the answer of IF command, with retry handling */ static int get_ic10_if(RIG *rig, char *data) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; int i, data_len, retval = RIG_EINVAL; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); for (i = 0; retval != RIG_OK && i < RIGPORT(rig)->retry; i++) { data_len = 37; retval = ic10_transaction(rig, "IF;", 3, data, &data_len); if (retval != RIG_OK) { continue; } if (data_len < priv->if_len || data[0] != 'I' || data[1] != 'F') { rig_debug(RIG_DEBUG_WARN, "%s: unexpected answer %s, len=%d\n", __func__, data, data_len); retval = -RIG_ERJCTED; } } return retval; } /* * ic10_set_vfo * Assumes rig!=NULL */ int ic10_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[6]; int retval; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_MAIN: case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_SUB: case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c;", vfo_function); retval = ic10_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, 0); return retval; } /* * ic10_get_vfo * Assumes rig!=NULL, !vfo */ int ic10_get_vfo(RIG *rig, vfo_t *vfo) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char vfobuf[50]; unsigned char c; int retval, iflen; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); /* query RX VFO */ retval = get_ic10_if(rig, vfobuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(vfobuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ c = vfobuf[iflen - 3]; switch (c) { case '0': *vfo = RIG_VFO_A; break; case '1': *vfo = RIG_VFO_B; break; case '2': *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, c); return -RIG_EPROTO; } rig_debug(RIG_DEBUG_VERBOSE, "%s: returning VFO=%s\n", __func__, rig_strvfo(*vfo)); return RIG_OK; } int ic10_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s tx_freq=%.0f\n", __func__, rig_strvfo(vfo), tx_freq); return ic10_set_freq(rig, RIG_VFO_B, tx_freq); } int ic10_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called vfo=%s\n", __func__, rig_strvfo(vfo)); return ic10_get_freq(rig, RIG_VFO_B, tx_freq); } int ic10_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); return ic10_transaction(rig, split == RIG_SPLIT_ON ? "SP1;" : "SP0;", 4, NULL, 0); } int ic10_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char infobuf[50]; int retval, iflen; retval = get_ic10_if(rig, infobuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(infobuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ *split = infobuf[iflen - 1] == '0' ? RIG_SPLIT_OFF : RIG_SPLIT_ON; return RIG_OK; } /* * ic10_get_mode * Assumes rig!=NULL, !vfo */ int ic10_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char modebuf[50]; unsigned char c; int retval, iflen; /* query RX VFO */ retval = get_ic10_if(rig, modebuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(modebuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ c = modebuf[iflen - 4]; switch (c) { case MD_CW : *mode = RIG_MODE_CW; break; case MD_USB : *mode = RIG_MODE_USB; break; case MD_LSB : *mode = RIG_MODE_LSB; break; case MD_FM : *mode = RIG_MODE_FM; break; case MD_AM : *mode = RIG_MODE_AM; break; case MD_FSK : *mode = RIG_MODE_RTTY; break; case MD_NONE: *mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, c); return -RIG_EINVAL; } *width = rig_passband_normal(rig, *mode); return RIG_OK; } /* * ic10_set_mode * Assumes rig!=NULL */ int ic10_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char modebuf[6]; int retval; char mode_letter; switch (mode) { case RIG_MODE_LSB : mode_letter = MD_LSB; break; case RIG_MODE_USB : mode_letter = MD_USB; break; case RIG_MODE_CW : mode_letter = MD_CW; break; case RIG_MODE_FM : mode_letter = MD_FM; break; case RIG_MODE_AM : mode_letter = MD_AM; break; case RIG_MODE_RTTY : mode_letter = MD_FSK; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(modebuf, sizeof(modebuf), "MD%c;", mode_letter); retval = ic10_transaction(rig, modebuf, strlen(modebuf), NULL, 0); return retval; } /* * ic10_get_freq * Assumes rig!=NULL, freq!=NULL */ int ic10_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char infobuf[50]; int retval; if (vfo != RIG_VFO_CURR) { /* targeted freq retrieval */ return kenwood_get_freq(rig, vfo, freq); } retval = get_ic10_if(rig, infobuf); if (retval != RIG_OK) { return retval; } /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ infobuf[13] = '\0'; sscanf(infobuf + 2, "%011"SCNfreq, freq); return RIG_OK; } /* * ic10_set_freq * Assumes rig!=NULL */ int ic10_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[64]; int retval; unsigned char vfo_letter; vfo_t tvfo; if (vfo == RIG_VFO_CURR) { tvfo = STATE(rig)->current_vfo; } else { tvfo = vfo; } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(freqbuf, sizeof(freqbuf), "F%c%011"PRIll";", vfo_letter, (int64_t)freq); retval = ic10_transaction(rig, freqbuf, strlen(freqbuf), NULL, 0); return retval; } /* * ic10_set_ant * Assumes rig!=NULL */ int ic10_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char buf[6], ackbuf[64]; int ack_len, retval; SNPRINTF(buf, sizeof(buf), "AN%c;", ant == RIG_ANT_1 ? '1' : '2'); retval = ic10_transaction(rig, buf, strlen(buf), ackbuf, &ack_len); return retval; } /* * ic10_get_ant * Assumes rig!=NULL, ptt!=NULL */ int ic10_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char infobuf[50]; int info_len, retval; info_len = 4; retval = ic10_transaction(rig, "AN;", 3, infobuf, &info_len); if (retval != RIG_OK) { return retval; } if (info_len < 4 || infobuf[0] != 'A' || infobuf[1] != 'N') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, info_len); return -RIG_ERJCTED; } *ant_curr = infobuf[2] == '1' ? RIG_ANT_1 : RIG_ANT_2; return RIG_OK; } /* * ic10_get_ptt * Assumes rig!=NULL, ptt!=NULL */ int ic10_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char infobuf[50]; int retval, iflen, offset; retval = get_ic10_if(rig, infobuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(infobuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp#### what should be if p13/p14/p15 included */ /* IF00014074000 +00000000003000000 ; QRP QDX bad IF command -- 36 bytes instead of 33 */ /* QRP QDX should be 37 bytes but used only 1 byte for p14 instead of 2 bytes */ /* 12345678901234567890123456789012345678 */ offset = 5; if (iflen == 36) { offset = 8; } // QRP QDX gets completely bogus length else if (iflen == 37) { offset = 9; } // just in case somebody does this add p13/p14x2/p15 *ptt = infobuf[iflen - offset] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; return RIG_OK; } // Not referenced anywhere /* * ic10_set_ptt * Assumes rig!=NULL */ int ic10_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char pttbuf[4]; int retval; unsigned char ptt_letter; rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__); switch (ptt) { case RIG_PTT_OFF: ptt_letter = 'R'; break; case RIG_PTT_ON : ptt_letter = 'T'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported PTT %d\n", __func__, ptt); return -RIG_EINVAL; } SNPRINTF(pttbuf, sizeof(pttbuf), "%cX;", ptt_letter); retval = ic10_transaction(rig, pttbuf, strlen(pttbuf), NULL, 0); return retval; } /* * ic10_get_mem * Assumes rig!=NULL */ int ic10_get_mem(RIG *rig, vfo_t vfo, int *ch) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char membuf[50]; int retval, iflen; retval = get_ic10_if(rig, membuf); if (retval != RIG_OK) { return retval; } /* trim extra spaces */ iflen = ic10_cmd_trim(membuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ membuf[iflen - 5] = '\0'; *ch = atoi(membuf + priv->if_len - 7); return RIG_OK; } /* * ic10_set_mem * Assumes rig!=NULL */ int ic10_set_mem(RIG *rig, vfo_t vfo, int ch) { char membuf[8], ackbuf[64]; int ack_len, retval; SNPRINTF(membuf, sizeof(membuf), "MC%02d;", ch); retval = ic10_transaction(rig, membuf, strlen(membuf), ackbuf, &ack_len); return retval; } int ic10_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { char membuf[16], infobuf[32]; int retval, info_len; SNPRINTF(membuf, sizeof(membuf), "MR00%02d;", chan->channel_num); info_len = 24; retval = ic10_transaction(rig, membuf, strlen(membuf), infobuf, &info_len); if (retval != RIG_OK) { return retval; } /* MRs-ccfffffffffffml----; */ /* 012345678901234567890123 */ switch (infobuf[17]) { case MD_CW : chan->mode = RIG_MODE_CW; break; case MD_USB : chan->mode = RIG_MODE_USB; break; case MD_LSB : chan->mode = RIG_MODE_LSB; break; case MD_FM : chan->mode = RIG_MODE_FM; break; case MD_AM : chan->mode = RIG_MODE_AM; break; case MD_FSK : chan->mode = RIG_MODE_RTTY; break; case MD_NONE: chan->mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, infobuf[17]); return -RIG_EINVAL; } chan->width = rig_passband_normal(rig, chan->mode); sscanf(infobuf + 6, "%011"SCNfreq, &chan->freq); chan->vfo = RIG_VFO_MEM; if (chan->channel_num >= 90) { chan->split = 1; /* TX VFO (Split channel only) */ SNPRINTF(membuf, sizeof(membuf), "MR10%02d;", chan->channel_num); info_len = 24; retval = ic10_transaction(rig, membuf, strlen(membuf), infobuf, &info_len); if (retval == RIG_OK && info_len > 17) { /* MRn rrggmmmkkkhhhdz ; */ switch (infobuf[17]) { case MD_CW : chan->tx_mode = RIG_MODE_CW; break; case MD_USB : chan->tx_mode = RIG_MODE_USB; break; case MD_LSB : chan->tx_mode = RIG_MODE_LSB; break; case MD_FM : chan->tx_mode = RIG_MODE_FM; break; case MD_AM : chan->tx_mode = RIG_MODE_AM; break; case MD_FSK : chan->tx_mode = RIG_MODE_RTTY; break; case MD_NONE: chan->tx_mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, infobuf[17]); return -RIG_EINVAL; } chan->tx_width = rig_passband_normal(rig, chan->tx_mode); sscanf(infobuf + 6, "%011"SCNfreq, &chan->tx_freq); } } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ic10_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char membuf[64]; int retval, md; int64_t freq; freq = (int64_t) chan->freq; if (chan->channel_num < 90 && chan->tx_freq != 0) { rig_debug(RIG_DEBUG_ERR, "%s: Transmit/split can only be on channels 90-99\n", __func__); return -RIG_EINVAL; } switch (chan->mode) { case RIG_MODE_CW : md = MD_CW; break; case RIG_MODE_USB : md = MD_USB; break; case RIG_MODE_LSB : md = MD_LSB; break; case RIG_MODE_FM : md = MD_FM; break; case RIG_MODE_AM : md = MD_AM; break; case RIG_MODE_RTTY: md = MD_FSK; break; case RIG_MODE_NONE: md = MD_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } /* MWnxrrggmmmkkkhhhdzxxxx; */ SNPRINTF(membuf, sizeof(membuf), "MW0 %02d%011"PRIll"%c0 ;", chan->channel_num, freq, md ); retval = ic10_transaction(rig, membuf, strlen(membuf), NULL, 0); if (retval != RIG_OK) { return retval; } /* TX VFO (Split channel only) */ freq = chan->tx_freq; switch (chan->tx_mode) { case RIG_MODE_CW: md = MD_CW; break; case RIG_MODE_USB: md = MD_USB; break; case RIG_MODE_LSB: md = MD_LSB; break; case RIG_MODE_FM: md = MD_FM; break; case RIG_MODE_AM: md = MD_AM; break; case RIG_MODE_RTTY: md = MD_FSK; break; case RIG_MODE_NONE: md = MD_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } if (chan->channel_num >= 90) { /* MWnxrrggmmmkkkhhhdzxxxx; */ SNPRINTF(membuf, sizeof(membuf), "MW1 %02d%011"PRIll"%c0 ;", chan->channel_num, freq, md ); retval = ic10_transaction(rig, membuf, strlen(membuf), NULL, 0); // I assume we need to check the retval here -- W9MDB // This was found from cppcheck if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: transaction failed: %s\n", __func__, rigerror(retval)); return retval; } } return RIG_OK; } /* * ic10_get_func * Assumes rig!=NULL, val!=NULL */ int ic10_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char cmdbuf[6], fctbuf[50]; int fct_len, retval; fct_len = 4; switch (func) { case RIG_FUNC_LOCK: SNPRINTF(cmdbuf, sizeof(cmdbuf), "LK;"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } retval = ic10_transaction(rig, cmdbuf, strlen(cmdbuf), fctbuf, &fct_len); if (retval != RIG_OK) { return retval; } if (fct_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, fct_len); return -RIG_ERJCTED; } *status = fctbuf[2] == '0' ? 0 : 1; return RIG_OK; } /* * ic10_set_func * Assumes rig!=NULL, val!=NULL */ int ic10_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[4], fctbuf[16], ackbuf[64]; int ack_len; switch (func) { case RIG_FUNC_LOCK: SNPRINTF(cmdbuf, sizeof(cmdbuf), "LK"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_func %s", __func__, rig_strfunc(func)); return -RIG_EINVAL; } SNPRINTF(fctbuf, sizeof(fctbuf), "%s%c;", cmdbuf, status == 0 ? '0' : '1'); return ic10_transaction(rig, fctbuf, strlen(fctbuf), ackbuf, &ack_len); } /* * ic10_set_parm * Assumes rig!=NULL */ int ic10_set_parm(RIG *rig, setting_t parm, value_t val) { char cmdbuf[50]; int hours; int minutes; int seconds; switch (parm) { case RIG_PARM_TIME: minutes = val.i / 60; hours = minutes / 60; seconds = val.i - (minutes * 60); minutes = minutes % 60; SNPRINTF(cmdbuf, sizeof(cmdbuf), "CK1%02d%02d%02d;", hours, minutes, seconds); return ic10_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported set_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * ic10_get_parm * Assumes rig!=NULL, val!=NULL */ int ic10_get_parm(RIG *rig, setting_t parm, value_t *val) { int retval, lvl_len, i; char lvlbuf[50]; switch (parm) { case RIG_PARM_TIME: lvl_len = 10; retval = ic10_transaction(rig, "CK1;", 4, lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } /* "CK1hhmmss;"*/ if (lvl_len != 10) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, lvl_len); return -RIG_ERJCTED; } /* convert ASCII to numeric 0..9 */ for (i = 3; i < 9; i++) { lvlbuf[i] -= '0'; } val->i = ((10 * lvlbuf[3] + lvlbuf[4]) * 60 + /* hours */ 10 * lvlbuf[5] + lvlbuf[6]) * 60 + /* minutes */ 10 * lvlbuf[7] + lvlbuf[8]; /* seconds */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported get_parm %s\n", __func__, rig_strparm(parm)); return -RIG_EINVAL; } return RIG_OK; } /* * ic10_set_powerstat * Assumes rig!=NULL */ int ic10_set_powerstat(RIG *rig, powerstat_t status) { char pwrbuf[16], ackbuf[64]; int ack_len; SNPRINTF(pwrbuf, sizeof(pwrbuf), "PS%c;", status == RIG_POWER_ON ? '1' : '0'); return ic10_transaction(rig, pwrbuf, strlen(pwrbuf), ackbuf, &ack_len); } /* * ic10_get_powerstat * Assumes rig!=NULL, trn!=NULL */ int ic10_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[50]; int pwr_len, retval; pwr_len = 4; retval = ic10_transaction(rig, "PS;", 3, pwrbuf, &pwr_len); if (retval != RIG_OK) { return retval; } if (pwr_len != 4) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, pwr_len); return -RIG_ERJCTED; } *status = pwrbuf[2] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; return RIG_OK; } /* * ic10_set_trn * Assumes rig!=NULL */ int ic10_set_trn(RIG *rig, int trn) { char trnbuf[16], ackbuf[64]; int ack_len; SNPRINTF(trnbuf, sizeof(trnbuf), "AI%c;", trn == RIG_TRN_RIG ? '1' : '0'); return ic10_transaction(rig, trnbuf, strlen(trnbuf), ackbuf, &ack_len); } /* * ic10_get_trn * Assumes rig!=NULL, trn!=NULL */ int ic10_get_trn(RIG *rig, int *trn) { char trnbuf[50]; int trn_len, retval; trn_len = 38; retval = ic10_transaction(rig, "AI;", 3, trnbuf, &trn_len); if (retval != RIG_OK) { return retval; } if (trn_len != 38) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, trn_len); return -RIG_ERJCTED; } *trn = trnbuf[2] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; return RIG_OK; } /* * ic10_vfo_op * Assumes rig!=NULL */ int ic10_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char *cmd, ackbuf[64]; int ack_len; switch (op) { case RIG_OP_UP : cmd = "UP;"; break; case RIG_OP_DOWN : cmd = "DN;"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } return ic10_transaction(rig, cmd, 3, ackbuf, &ack_len); } /* * ic10_scan * Assumes rig!=NULL, val!=NULL */ int ic10_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { char ackbuf[64]; int ack_len; return ic10_transaction(rig, scan == RIG_SCAN_STOP ? "SC0;" : "SC1;", 4, ackbuf, &ack_len); } /* * ic10_get_info * Assumes rig!=NULL */ const char *ic10_get_info(RIG *rig) { char firmbuf[50]; int firm_len, retval; firm_len = 6; retval = ic10_transaction(rig, "ID;", 3, firmbuf, &firm_len); if (retval != RIG_OK) { return NULL; } if (firm_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, firm_len); return NULL; } switch (firmbuf[4]) { case '4': return "ID: TS-440S"; case '5': return "ID: R-5000"; default: return "ID: unknown"; } } /* * ic10_decode_event is called by sa_sigio, when some asynchronous * data has been received from the rig. */ int ic10_decode_event(RIG *rig) { const struct kenwood_priv_caps *priv = (struct kenwood_priv_caps *) rig->caps->priv; char asyncbuf[128], c; int retval, async_len = 128, iflen; vfo_t vfo; freq_t freq; rmode_t mode; ptt_t ptt; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = ic10_transaction(rig, NULL, 0, asyncbuf, &async_len); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__); /* --------------------------------------------------------------------- */ if (async_len < priv->if_len || asyncbuf[0] != 'I' || asyncbuf[1] != 'F') { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf); return -RIG_ENIMPL; } /* trim extra spaces */ iflen = ic10_cmd_trim(asyncbuf, priv->if_len); /* IFggmmmkkkhhh snnnzrx yytdfcp */ /* IFggmmmkkkhhhxxxxxrrrrrssxcctmfcp */ c = asyncbuf[iflen - 3]; switch (c) { case '0': vfo = RIG_VFO_A; break; case '1': vfo = RIG_VFO_B; break; case '2': vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, c); return -RIG_EPROTO; } c = asyncbuf[iflen - 4]; switch (c) { case MD_CW : mode = RIG_MODE_CW; break; case MD_USB : mode = RIG_MODE_USB; break; case MD_LSB : mode = RIG_MODE_LSB; break; case MD_FM : mode = RIG_MODE_FM; break; case MD_AM : mode = RIG_MODE_AM; break; case MD_FSK : mode = RIG_MODE_RTTY; break; case MD_NONE: mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%c'\n", __func__, c); return -RIG_EINVAL; } ptt = asyncbuf[iflen - 5] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; asyncbuf[13] = '\0'; sscanf(asyncbuf + 2, "%011"SCNfreq, &freq); /* Callback execution */ if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, vfo, rig->callbacks.vfo_arg); } if (rig->callbacks.freq_event) { rig->callbacks.freq_event(rig, vfo, freq, rig->callbacks.freq_arg); } if (rig->callbacks.mode_event) { rig->callbacks.mode_event(rig, vfo, mode, RIG_PASSBAND_NORMAL, rig->callbacks.mode_arg); } if (rig->callbacks.ptt_event) { rig->callbacks.ptt_event(rig, vfo, ptt, rig->callbacks.ptt_arg); } return RIG_OK; } hamlib-4.6.2/rigs/kenwood/flex.c0000644000175000017500000001053314752216205013422 00000000000000/* * Hamlib Flex 6K series support using supported Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2011 by Alexander Sack, Alexander Sack, pisymbol@gmail.com * Copyright (C) 2013 by Steve Conklin AI4QR, steve@conklinhouse.com * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include "flex.h" #include "kenwood.h" /* Private helper functions */ int verify_flexradio_id(RIG *rig, char *id) { int err; char *idptr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!id) { return -RIG_EINVAL; } /* Check for a Flex 6700 which returns "904" */ err = kenwood_get_id(rig, id); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cannot get identification\n", __func__); return err; } /* ID is 'ID904;' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown ID type (%s)\n", __func__, id); return -RIG_EPROTO; } /* check for any white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } if (strcmp("900", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (PowerSDR compatible)\n", __func__, id); } else if (strcmp("904", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6700)\n", __func__, id); } else if (strcmp("905", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6500)\n", __func__, id); } else if (strcmp("906", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6500R)\n", __func__, id); } else if (strcmp("907", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6300)\n", __func__, id); } else if (strcmp("908", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6400)\n", __func__, id); } else if (strcmp("909", idptr) == 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.5s (Flex 6600)\n", __func__, id); } else { rig_debug(RIG_DEBUG_WARN, "%s: Rig (%.5s) is not a Flex 6000 Series\n", __func__, id); } return RIG_OK; } /* Shared backend function definitions */ /* flexradio_open() * */ int flexradio_open(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; int err; char id[FLEXRADIO_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); //struct flexradio_priv_data *priv = STATE(rig)->priv; /* Use check for "ID017;" to verify rig is reachable */ err = verify_flexradio_id(rig, id); if (err != RIG_OK) { return err; } switch (rig->caps->rig_model) { case RIG_MODEL_F6K: break; case RIG_MODEL_POWERSDR: case RIG_MODEL_THETIS: break; default: rig_debug(RIG_DEBUG_WARN, "%s: unrecognized rig model %u\n", __func__, rig->caps->rig_model); return -RIG_EINVAL; } priv->has_rit2 = 1; /* get current AI state so it can be restored */ priv->trn_state = -1; kenwood_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ return RIG_OK; } //stopped hamlib-4.6.2/rigs/kenwood/pihpsdr.c0000644000175000017500000012062514752216205014141 00000000000000/* * Hamlib PiHPSDR backend - TS-2000 Emulation (derived from ts2000.c) * Copyright (c) 2017 by Jae Stutzman * Copyright (c) 2000-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include "kenwood.h" #include "tones.h" #define PIHPSDR_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define PIHPSDR_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define PIHPSDR_AM_TX_MODES RIG_MODE_AM #define PIHPSDR_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_BC|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_COMP) #define PIHPSDR_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_COMP|RIG_LEVEL_AGC|RIG_LEVEL_BKINDL|RIG_LEVEL_METER|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define PIHPSDR_MAINVFO (RIG_VFO_A|RIG_VFO_B) #define PIHPSDR_SUBVFO (RIG_VFO_C) #define PIHPSDR_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN) #define PIHPSDR_SCAN_OP (RIG_SCAN_VFO) #define PIHPSDR_ANTS (RIG_ANT_1|RIG_ANT_2) #define PIHPSDR_STR_CAL {9, {\ {0x00, -54},\ {0x03, -48},\ {0x06, -36},\ {0x09, -24},\ {0x0C, -12},\ {0x0F, 0},\ {0x14, 20},\ {0x19, 40},\ {0x1E, 60}}\ } /* prototypes */ static int pihpsdr_open(RIG *rig); static int pihpsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int pihpsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); static int pihspdr_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int pihspdr_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); static struct kenwood_priv_caps ts2000_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* memory capabilities */ #define PIHPSDR_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .dcs_code=1, \ .dcs_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* * PiHPSDR rig capabilities. (Emulates Kenwood TS-2000) */ struct rig_caps pihpsdr_caps = { RIG_MODEL(RIG_MODEL_HPSDR), .model_name = "PiHPSDR", .mfg_name = "OpenHPSDR", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 50, /* ms */ .timeout = 500, .retry = 1, .has_get_func = PIHPSDR_FUNC_ALL, .has_set_func = PIHPSDR_FUNC_ALL, .has_get_level = PIHPSDR_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(PIHPSDR_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .parm_gran = {}, .vfo_ops = PIHPSDR_VFO_OP, .scan_ops = PIHPSDR_SCAN_OP, .ctcss_list = common_ctcss_list, .dcs_list = common_dcs_list, .preamp = { 20, RIG_DBLST_END, }, /* FIXME: real preamp? */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, PIHPSDR_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(144), MHz(146), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(430), MHz(440), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(144), MHz(146), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, {MHz(430), MHz(440), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(1830), kHz(1850), PIHPSDR_AM_TX_MODES, 2000, 25000, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), kHz(3800), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), kHz(3800), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7100), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7100), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(50.2), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(50.2), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(144), MHz(146), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO}, {MHz(144), MHz(146), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO}, {MHz(430), MHz(440), PIHPSDR_OTHER_TX_MODES, W(5), W(50), PIHPSDR_MAINVFO}, {MHz(430), MHz(440), PIHPSDR_AM_TX_MODES, W(5), W(12.5), PIHPSDR_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(142), MHz(152), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(420), MHz(450), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_MAINVFO}, {MHz(118), MHz(174), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, {MHz(220), MHz(512), PIHPSDR_ALL_MODES, -1, -1, PIHPSDR_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(1800), MHz(2), PIHPSDR_AM_TX_MODES, 2000, 25000, PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), MHz(4), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(3500), MHz(4), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7300), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(7), kHz(7300), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(10.1), MHz(10.15), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(14), kHz(14350), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(18068), kHz(18168), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(21), kHz(21450), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {kHz(24890), kHz(24990), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(28), kHz(29700), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(54), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(50), MHz(54), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO, PIHPSDR_ANTS}, {MHz(144), MHz(148), PIHPSDR_OTHER_TX_MODES, W(5), W(100), PIHPSDR_MAINVFO}, {MHz(144), MHz(148), PIHPSDR_AM_TX_MODES, W(5), W(25), PIHPSDR_MAINVFO}, {MHz(430), MHz(450), PIHPSDR_OTHER_TX_MODES, W(5), W(50), PIHPSDR_MAINVFO}, {MHz(430), MHz(450), PIHPSDR_AM_TX_MODES, W(5), W(12.5), PIHPSDR_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {PIHPSDR_ALL_MODES, 10}, {PIHPSDR_ALL_MODES, 100}, {PIHPSDR_ALL_MODES, kHz(1)}, {PIHPSDR_ALL_MODES, kHz(2.5)}, {PIHPSDR_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {PIHPSDR_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {PIHPSDR_ALL_MODES, MHz(1)}, {PIHPSDR_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, Hz(600)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 5}, .max = {.i = 50}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .max = {.i = 1000}, .step = {.i = 50}}, [LVL_BKIN_DLYMS] = {.min = {.i = 0}, .max = {.i = 1000}, .step = {.i = 50}}, }, .str_cal = PIHPSDR_STR_CAL, .priv = (void *)& ts2000_priv_caps, .rig_init = kenwood_init, .rig_open = pihpsdr_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = pihpsdr_set_level, .get_level = pihpsdr_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = pihspdr_get_channel, .set_channel = pihspdr_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * pihspdr_get_channel * Read command format: M|R|P1|P2|P3|P3|;| * P1: 0 - RX frequency, 1 - TX frequency Memory channel 290 ~ 299: P1=0 (start frequency), P1=1 (end frequency) P2 - bank number allowed values: , 0, 1 or 2 P3 - channel number 00-99 Returned value: M | R |P1 |P2 |P3 |P3 |P4 |P4 |P4 |P4 | P4 |P4 |P4 |P4 |P4 |P4 |P4 |P5 |P6 |P7 | P8 |P8 |P9 |P9 |P10|P10|P10|P11|P12|P13| P13|P13|P13|P13|P13|P13|P13|P13|P14|P14| P15|P16|P16|P16|P16|P16|P16|P16|P16| ; | P1 - P3 described above P4: Frequency in Hz (11-digit). P5: Mode. 1: LSB, 2: USB, 3: CW, 4: FM, 5: AM, 6: FSK, 7: CR-R, 8: Reserved, 9: FSK-R P6: Lockout status. 0: Lockout OFF, 1: Lockout ON. P7: 0: OFF, 1: TONE, 2: CTCSS, 3: DCS. P8: Tone Number. Allowed values 01 (67Hz) - 38 (250.3Hz) P9: CTCSS tone number. Allowed values 01 (67Hz) - 38 (250.3Hz) P10: DCS code. Allowed values 000 (023 DCS code) to 103 (754 DCS code). P11: REVERSE status. P12: SHIFT status. 0: Simplex, 1: +, 2: –, 3: = (All E-types) P13: Offset frequency in Hz (9-digit). Allowed values 000000000 - 059950000 in steps of 50000. Unused digits must be 0. P14: Step size. Allowed values: for SSB, CW, FSK mode: 00 - 03 00: 1 kHz, 01: 2.5 kHz, 02: 5 kHz, 03: 10 kHz for AM, FM mode: 00 - 09 00: 5 kHz, 01: 6.25 kHz, 02: 10 kHz, 03: 12.5 kHz, 04: 15 kHz, 05: 20 kHz, 06: 25 kHz, 07: 30 kHz, 08: 50 kHz, 09: 100 kHz P15: Memory Group number (0 ~ 9). P16: Memory name. A maximum of 8 characters. */ int pihspdr_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; int tmp; char buf[52]; char cmd[8]; size_t length; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan || chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* put channel num in the command string */ SNPRINTF(cmd, sizeof(cmd), "MR0%03d;", chan->channel_num); err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } length = strlen(buf); memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ /* First check if a name is assigned. Name is returned at positions 41-48 (counting from 0) */ if (length > 41) { // rig_debug(RIG_DEBUG_VERBOSE, "Copying channel description: %s\n", &buf[ 41 ] ); strcpy(chan->channel_desc, &buf[ 41 ]); } /* Memory group no */ chan->scan_group = buf[ 40 ] - '0'; /* Fields 38-39 contain tuning step as a number 00 - 09. Tuning step depends on this number and the mode, just save it for now */ buf[ 40 ] = '\0'; tmp = atoi(&buf[ 38]); /* Offset frequency */ buf[ 38 ] = '\0'; chan->rptr_offs = atoi(&buf[ 29 ]); /* Shift type WARNING: '=' shift type not programmed */ if (buf[ 28 ] == '1') { chan->rptr_shift = RIG_RPT_SHIFT_PLUS; } else { if (buf[ 28 ] == '2') { chan->rptr_shift = RIG_RPT_SHIFT_MINUS; } else { chan->rptr_shift = RIG_RPT_SHIFT_NONE; } } /* Reverse status */ if (buf[27] == '1') { chan->funcs |= RIG_FUNC_REV; } /* Check for tone, CTCSS and DCS */ /* DCS code first */ if (buf[ 19 ] == '3') { if (rig->caps->dcs_list) { buf[ 27 ] = '\0'; chan->dcs_code = rig->caps->dcs_list[ atoi(&buf[ 24 ]) ]; chan->dcs_sql = chan->dcs_code; chan->ctcss_tone = 0; chan->ctcss_sql = 0; } } else { chan->dcs_code = 0; chan->dcs_sql = 0; /* CTCSS code Caution, CTCSS codes, unlike DCS codes, are numbered from 1! */ buf[ 24 ] = '\0'; if (buf[ 19 ] == '2') { chan->funcs |= RIG_FUNC_TSQL; if (rig->caps->ctcss_list) { chan->ctcss_sql = rig->caps->ctcss_list[ atoi(&buf[22]) - 1 ]; chan->ctcss_tone = 0; } } else { chan->ctcss_sql = 0; /* CTCSS tone */ if (buf[ 19 ] == '1') { chan->funcs |= RIG_FUNC_TONE; buf[ 22 ] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[ atoi(&buf[20]) - 1 ]; } } else { chan->ctcss_tone = 0; } } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } /* mode */ chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); /* Now we have the mode, let's finish the tuning step */ if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (tmp) { case 0: chan->tuning_step = kHz(5); break; case 1: chan->tuning_step = kHz(6.25); break; case 2: chan->tuning_step = kHz(10); break; case 3: chan->tuning_step = kHz(12.5); break; case 4: chan->tuning_step = kHz(15); break; case 5: chan->tuning_step = kHz(20); break; case 6: chan->tuning_step = kHz(25); break; case 7: chan->tuning_step = kHz(30); break; case 8: chan->tuning_step = kHz(50); break; case 9: chan->tuning_step = kHz(100); break; default: chan->tuning_step = 0; } } else { switch (tmp) { case 0: chan->tuning_step = kHz(1); break; case 1: chan->tuning_step = kHz(2.5); break; case 2: chan->tuning_step = kHz(5); break; case 3: chan->tuning_step = kHz(10); break; default: chan->tuning_step = 0; } } /* Frequency */ buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[3]); /* Check split freq */ cmd[2] = '1'; err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int pihspdr_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char sqltype; char shift; char buf[128]; char mode, tx_mode = 0; int err; int tone = 0; int tstep; short code; short dcscode; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ sqltype = '0'; if (chan->ctcss_tone) { for (; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = -1; } else { sqltype = '1'; } } else { tone = -1; /* -1 because we will add 1 when outputting; this is necessary as CTCSS codes are numbered from 1 */ } /* find CTCSS code */ code = 0; if (chan->ctcss_sql) { for (; rig->caps->ctcss_list[code] != 0; code++) { if (chan->ctcss_sql == rig->caps->ctcss_list[code]) { break; } } if (chan->ctcss_sql != rig->caps->ctcss_list[code]) { code = -1; } else { sqltype = '2'; } } else { code = -1; } /* find DCS code */ dcscode = 0; if (chan->dcs_code) { for (; rig->caps->dcs_list[dcscode] != 0; dcscode++) { if (chan->dcs_code == rig->caps->dcs_list[dcscode]) { break; } } if (chan->dcs_code != rig->caps->dcs_list[dcscode]) { dcscode = 0; } else { sqltype = '3'; } } else { dcscode = 0; } shift = '0'; if (chan->rptr_shift == RIG_RPT_SHIFT_PLUS) { shift = '1'; } if (chan->rptr_shift == RIG_RPT_SHIFT_MINUS) { shift = '2'; } tstep = 0; if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (chan->tuning_step) { case s_kHz(6.25): tstep = 1; break; case s_kHz(10): tstep = 2; break; case s_kHz(12.5): tstep = 3; break; case s_kHz(15): tstep = 4; break; case s_kHz(20): tstep = 5; break; case s_kHz(25): tstep = 6; break; case s_kHz(30): tstep = 7; break; case s_kHz(50): tstep = 8; break; case s_kHz(100): tstep = 9; break; default: tstep = 0; } } else { switch (chan->tuning_step) { case s_kHz(2.5): tstep = 1; break; case s_kHz(5): tstep = 2; break; case s_kHz(10): tstep = 3; break; default: tstep = 0; } } /* P-number 2-3 4 5 6 7 8 9 101112 13 141516 */ SNPRINTF(buf, sizeof(buf), "MW0%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;", chan->channel_num, (unsigned) chan->freq, /* 4 - frequency */ '0' + mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* 15 - Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "The command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (chan->split == RIG_SPLIT_ON) { SNPRINTF(buf, sizeof(buf), "MW1%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;\n", chan->channel_num, (unsigned) chan->tx_freq, /* 4 - frequency */ '0' + tx_mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode + 1, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "Split, the command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); } return err; } int pihpsdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int i, kenwood_val; struct rig_state *rs = STATE(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { kenwood_val = val.f * 255; } else { kenwood_val = val.i; } switch (level) { case RIG_LEVEL_RFPOWER: /* level is float between 0.0 and 1.0, maps to 0 ... 100 */ kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", kenwood_val); break; case RIG_LEVEL_AF: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", kenwood_val); break; case RIG_LEVEL_RF: /* XXX check level range */ SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_SQL: SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%03d", kenwood_val); break; case RIG_LEVEL_AGC: if (kenwood_val == RIG_AGC_SUPERFAST) { kenwood_val = 5; } else if (kenwood_val == RIG_AGC_FAST) { kenwood_val = 10; } else if (kenwood_val == RIG_AGC_MEDIUM) { kenwood_val = 15; } else if (kenwood_val == RIG_AGC_SLOW) { kenwood_val = 20; } else if (kenwood_val != RIG_AGC_OFF) { rig_debug(RIG_DEBUG_ERR, "%s: unknown AGC level, expect OFF,SLOW,MEDIUM,FAST,SUPERFAST, got %d\n", __func__, kenwood_val); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_ATT: /* set the attenuator if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA00"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->attenuator[i]; i++) { if (val.i == rs->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_PREAMP: /* set the preamp if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->preamp[i]; i++) { if (val.i == rs->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_SLOPE_HIGH: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SH%02d", (val.i)); break; case RIG_LEVEL_SLOPE_LOW: if (val.i > 20 || val.i < 0) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "SL%02d", (val.i)); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "PT%02d", (val.i / 50) - 8); break; case RIG_LEVEL_KEYSPD: if (val.i > 50 || val.i < 5) { return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "KS%03d", val.i); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return kenwood_transaction(rig, levelbuf, NULL, 0); } /* * pihpsdr_get_level * Assumes rig!=NULL, val!=NULL */ int pihpsdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; size_t lvl_len; int lvl, retval; lvl_len = 50; switch (level) { case RIG_LEVEL_PREAMP: retval = kenwood_transaction(rig, "PA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 4)) /*TS-2000 returns 4 chars for PA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 10) /* just checking for main receiver preamp setting */ { val->i = 0; } if (lvl > 9) { val->i = STATE(rig)->preamp[0]; } break; case RIG_LEVEL_ATT: retval = kenwood_transaction(rig, "RA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 6)) /* TS-2000 returns 6 chars for RA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 100) /* just checking main band attenuator */ { val->i = 0; } if (lvl > 99) { val->i = STATE( rig)->attenuator[0]; /* Since the TS-2000 only has one step on the attenuator */ } break; case RIG_LEVEL_VOXDELAY: retval = kenwood_transaction(rig, "VD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_AF: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_CWPITCH: retval = kenwood_transaction(rig, "EX0310000", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 15) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d answer=%s\n", __func__, (int)lvl_len, lvlbuf); return -RIG_ERJCTED; } sscanf(lvlbuf + 8, "%d", &lvl); val->i = 400 + (50 * lvl); break; case RIG_LEVEL_RFPOWER: retval = kenwood_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 100.0; /* FIXME: for 1.2GHZ need to divide by 10 */ break; case RIG_LEVEL_MICGAIN: retval = kenwood_transaction(rig, "MG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 100.0; break; case RIG_LEVEL_KEYSPD: retval = kenwood_transaction(rig, "KS", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl; break; case RIG_LEVEL_NOTCHF: return -RIG_ENIMPL; break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "PL", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); lvl = lvl / 1000; val->f = lvl / 100.0; break; case RIG_LEVEL_AGC: /* pihpsdr defines the range 0 -20 for AGC (based on TS-2000) */ retval = kenwood_transaction(rig, "GT", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = RIG_AGC_OFF; } /*pihspdr: OFF */ else if (lvl < 6) { val->i = RIG_AGC_SUPERFAST; } /*pihspdr: 001-005 = FAST */ else if (lvl < 11) { val->i = RIG_AGC_FAST; } /*pihspdr: 006-010 = MEDIUM */ else if (lvl < 16) { val->i = RIG_AGC_MEDIUM; } /*pihspdr: 011-015 = SLOW */ else if (lvl <= 20) { val->i = RIG_AGC_SLOW; } /*pihspdr: 016-020 = LONG */ break; case RIG_LEVEL_BKINDL: retval = kenwood_transaction(rig, "SD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; break; case RIG_LEVEL_METER: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 7) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 10000; break; case RIG_LEVEL_VOXGAIN: retval = kenwood_transaction(rig, "VG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 9.0; break; case RIG_LEVEL_ANTIVOX: return -RIG_ENIMPL; break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (((lvl_len != 7)) || lvlbuf[1] != 'M') { /* TS-2000 returns 8 bytes for S meter level */ rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 3, "%d", &val->i); /* TS-2000 main receiver returns values from 0 - 30 */ /* so scale the value */ if (level == RIG_LEVEL_STRENGTH) { val->i = (val->i * 3.6) - 54; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* use custom open function since this rig emulates TS-2000 and we need to not use the TS-2000 backend open function */ int pihpsdr_open(RIG *rig) { char id[KENWOOD_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* get id in buffer, will be null terminated */ kenwood_get_id(rig, id); if (!strcmp(id, "ID019")) /* matched */ { /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ return RIG_OK; } /* driver mismatch */ rig_debug(RIG_DEBUG_ERR, "%s: wrong driver selected\n", __func__); return -RIG_EINVAL; } hamlib-4.6.2/rigs/kenwood/elecraft.h0000644000175000017500000000775014752216205014265 00000000000000/* * Hamlib Elecraft backend--support extensions to Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ELECRAFT_H #define _ELECRAFT_H 1 #include #include "token.h" /* The Elecraft Programmer's Reference details the extension level that * a K2 or K3 may have in effect which modify certain commands. */ enum elec_ext_id_e { K20 = 0, /* K2 Normal mode */ K21, /* K2 Normal/rtty_off */ K22, /* K2 Extended mode */ K23, /* K2 Extended mode/rtty_off */ K30, /* K3 Normal mode */ K31, /* K3 Extended mode */ XG3, /* XG3 */ EXT_LEVEL_NONE }; struct elec_ext_id_str { enum elec_ext_id_e level; const char *id; }; /* Data sub-modes are provided from the K3 via the DT command */ enum k3_data_submodes_e { K3_MODE_DATA_A = 0, /* DT0; */ K3_MODE_AFSK_A, /* DT1; */ K3_MODE_FSK_D, /* DT2; */ K3_MODE_PSK_D /* DT3; */ }; /* Private tokens used for ext_lvl function in Elecraft backends. * Extra levels which are rig specific should be coded in * the individual rig files and token #s >= 101. * * See Private Elecraft extra levels definitions in elecraft.c */ #define TOK_IF_FREQ TOKEN_BACKEND(101) /* K3 FI command - IF center frequency (K3/K3S only) */ #define TOK_TX_STAT TOKEN_BACKEND(102) /* K3 TQ command - transmit query (K3/K3S/KX3/KX2) */ #define TOK_RIT_CLR TOKEN_BACKEND(103) /* K3 RC command - RIT/XIT clear (K3/K3S/KX3/KX2) */ #define TOK_ESSB TOKEN_BACKEND(104) /* K3 ES command - ESSB mode (K3/K3S/KX3/KX2) */ #define TOK_RX_ANT TOKEN_BACKEND(105) /* K3 AR command - RX antenna on/off (K3/K3S only) */ #define TOK_LINK_VFOS TOKEN_BACKEND(106) /* K3 LN command - link VFOs on/off (K3/K3S only) */ #define TOK_TX_METER TOKEN_BACKEND(107) /* K3 TM command - Transmit meter mode, SWR/ALC (K3/K3S only) */ #define TOK_IF_NB TOKEN_BACKEND(108) /* K3 NL command - IF noise blanker level (K3/K3S only) */ /* Token structure assigned to .cfgparams in rig_caps */ extern const struct confparams elecraft_ext_levels[]; /* Elecraft extension function declarations */ int elecraft_open(RIG *rig); int elecraft_close(RIG *rig); /* S-meter calibration tables */ /* K3 defines 16 values--0-15. * Table is RASTR value from SM command and dB relative to S9 == 0 * (see rig_get_level() in src/settings.c */ #define K3_SM_CAL { 16, \ { \ { 0, -54 }, \ { 1, -42 }, \ { 2, -36 }, \ { 3, -24 }, \ { 4, -12 }, \ { 5, -6 }, \ { 6, 0 }, \ { 7, 10 }, \ { 8, 15 }, \ { 9, 20 }, \ { 10, 30 }, \ { 11, 35 }, \ { 12, 40 }, \ { 13, 50 }, \ { 14, 55 }, \ { 15, 60 }, \ } } /* K3 defines 100 values--0-100 in high resolution mode. * Table is RASTR value from SMH command and dB relative to S9 == 0 * (see rig_get_level() in src/settings.c */ #define K3_SMH_CAL { 22, \ { \ { 0, -54 }, \ { 5, -48 }, \ { 9, -42 }, \ { 14, -36 }, \ { 22, -30 }, \ { 24, -24 }, \ { 28, -18 }, \ { 33, -12 }, \ { 38, -6 }, \ { 42, 0 }, \ { 47, 5 }, \ { 53, 10 }, \ { 58, 15 }, \ { 63, 20 }, \ { 68, 25 }, \ { 73, 30 }, \ { 78, 35 }, \ { 83, 40 }, \ { 88, 45 }, \ { 93, 50 }, \ { 98, 55 }, \ { 103, 60 }, \ } } // K4 is the only we know that has this as of 2021-11-09 int elecraft_get_vfo_tq(RIG *rig, vfo_t *vfo); #endif /* _ELECRAFT_H */ hamlib-4.6.2/rigs/kenwood/ts590.c0000644000175000017500000022731614752216205013361 00000000000000/* * Hamlib Kenwood backend - TS-590(S/SG) description * Copyright (c) 2010 by Stephane Fillod * Copyright (c) 2023 by Mikael Nousiainen OH3BHX * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "hamlib/rig.h" #include "kenwood.h" #include "misc.h" #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| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT) #define TS590_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_USB_AF|RIG_LEVEL_USB_AF_INPUT) #define TS590_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT| \ RIG_FUNC_TUNER|RIG_FUNC_MON|RIG_FUNC_FBKIN|RIG_FUNC_LOCK) #define TS590_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_CPY|RIG_OP_TUNE) #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 { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .funcs=RIG_FUNC_TONE, \ .flags=RIG_CHFLAG_SKIP \ } #define TS590_STR_CAL {9, {\ { 0, -60},\ { 3, -48},\ { 6, -36},\ { 9, -24},\ {12, -12},\ {15, 0},\ {20, 20},\ {25, 40},\ {30, 60}}\ } #define TS590_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 6, 1.5f }, \ { 12, 2.0f }, \ { 18, 3.0f }, \ { 30, 10.0f } \ } } #define TOK_FUNC_NOISE_REDUCTION_2 TOKEN_BACKEND(102) #define TOK_LEVEL_DSP_RX_EQUALIZER TOKEN_BACKEND(104) #define TOK_LEVEL_DSP_TX_EQUALIZER TOKEN_BACKEND(105) #define TOK_LEVEL_BEEP_VOLUME TOKEN_BACKEND(107) #define TOK_LEVEL_TX_SIDETONE_VOLUME TOKEN_BACKEND(108) #define TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL TOKEN_BACKEND(109) #define TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL TOKEN_BACKEND(110) // these two USB_AUDIO items are being kept for backwards compatibility // replaced by RIG_LEVEL_USB_AF and RIG_LEVEL_USB_AF_INPUT #define TOK_LEVEL_USB_AUDIO_INPUT_LEVEL TOKEN_BACKEND(113) #define TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL TOKEN_BACKEND(114) #define TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER TOKEN_BACKEND(115) #define TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER TOKEN_BACKEND(116) #define TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER TOKEN_BACKEND(117) #define TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER TOKEN_BACKEND(118) int ts590_ext_tokens[] = { TOK_FUNC_NOISE_REDUCTION_2, TOK_LEVEL_DSP_RX_EQUALIZER, TOK_LEVEL_DSP_TX_EQUALIZER, TOK_LEVEL_BEEP_VOLUME, TOK_LEVEL_TX_SIDETONE_VOLUME, TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL, TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL, TOK_LEVEL_USB_AUDIO_INPUT_LEVEL, TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL, TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER, TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER, TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER, TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER, TOK_BACKEND_NONE, }; const struct confparams ts590_ext_funcs[] = { { TOK_FUNC_NOISE_REDUCTION_2, "NR2", "Noise reduction 2", "Noise reduction 2", NULL, RIG_CONF_CHECKBUTTON, }, { RIG_CONF_END, NULL, } }; const struct confparams ts590_ext_levels[] = { { TOK_LEVEL_DSP_RX_EQUALIZER, "DSP_RX_EQUALIZER", "DSP RX equalizer", "DSP RX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "c", "U", NULL } } } }, { TOK_LEVEL_DSP_TX_EQUALIZER, "DSP_TX_EQUALIZER", "DSP TX equalizer", "DSP TX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "flat", "U", NULL } } } }, { TOK_LEVEL_BEEP_VOLUME, "BEEP_VOLUME", "Beep volume", "Beep volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 20, .step = 1 } } }, { TOK_LEVEL_TX_SIDETONE_VOLUME, "TX_SIDETONE_VOLUME", "TX sidetone volume", "TX sidetone volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 20, .step = 1 } } }, { TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL, "ACC2_AUDIO_INPUT_LEVEL", "ACC2 audio input level", "ACC2 audio input level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL, "ACC2_AUDIO_OUTPUT_LEVEL", "ACC2 audio output level", "ACC2 audio output level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_USB_AUDIO_INPUT_LEVEL, "USB_AUDIO_INPUT_LEVEL", "USB audio input level", "USB audio input level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL, "USB_AUDIO_OUTPUT_LEVEL", "USB audio output level", "USB audio output level", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER, "DSP_TX_SSB_AM_LOW_CUT_FILTER", "DSP TX SSB/AM low-cut", "DSP TX low-cut filter for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "10 Hz", "100 Hz", "200 Hz", "300 Hz", "400 Hz", "500 Hz", NULL } } } }, { TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER, "DSP_TX_SSB_AM_HIGH_CUT_FILTER", "DSP TX SSB/AM high-cut", "DSP TX high-cut filter for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2500 Hz", "2600 Hz", "2700 Hz", "2800 Hz", "2900 Hz", "3000 Hz", NULL } } } }, { TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER, "DSP_TX_SSB_DATA_LOW_CUT_FILTER", "DSP TX SSB data low-cut", "DSP TX low-cut filter for SSB data", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "10 Hz", "100 Hz", "200 Hz", "300 Hz", "400 Hz", "500 Hz", NULL } } } }, { TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER, "DSP_TX_SSB_DATA_HIGH_CUT_FILTER", "DSP TX SSB data high-cut", "DSP TX high-cut filter for SSB data", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2500 Hz", "2600 Hz", "2700 Hz", "2800 Hz", "2900 Hz", "3000 Hz", NULL } } } }, { RIG_CONF_END, NULL, } }; /* * ts590_get_info * This is not documented in the manual as of 3/11/15 but confirmed from Kenwood * "TY" produces "TYK 00" for example */ const char *ts590_get_info(RIG *rig) { char firmbuf[10]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "TY", firmbuf, 10, 6); if (retval != RIG_OK) { return NULL; } switch (firmbuf[2]) { case 'K': return "Firmware: USA version"; case 'E': return "Firmware: European version"; default: return "Firmware: unknown"; } } // keep track of SF command ability static int sf_fails; static int ts590_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char kmode = rmode2kenwood(mode, caps->mode_table); char cmd[32], c; int retval = -RIG_EINTERNAL; int hwidth = 0; // int lwidth; // not implemented yet until new API is created if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); RETURNFUNC2(-RIG_EINVAL); } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } if (!sf_fails) { SNPRINTF(cmd, sizeof(cmd), "SF%d%011.0f%c", vfo == RIG_VFO_A ? 0 : 1, vfo == RIG_VFO_A ? CACHE(rig)->freqMainA : CACHE(rig)->freqMainB, c); retval = kenwood_transaction(rig, cmd, NULL, 0); } if (retval != RIG_OK || sf_fails) { return kenwood_set_mode(rig, vfo, mode, width); } if (width != RIG_PASSBAND_NOCHANGE) { if (mode == RIG_MODE_CW || mode == RIG_MODE_CWR) { const int cw_table[] = { 50, 80, 100, 150, 200, 250, 300, 400, 500, 600, 1000, 1500, 2000, 2500 }; int twidth = 2500; // maximum for (int i = 0; i < sizeof(cw_table) / sizeof(int); ++i) { if (cw_table[i] >= width) { twidth = cw_table[i]; break; } } SNPRINTF(cmd, sizeof(cmd), "FW%04d;", twidth); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } else if (mode == RIG_MODE_RTTY || mode == RIG_MODE_RTTYR) { const int cw_table[] = { 250, 500, 1000, 1500 }; int twidth = 1500; // maximum for (int i = 0; i < sizeof(cw_table) / sizeof(int); ++i) { if (cw_table[i] >= width) { twidth = cw_table[i]; break; } } SNPRINTF(cmd, sizeof(cmd), "FW%04d;", twidth); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } else if (mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB) { const int pkt_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; // not setting SL since no API for it yet // we will just set SH based on requested bandwidth not taking SL into account //const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; for (int i = 0; i < sizeof(pkt_htable) / sizeof(int); ++i) { if (pkt_htable[i] >= width) { hwidth = i; break; } } } else if (mode == RIG_MODE_AM || mode == RIG_MODE_PKTAM) { const int am_htable[] = { 2500, 3000, 4000, 5000 }; //const int am_ltable[] = { 0, 100, 200, 300 }; for (int i = 0; i < sizeof(am_htable) / sizeof(int); ++i) { if (am_htable[i] >= width) { hwidth = i; break; } } } else if (mode == RIG_MODE_SSB || mode == RIG_MODE_LSB || mode == RIG_MODE_USB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; //const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; for (int i = 0; i < sizeof(ssb_htable) / sizeof(int); ++i) { if (ssb_htable[i] >= width) { hwidth = i; break; } } } SNPRINTF(cmd, sizeof(cmd), "SH%02d;", hwidth); retval = kenwood_transaction(rig, cmd, NULL, 0); } return retval; } static int ts590_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char cmd[32], ackbuf[32]; int retval; if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (vfo == RIG_VFO_TX || vfo == RIG_VFO_RX) { vfo = vfo_fixup(rig, vfo, CACHE(rig)->split); } retval = RIG_OK; if (!sf_fails) { SNPRINTF(cmd, sizeof(cmd), "SF%d", vfo == RIG_VFO_A ? 0 : 1); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 15); } // if this fails fall back to old method if (retval != RIG_OK || sf_fails) { sf_fails = 1; return kenwood_get_mode(rig, vfo, mode, width); } *mode = ackbuf[14]; if (*mode >= 'A') { *mode = *mode - 'A' + 10; } else { *mode -= '0'; } *mode = kenwood2rmode(*mode, caps->mode_table); // now let's get our widths // CW is different then other modes if (*mode == RIG_MODE_CW || *mode == RIG_MODE_CWR || *mode == RIG_MODE_RTTY || *mode == RIG_MODE_RTTYR) { SNPRINTF(cmd, sizeof(cmd), "FW"); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 6); if (retval == RIG_OK) { int twidth; sscanf(ackbuf, "FW%d", &twidth); *width = twidth; } return retval; } SNPRINTF(cmd, sizeof(cmd), "SH"); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SH command failed: %s\n", __func__, rigerror(retval)); return retval; } int hwidth; sscanf(ackbuf, "SH%d", &hwidth); int lwidth; int shift = 0; SNPRINTF(cmd, sizeof(cmd), "SL"); retval = kenwood_safe_transaction(rig, cmd, ackbuf, sizeof(ackbuf), 4); sscanf(ackbuf, "SL%d", &lwidth); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: SL command failed: %s\n", __func__, rigerror(retval)); return retval; } if (*mode == RIG_MODE_PKTUSB || *mode == RIG_MODE_PKTLSB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; *width = ssb_htable[hwidth]; // we don't do anything with shift yet which will be just the hwidth value shift = ssb_ltable[lwidth]; } else if (*mode == RIG_MODE_AM || *mode == RIG_MODE_PKTAM) { const int am_htable[] = { 2500, 3000, 4000, 5000 }; const int am_ltable[] = { 0, 100, 200, 300 }; *width = am_htable[hwidth] - am_ltable[lwidth]; } else if (*mode == RIG_MODE_SSB || *mode == RIG_MODE_LSB || *mode == RIG_MODE_USB) { const int ssb_htable[] = { 1000, 1200, 1400, 1600, 1800, 2000, 2200, 2400, 2600, 2800, 3000, 3400, 4000, 5000 }; const int ssb_ltable[] = { 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 }; *width = ssb_htable[hwidth] - ssb_ltable[lwidth]; } rig_debug(RIG_DEBUG_VERBOSE, "%s: width=%ld, shift=%d, lwidth=%d, hwidth=%d\n", __func__, *width, shift, lwidth, hwidth); return RIG_OK; } static int ts590_set_ex_menu(RIG *rig, int number, int value_len, int value) { char buf[20]; ENTERFUNC; SNPRINTF(buf, sizeof(buf), "EX%03d0000%0*d", number, value_len, value); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } static int ts590_get_ex_menu(RIG *rig, int number, int value_len, int *value) { int retval; char buf[20]; char ackbuf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(buf, sizeof(buf), "EX%03d0000", number); retval = kenwood_safe_transaction(rig, buf, ackbuf, sizeof(ackbuf), 9 + value_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(ackbuf + 9, "%d", value); RETURNFUNC2(RIG_OK); } static int ts590_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[20]; ENTERFUNC; switch (func) { case RIG_FUNC_MON: SNPRINTF(buf, sizeof(buf), "ML00%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c0", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TUNER: SNPRINTF(buf, sizeof(buf), "AC%c%c0", (status == 0) ? '0' : '1', (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); default: RETURNFUNC(kenwood_set_func(rig, vfo, func, status)); } } static int ts590_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[20]; int retval; ENTERFUNC; switch (func) { case RIG_FUNC_MON: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(buf, "ML%d", &raw_value); *status = (raw_value > 0); break; } case RIG_FUNC_LOCK: retval = kenwood_safe_transaction(rig, "LK", buf, sizeof(buf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[2] != '0'; break; case RIG_FUNC_TUNER: retval = kenwood_safe_transaction(rig, "AC", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[3] != '0' ? 1 : 0; RETURNFUNC(RIG_OK); default: RETURNFUNC(kenwood_get_func(rig, vfo, func, status)); } RETURNFUNC(RIG_OK); } static int ts590_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { struct kenwood_priv_data *priv = STATE(rig)->priv; char levelbuf[16]; int kenwood_val; int result; int cmd; ENTERFUNC; switch (level) { case RIG_LEVEL_USB_AF: kenwood_val = roundl((val.f + .045) * 9); cmd = 65; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 72; } SNPRINTF(levelbuf, sizeof(levelbuf), "EX%03d0000%d", cmd, kenwood_val); break; case RIG_LEVEL_USB_AF_INPUT: kenwood_val = roundl((val.f + .045) * 9); cmd = 64; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 71; } SNPRINTF(levelbuf, sizeof(levelbuf), "EX%03d0000%d", cmd, kenwood_val); break; case RIG_LEVEL_RF: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_AF: RETURNFUNC(kenwood_set_level(rig, vfo, level, val)); case RIG_LEVEL_SQL: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "SQ0%03d", kenwood_val); break; case RIG_LEVEL_AGC: /* Possible values for TS-2000 are 0(=off)-020(=slow) */ switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_SUPERFAST: kenwood_val = 1; break; case RIG_AGC_FAST: kenwood_val = 5; break; case RIG_AGC_MEDIUM: kenwood_val = 10; break; case RIG_AGC_SLOW: kenwood_val = 20; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value", __func__); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%02d", kenwood_val); break; case RIG_LEVEL_MONITOR_GAIN: if (rig->caps->rig_model == RIG_MODEL_TS590S) { kenwood_val = val.f * 9.0f; } else { kenwood_val = val.f * 20.0f; } SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", kenwood_val); break; case RIG_LEVEL_NB: priv->question_mark_response_means_rejected = 1; kenwood_val = val.f * 10.0; SNPRINTF(levelbuf, sizeof(levelbuf), "NL%03d", kenwood_val); break; case RIG_LEVEL_NR: priv->question_mark_response_means_rejected = 1; kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RL%02d", kenwood_val); break; case RIG_LEVEL_PREAMP: if (val.i != 12 && val.i != 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "PA%c", (val.i == 12) ? '1' : '0'); break; case RIG_LEVEL_ATT: if (val.i != 12 && val.i != 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", (val.i == 12) ? 1 : 0); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 300) { RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(ts590_set_ex_menu(rig, 40, 2, (val.i - 300) / 50)); default: RETURNFUNC(kenwood_set_level(rig, vfo, level, val)); } result = kenwood_transaction(rig, levelbuf, NULL, 0); priv->question_mark_response_means_rejected = 0; RETURNFUNC(result); } static int ts590_read_meters(RIG *rig, int *swr, int *comp, int *alc) { int retval; char *cmd = "RM;"; struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 24; ENTERFUNC; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); if (retval != RIG_OK) { RETURNFUNC(retval); } // TS-590 returns values for all meters at the same time, for example: RM10000;RM20000;RM30000; retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to read rig response\n", __func__); RETURNFUNC(retval); } if (retval != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d bytes, got %d in '%s'\n", __func__, expected_len, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } retval = sscanf(ackbuf, "RM1%d;RM2%d;RM3%d;", swr, comp, alc); if (retval != 3) { rig_debug(RIG_DEBUG_ERR, "%s: expected 3 meter values to parse, got %d in '%s'\n", __func__, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } static int ts590_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { struct kenwood_priv_data *priv = STATE(rig)->priv; char ackbuf[50]; size_t ack_len, ack_len_expected; int levelint = 0; int retval; int cmd; ENTERFUNC; switch (level) { case RIG_LEVEL_USB_AF: cmd = 65; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 72; } retval = ts590_get_ex_menu(rig, cmd, 1, &levelint); if (levelint == 9) { val->f = 1.0; } else { val->f = roundl(levelint * 10 / 10.0 + .04) / 10.0; } RETURNFUNC(retval); case RIG_LEVEL_USB_AF_INPUT: cmd = 64; // TS-590S if (rig->caps->rig_model == RIG_MODEL_TS590SG) { cmd = 71; } retval = ts590_get_ex_menu(rig, cmd, 1, &levelint); if (levelint == 9) { val->f = 1.0; } else { val->f = roundl(levelint * 10 / 10.0) / 10.0; } RETURNFUNC(retval); case RIG_LEVEL_AF: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (5 != ack_len) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = levelint / (float) 255; RETURNFUNC(RIG_OK); case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", ackbuf, sizeof(ackbuf)); ack_len_expected = 6; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) levelint / 255.; RETURNFUNC(RIG_OK); case RIG_LEVEL_AGC: priv->question_mark_response_means_rejected = 1; retval = kenwood_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); priv->question_mark_response_means_rejected = 0; ack_len_expected = 4; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } if (levelint == 0) { val->i = RIG_AGC_OFF; } else if (levelint <= 1) { val->i = RIG_AGC_SUPERFAST; } else if (levelint <= 5) { val->i = RIG_AGC_FAST; } else if (levelint <= 10) { val->i = RIG_AGC_MEDIUM; } else { val->i = RIG_AGC_SLOW; } RETURNFUNC(RIG_OK); case RIG_LEVEL_STRENGTH: if (CACHE(rig)->ptt != RIG_PTT_OFF) { val->i = -9 * 6; break; } RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_MONITOR_GAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "ML%d", &raw_value); if (rig->caps->rig_model == RIG_MODEL_TS590S) { val->f = (float) raw_value / 9.0f; } else { val->f = (float) raw_value / 20.0f; } break; } case RIG_LEVEL_NB: { int raw_value; priv->question_mark_response_means_rejected = 1; retval = kenwood_safe_transaction(rig, "NL", ackbuf, sizeof(ackbuf), 5); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NL%d", &raw_value); val->f = (float) raw_value / 10.0f; break; } case RIG_LEVEL_NR: { int raw_value; priv->question_mark_response_means_rejected = 1; retval = kenwood_safe_transaction(rig, "RL", ackbuf, sizeof(ackbuf), 4); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RL%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[2] == '1' ? 12 : 0; break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[3] == '1' ? 12 : 0; break; case RIG_LEVEL_SWR: case RIG_LEVEL_COMP_METER: case RIG_LEVEL_ALC: { int swr; int comp; int alc; retval = ts590_read_meters(rig, &swr, &comp, &alc); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(swr, &rig->caps->swr_cal); } else { val->f = (float) swr / 2.0f; } break; case RIG_LEVEL_COMP_METER: val->f = (float) comp; // Maximum value is 30 break; case RIG_LEVEL_ALC: // Maximum value is 30, so have the max at 5 just to be on the range where other rigs report ALC val->f = (float) alc / 6.0f; break; default: RETURNFUNC(-RIG_ENAVAIL); } break; } case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: { static cal_table_t power_meter = { 7, { { 0, 0}, { 3, 5}, { 6, 10}, { 8, 15}, {12, 25}, { 17, 50}, { 30, 100} } }; int raw_value; if (CACHE(rig)->ptt == RIG_PTT_OFF) { val->f = 0; break; } retval = kenwood_safe_transaction(rig, "SM0", ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "SM0%d", &raw_value); // val->f = (float) raw_value / 30.0f; if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f = roundf(rig_raw2val(raw_value, &power_meter)); if (val->f < 10) { val->f = roundf(rig_raw2val(raw_value, &power_meter) * 10.0) / 10.0; } } break; } case RIG_LEVEL_CWPITCH: { int raw_value; retval = ts590_get_ex_menu(rig, 40, 2, &raw_value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = 300 + raw_value * 50; break; } default: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); } RETURNFUNC(RIG_OK); } static int ts590_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[20]; int retval; int rit_enabled; int xit_enabled; ENTERFUNC; if (rit < -9999 || rit > 9999) { RETURNFUNC(-RIG_EINVAL); } // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (rit == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(buf, sizeof(buf), "R%c%05d", (rit > 0) ? 'U' : 'D', abs((int) rit)); retval = kenwood_transaction(rig, buf, NULL, 0); RETURNFUNC(retval); } static int ts590_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(buf, &priv->info[18], 5); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } static int ts590_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { char cmdbuf[20]; int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "NR%d", status ? 2 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts590_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: { int value; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "NR", ackbuf, sizeof(ackbuf), 3); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NR%d", &value); *status = (value == 2) ? 1 : 0; break; } default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts590_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 31, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 37, 1, val.i); } break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 30, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 36, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 25, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 31, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 26, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 32, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 27, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 33, 1, val.i); } break; case TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 28, 1, val.i); } else { retval = ts590_set_ex_menu(rig, 34, 1, val.i); } break; case TOK_LEVEL_BEEP_VOLUME: if (val.f < 0 || val.f > 20) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 3, 2, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 5, 2, (int) val.f); } break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (val.f < 0 || val.f > 20) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 4, 2, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 6, 2, (int) val.f); } break; case TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 66, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 73, 1, (int) val.f); } break; case TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 67, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 74, 1, (int) val.f); } break; case TOK_LEVEL_USB_AUDIO_INPUT_LEVEL: // keep for backwards compatibility if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 64, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 71, 1, (int) val.f); } break; case TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL: // keep for backwards compatibility if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_set_ex_menu(rig, 65, 1, (int) val.f); } else { retval = ts590_set_ex_menu(rig, 72, 1, (int) val.f); } break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts590_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; int value; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 31, 1, &value); } else { retval = ts590_get_ex_menu(rig, 37, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 30, 1, &value); } else { retval = ts590_get_ex_menu(rig, 36, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_AM_LOW_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 25, 1, &value); } else { retval = ts590_get_ex_menu(rig, 31, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_AM_HIGH_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 26, 1, &value); } else { retval = ts590_get_ex_menu(rig, 32, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_DATA_LOW_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 27, 1, &value); } else { retval = ts590_get_ex_menu(rig, 33, 1, &value); } val->i = value; break; case TOK_LEVEL_DSP_TX_SSB_DATA_HIGH_CUT_FILTER: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 28, 1, &value); } else { retval = ts590_get_ex_menu(rig, 34, 1, &value); } val->i = value; break; case TOK_LEVEL_BEEP_VOLUME: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 3, 2, &value); } else { retval = ts590_get_ex_menu(rig, 5, 2, &value); } val->f = value; break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 4, 2, &value); } else { retval = ts590_get_ex_menu(rig, 6, 2, &value); } val->f = value; break; case TOK_LEVEL_ACC2_AUDIO_INPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 66, 1, &value); } else { retval = ts590_get_ex_menu(rig, 73, 1, &value); } val->f = value; break; case TOK_LEVEL_ACC2_AUDIO_OUTPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 67, 1, &value); } else { retval = ts590_get_ex_menu(rig, 74, 1, &value); } val->f = value; break; case TOK_LEVEL_USB_AUDIO_INPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 64, 1, &value); } else { retval = ts590_get_ex_menu(rig, 71, 1, &value); } val->f = value; break; case TOK_LEVEL_USB_AUDIO_OUTPUT_LEVEL: if (rig->caps->rig_model == RIG_MODEL_TS590S) { retval = ts590_get_ex_menu(rig, 65, 1, &value); } else { retval = ts590_get_ex_menu(rig, 72, 1, &value); } val->f = value; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static struct kenwood_filter_width ts590_filter_width[] = { { RIG_MODE_CW | RIG_MODE_CWR, 50, 50 }, { RIG_MODE_CW | RIG_MODE_CWR, 80, 80 }, { RIG_MODE_CW | RIG_MODE_CWR, 100, 100 }, { RIG_MODE_CW | RIG_MODE_CWR, 150, 150 }, { RIG_MODE_CW | RIG_MODE_CWR, 200, 200 }, { RIG_MODE_CW | RIG_MODE_CWR, 250, 250 }, { RIG_MODE_CW | RIG_MODE_CWR, 300, 300 }, { RIG_MODE_CW | RIG_MODE_CWR, 400, 400 }, { RIG_MODE_CW | RIG_MODE_CWR, 500, 500 }, { RIG_MODE_CW | RIG_MODE_CWR, 600, 600 }, { RIG_MODE_CW | RIG_MODE_CWR, 1000, 1000 }, { RIG_MODE_CW | RIG_MODE_CWR, 1500, 1500 }, { RIG_MODE_CW | RIG_MODE_CWR, 2000, 2000 }, { RIG_MODE_CW | RIG_MODE_CWR, 2500, 2500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 250, 250 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 500, 500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1000, 1000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1500, 1500 }, { RIG_MODE_SSB, 0, 2400 }, { RIG_MODE_FM, 0, 12000 }, { RIG_MODE_AM, 0, 6000 }, { RIG_MODE_NONE, -1, -1 }, }; static struct kenwood_slope_filter ts590_slope_filter_high[] = { { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 1000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 1200 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 1400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 1600 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 1800 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 2000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 2200 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 2400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 2600 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 2800 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 3000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 3400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 12, 4000 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 13, 5000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 0, 2500 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 1, 3000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 2, 4000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 3, 5000 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_slope_filter ts590_slope_filter_low[] = { { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 0 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 50 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 100 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 200 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 300 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 400 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 500 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 600 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 700 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 800 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 900 }, { RIG_MODE_SSB | RIG_MODE_PKTSSB | RIG_MODE_FM | RIG_MODE_PKTFM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 1000 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 0, 0 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 1, 100 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 2, 200 }, { RIG_MODE_AM | RIG_MODE_PKTAM, 0, 3, 300 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_priv_caps ts590_priv_caps = { .cmdtrm = EOM_KEN, .filter_width = ts590_filter_width, .slope_filter_high = ts590_slope_filter_high, .slope_filter_low = ts590_slope_filter_low, .tone_table_base = 0, }; /** * TS-590 rig capabilities */ struct rig_caps ts590_caps = { RIG_MODEL(RIG_MODEL_TS590S), .model_name = "TS-590S", .mfg_name = "Kenwood", .version = BACKEND_VER ".18", .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 = 4800, .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, // mode command is not vfo targetable .targetable_vfo = RIG_TARGETABLE_FREQ, .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), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1810), kHz(1850), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), kHz(3800), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), kHz(3800), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(30), Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), MHz(4) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_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 | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_RF #define NO_LVL_AF #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #define NO_LVL_VOXDELAY #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_RF #undef NO_LVL_AF #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT #undef NO_LVL_VOXDELAY #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.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 }; /** * BG2FX FX-4C/FX-4CR rig capabilities * Supposed to be 590S compatible * Separate entry allows for customization */ struct rig_caps fx4_caps = { RIG_MODEL(RIG_MODEL_FX4), .model_name = "FX4/C/CR/L", .mfg_name = "BG2FX", .version = BACKEND_VER ".11", .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, // mode command is not vfo targetable .targetable_vfo = RIG_TARGETABLE_FREQ, .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 = { #define NO_LVL_RF #define NO_LVL_AF #define NO_LVL_VOXDELAY #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_RF #undef NO_LVL_AF #undef NO_LVL_VOXDELAY #undef NO_LVL_CWPITCH #undef NO_LVL_BKIND_LYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [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 / 255.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, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .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 */ struct rig_caps ts590sg_caps = { RIG_MODEL(RIG_MODEL_TS590SG), .model_name = "TS-590SG", .mfg_name = "Kenwood", .version = BACKEND_VER ".12", .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 = 4800, .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, // mode command is not vfo targetable .targetable_vfo = RIG_TARGETABLE_FREQ, .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 }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(30), Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1810), kHz(1850), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), kHz(3800), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), kHz(3800), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7200), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(30), Hz(59999999), TS590_ALL_MODES, -1, -1, TS590_VFO, TS590_ANTS}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(3500), MHz(4) - 1, TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(5250), kHz(5450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(7), kHz(7300), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(10100), kHz(10150), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(14), kHz(14350), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(18068), kHz(18168), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(21), kHz(21450), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {kHz(24890), kHz(24990), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(28), kHz(29700), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_OTHER_TX_MODES, 5000, 100000, TS590_VFO, TS590_ANTS}, {MHz(50), kHz(52000), TS590_AM_TX_MODES, 5000, 25000, TS590_VFO, TS590_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 | RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_RF #define NO_LVL_AF #define NO_LVL_USB_AF #define NO_LVL_USB_AF_INPUT #define NO_LVL_VOXDELAY #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_RF #undef NO_LVL_AF #undef NO_LVL_USB_AF #undef NO_LVL_USB_AF_INPUT #undef NO_LVL_VOXDELAY #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 255.0f } }, [LVL_USB_AF] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.0f } }, [LVL_USB_AF_INPUT] = { .min = { .f = 0 }, .max = { .f = 1.0 }, .step = { .f = 1.0f / 10.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 }; hamlib-4.6.2/rigs/kenwood/thg71.c0000644000175000017500000003463514752216205013427 00000000000000/* * Hamlib Kenwood backend - TH-G71 description * Copyright (c) 2003-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include "kenwood.h" #include "th.h" #if 1 #define RIG_ASSERT(x) if (!(x)) { rig_debug(RIG_DEBUG_ERR, "Assertion failed on line %i\n",__LINE__); abort(); } #else #define RIG_ASSERT(x) #endif #define THG71_VFO (RIG_VFO_A) #define THG71_MODES (RIG_MODE_FM) #define THG71_FUNC_ALL (\ RIG_FUNC_TBURST \ ) #define THG71_LEVEL_ALL (\ RIG_LEVEL_RAWSTR| \ RIG_LEVEL_SQL| \ RIG_LEVEL_RFPOWER\ ) #ifndef RIG_TONEMAX #define RIG_TONEMAX 38 #endif #define RIG_VFO_A_OP (RIG_OP_UP|RIG_OP_DOWN) #define ACKBUF_LEN 128 static rmode_t thg71_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_AM, }; static struct kenwood_priv_caps thg71_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thg71_mode_table, }; /* thg71 procs */ static int thg71_open(RIG *rig); static int thg71_decode_event(RIG *rig); static int thg71_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); static int thg71_set_vfo(RIG *rig, vfo_t vfo); static int thg71_get_vfo(RIG *rig, vfo_t *vfo); static int thg71_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); /* * th-g71 rig capabilities. * * http://www.iw5edi.com/ham-radio/files/TH-G71_Serial_Protocol.pdf */ struct rig_caps thg71_caps = { RIG_MODEL(RIG_MODEL_THG71), .model_name = "TH-G71", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 1, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_set_func = THG71_FUNC_ALL, .has_get_level = THG71_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THG71_LEVEL_ALL), .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = RIG_VFO_A_OP, .targetable_vfo = RIG_TARGETABLE_NONE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 6, .chan_list = { { 1, 199, RIG_MTYPE_MEM, {TH_CHANNEL_CAPS}}, /* normal MEM */ { 200, 209, RIG_MTYPE_EDGE, {TH_CHANNEL_CAPS}}, /* L MEM */ { 210, 219, RIG_MTYPE_EDGE, {TH_CHANNEL_CAPS}}, /* U MEM */ { 220, 220, RIG_MTYPE_PRIO, {TH_CHANNEL_CAPS}}, /* Priority */ { 221, 222, RIG_MTYPE_CALL, {TH_CHANNEL_CAPS}}, /* Call 0/1 */ { 223, 231, RIG_MTYPE_BAND, {TH_CHANNEL_CAPS}}, /* Band VFO */ RIG_CHAN_END, }, /* no rx/tx_range_list */ .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {MHz(118), MHz(174), THG71_MODES, -1, -1, THG71_VFO}, {MHz(400), MHz(470), THG71_MODES, -1, -1, THG71_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {MHz(144), MHz(148), THG71_MODES, W(0.05), W(5), THG71_VFO}, {MHz(430), MHz(450), THG71_MODES, W(0.05), W(5), THG71_VFO}, RIG_FRNG_END, }, /* computed in thg71_open */ .tuning_steps = { {RIG_MODE_FM, kHz(5)}, {RIG_MODE_FM, kHz(6.25)}, {RIG_MODE_FM, kHz(10)}, {RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_FM, kHz(15)}, {RIG_MODE_FM, kHz(20)}, {RIG_MODE_FM, kHz(25)}, {RIG_MODE_FM, kHz(30)}, {RIG_MODE_FM, kHz(50)}, {RIG_MODE_FM, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_AM, kHz(9)}, RIG_FLT_END, }, .str_cal = { 3, { { 0, -60 }, {1, -30 }, {5, -13}}}, /* guessed from technical manual */ .priv = (void *)& thg71_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = thg71_open, .rig_close = kenwood_close, .set_freq = th_set_freq, .get_freq = th_get_freq, .get_mode = thg71_get_mode, .set_vfo = thg71_set_vfo, .get_vfo = thg71_get_vfo, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_trn = th_set_trn, .get_trn = th_get_trn, .set_func = thg71_set_func, .get_level = th_get_level, .set_level = th_set_level, .get_info = th_get_info, .vfo_op = th_vfo_op, .set_ptt = th_set_ptt, .get_dcd = th_get_dcd, .decode_event = thg71_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* --------------------------------------------------------------------- */ int thg71_decode_event(RIG *rig) { char asyncbuf[ACKBUF_LEN]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = kenwood_transaction(rig, NULL, asyncbuf, sizeof(asyncbuf)); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_TRACE, "%s: Decoding message\n", __func__); if (asyncbuf[0] == 'B' && asyncbuf[1] == 'U' && asyncbuf[2] == 'F') { freq_t freq, offset; int step, shift, rev, tone, ctcss, tonefq, ctcssfq; retval = sscanf(asyncbuf, "BUF 0,%"SCNfreq",%d,%d,%d,%d,%d,,%d,,%d,%"SCNfreq, &freq, &step, &shift, &rev, &tone, &ctcss, &tonefq, &ctcssfq, &offset); if (retval != 11) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BUF message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } rig_debug(RIG_DEBUG_TRACE, "%s: Buffer (freq %"PRIfreq" Hz)\n", __func__, freq); /* Callback execution */ if (rig->callbacks.vfo_event) { rig->callbacks.vfo_event(rig, RIG_VFO_A, rig->callbacks.vfo_arg); } if (rig->callbacks.freq_event) { rig->callbacks.freq_event(rig, RIG_VFO_A, freq, rig->callbacks.freq_arg); } /* if (rig->callbacks.mode_event) { rig->callbacks.mode_event(rig, RIG_VFO_A, mode, RIG_PASSBAND_NORMAL, rig->callbacks.mode_arg); } */ /* --------------------------------------------------------------------- */ } else if (asyncbuf[0] == 'S' && asyncbuf[1] == 'M') { int lev; retval = sscanf(asyncbuf, "SM 0,%d", &lev); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected SM message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } rig_debug(RIG_DEBUG_TRACE, "%s: Signal strength event - signal = %.3f\n", __func__, (float)(lev / 5.0)); /* Callback execution */ #if STILLHAVETOADDCALLBACK if (rig->callbacks.strength_event) rig->callbacks.strength_event(rig, RIG_VFO_0, (float)(lev / 5.0), rig->callbacks.strength_arg); #endif /* --------------------------------------------------------------------- */ } else if (asyncbuf[0] == 'B' && asyncbuf[1] == 'Y') { int busy; retval = sscanf(asyncbuf, "BY 0,%d", &busy); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected BY message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } rig_debug(RIG_DEBUG_TRACE, "%s: Busy event - status = '%s'\n", __func__, (busy == 0) ? "OFF" : "ON"); return -RIG_ENIMPL; /* This event does not have a callback. */ /* --------------------------------------------------------------------- */ } else if (asyncbuf[0] == 'V' && asyncbuf[1] == 'M' && asyncbuf[2] == 'C') { vfo_t bandmode; retval = sscanf(asyncbuf, "VMC 0,%u", &bandmode); if (retval != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VMC message '%s'\n", __func__, asyncbuf); return -RIG_ERJCTED; } switch (bandmode) { case 0: bandmode = RIG_VFO_VFO; break; case 2: bandmode = RIG_VFO_MEM; break; /* case 3: bandmode = RIG_VFO_CALL; break; */ default: bandmode = RIG_VFO_CURR; break; } rig_debug(RIG_DEBUG_TRACE, "%s: Mode of Band event - %u\n", __func__, bandmode); /* TODO: This event does not have a callback! */ return -RIG_ENIMPL; /* --------------------------------------------------------------------- */ } else { rig_debug(RIG_DEBUG_ERR, "%s: Unsupported transceive cmd '%s'\n", __func__, asyncbuf); return -RIG_ENIMPL; } return RIG_OK; } /* --------------------------------------------------------------------- */ int thg71_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char ackbuf[ACKBUF_LEN]; int retval; int step; freq_t freq; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_CURR: break; case RIG_VFO_A: break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } /* try to guess from frequency */ retval = kenwood_transaction(rig, "FQ", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } sscanf(ackbuf, "FQ %"SCNfreq",%d", &freq, &step); if (freq < MHz(136)) { *mode = RIG_MODE_AM; *width = kHz(9); } else { *mode = RIG_MODE_FM; *width = kHz(12); } return RIG_OK; } /* --------------------------------------------------------------------- */ int thg71_set_vfo(RIG *rig, vfo_t vfo) { char vfobuf[16]; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); switch (vfo) { case RIG_VFO_A: case RIG_VFO_VFO: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,0"); break; case RIG_VFO_MEM: SNPRINTF(vfobuf, sizeof(vfobuf), "VMC 0,2"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EVFO; } retval = kenwood_transaction(rig, vfobuf, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } /* --------------------------------------------------------------------- */ int thg71_get_vfo(RIG *rig, vfo_t *vfo) { char ackbuf[ACKBUF_LEN]; int retval; int vch; retval = kenwood_transaction(rig, "VMC 0", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } sscanf(ackbuf, "VMC 0,%d", &vch); switch (vch) { case 0: *vfo = RIG_VFO_A; break; case 1: case 2: *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unsupported VFO %s\n", __func__, rig_strvfo(*vfo)); return -RIG_EVFO; } return RIG_OK; } /* --------------------------------------------------------------------- */ int thg71_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { if (func != RIG_FUNC_TBURST) { return -RIG_EINVAL; } if (status == 1) { int retval = kenwood_transaction(rig, "TT", NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } if (status == 0) { return rig_set_ptt(rig, vfo, RIG_PTT_OFF); } return -RIG_EINVAL; } /* --------------------------------------------------------------------- */ int thg71_open(RIG *rig) { char ackbuf[ACKBUF_LEN]; int retval, i; const freq_range_t frend = RIG_FRNG_END; struct rig_state *rs = STATE(rig); /* this will check the model id */ retval = kenwood_open(rig); if (retval != RIG_OK) { return retval; } /* fill state.rx/tx range_list */ retval = kenwood_transaction(rig, "FL", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } strtok(ackbuf, " "); for (i = 0; i < HAMLIB_FRQRANGESIZ - 1; i++) { freq_range_t frng; char *strl, *stru; strl = strtok(NULL, ","); stru = strtok(NULL, ","); if (strl == NULL && stru == NULL) { break; } frng.startf = MHz(atoi(strl)); frng.endf = MHz(atoi(stru)); frng.vfo = RIG_VFO_A; frng.ant = 0; if (frng.endf <= MHz(135)) { frng.modes = RIG_MODE_AM; } else { frng.modes = RIG_MODE_FM; } frng.high_power = -1; frng.low_power = -1; frng.label = ""; rs->rx_range_list[i] = frng; if (frng.startf > MHz(200)) { frng.high_power = mW(5500); } else { frng.high_power = mW(6000); } frng.low_power = mW(50); rs->tx_range_list[i] = frng; } rs->rx_range_list[i] = frend; rs->tx_range_list[i] = frend; rs->vfo_list = RIG_VFO_A | RIG_VFO_MEM ; return RIG_OK; } hamlib-4.6.2/rigs/kenwood/ts690.c0000644000175000017500000001561714752216205013361 00000000000000/* * Hamlib Kenwood backend - TS690 description * Copyright (c) 2000-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "bandplan.h" #include "kenwood.h" extern int ts450_open(RIG *rig); #define TS690_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_CW|RIG_MODE_RTTYR|RIG_MODE_CWR|RIG_MODE_SSB) #define TS690_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_CWR) #define TS690_AM_TX_MODES RIG_MODE_AM /* FIXME: TBC */ #define TS690_FUNC_ALL (RIG_FUNC_LOCK|RIG_FUNC_AIP|RIG_FUNC_TONE) #define TS690_LEVEL_ALL (RIG_LEVEL_STRENGTH|RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_ALC) #define TS690_PARMS (RIG_PARM_ANN) /* optional */ #define TS690_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS690_SCAN_OPS (RIG_SCAN_VFO) #define TS690_VFO (RIG_VFO_A|RIG_VFO_B) #define TS690_ANTS (0) #define TS690_CHANNEL_CAPS { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .funcs=RIG_FUNC_TONE, \ .flags=RIG_CHFLAG_SKIP \ } static struct kenwood_priv_caps ts690_priv_caps = { .cmdtrm = EOM_KEN, }; /* * ts690 rig capabilities. * written from specs: * http://www.qsl.net/sm7vhs/radio/kenwood/ts690/specs.htm * * TODO: protocol to be checked with manual! * - how to set_split in vfo mode? * - ... */ struct rig_caps ts690s_caps = { RIG_MODEL(RIG_MODEL_TS690S), .model_name = "TS-690S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 100, .timeout = 1000, .retry = 10, .has_get_func = TS690_FUNC_ALL, .has_set_func = TS690_FUNC_ALL, .has_get_level = TS690_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS690_LEVEL_ALL), .has_get_parm = TS690_PARMS, .has_set_parm = RIG_LEVEL_SET(TS690_PARMS), /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(2.2), .max_xit = kHz(2.2), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = TS690_VFO_OPS, .scan_ops = TS690_SCAN_OPS, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS690_CHANNEL_CAPS }, /* TBC */ { 90, 99, RIG_MTYPE_EDGE, TS690_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS690_ALL_MODES, -1, -1, TS690_VFO}, {MHz(50), MHz(54), TS690_ALL_MODES, -1, -1, TS690_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS690_OTHER_TX_MODES, W(5), W(100), TS690_VFO, TS690_ANTS), FRQ_RNG_HF(1, TS690_AM_TX_MODES, W(4), W(40), TS690_VFO, TS690_ANTS), /* AM class */ FRQ_RNG_6m(1, TS690_OTHER_TX_MODES, W(2.5), W(50), TS690_VFO, TS690_ANTS), FRQ_RNG_6m(1, TS690_AM_TX_MODES, W(2), W(20), TS690_VFO, TS690_ANTS), /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TS690_ALL_MODES, -1, -1, TS690_VFO}, {MHz(50), MHz(54), TS690_ALL_MODES, -1, -1, TS690_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS690_OTHER_TX_MODES, W(5), W(100), TS690_VFO, TS690_ANTS), FRQ_RNG_HF(2, TS690_AM_TX_MODES, W(4), W(40), TS690_VFO, TS690_ANTS), /* AM class */ FRQ_RNG_6m(2, TS690_OTHER_TX_MODES, W(2.5), W(50), TS690_VFO, TS690_ANTS), FRQ_RNG_6m(2, TS690_AM_TX_MODES, W(2), W(20), TS690_VFO, TS690_ANTS), /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TS690_ALL_MODES, 1}, {TS690_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, Hz(500)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR | RIG_MODE_AM, kHz(12)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY | RIG_MODE_CWR | RIG_MODE_RTTYR, kHz(6)}, RIG_FLT_END, }, .priv = (void *)& ts690_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = ts450_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .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_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .reset = kenwood_reset, .scan = kenwood_scan, .get_channel = kenwood_get_channel, .set_channel = kenwood_set_channel, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/README.flex0000644000175000017500000000335314752216205014137 00000000000000FlexRadio 6xxx series notes and Hamlib errata by Steve Conklin, AI4QR. Commands as documented from Flex ----------Kenwood Command Set---------- FA Slice receiver A frequency. FB Slice receiver B frequency. FR Receive VFO FT Transmit VFO IF Transceiver Status KS Keying speed MD DSP Mode RX Set receive (TX off) SH Set DSP filter high frequency SL Set DSP filter low frequency TX Set transmit (TX on) ----------FlexRadio Command Set---------- ZZFA Slice receiver A frequency ZZFB Slice receiver B frequency ZZFI Slice Receiver A DSP filter ZZFJ Slice Receiver B DSP filter ZZIF Transceiver Status ZZMD Slice receiver A DSP Mode ZZME Slice receiver B DSP Mode ZZSW Set slice Transmit flag (RX A or RX B) ZZTX Set MOX (on/off) ================================================ rigctl commands used to test operation (freq set and read) f F 14100000 F 14070000 also test to see if RX and TX can be set out of band (mode set and read with passband) m M USB 5 [Should set to USB and 1.6K] M USB 20000 [should set to USb and 4K] also test other modes (vfo set and read) v V VFOB [opens with a 5K split] (set and get split freq) i I 14078000 [ Even if split is turned off, this sets VFOB] (split set and read) NOTE: When split off, TX VFO is always A s [ shows split and VFOA is TX] S 1 VFOA s S 1 VFOB (keying speed) l KEYSPD L KEYSPD 25 l KEYSPD L KEYSPD 10 l KEYSPD (filter edges) l SLOPE_HIGH l SLOPE_LOW === Supported: case RIG_LEVEL_KEYSPD: 'KS' case RIG_LEVEL_SLOPE_HIGH: 'SH' needs list of frequencies case RIG_LEVEL_SLOPE_LOW: 'SL' Not supported: case RIG_LEVEL_RFPOWER: 'PC' case RIG_LEVEL_AF: 'AG' case RIG_LEVEL_RF: 'RG' case RIG_LEVEL_SQL: 'SQ' case RIG_LEVEL_AGC: 'GT' case RIG_LEVEL_ATT: 'RA' case RIG_LEVEL_PREAMP: 'PA' case RIG_LEVEL_CWPITCH: 'PT' hamlib-4.6.2/rigs/kenwood/ts790.c0000644000175000017500000001517214752216205013356 00000000000000/* * Hamlib Kenwood backend - TS-790 description * Copyright (c) 2000-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "kenwood.h" #define TS790_ALL_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM) #define TS790_HI_MODES (RIG_MODE_CW|RIG_MODE_FM) #define TS790_LO_MODES (RIG_MODE_SSB) /* func and levels to be checked */ #define TS790_FUNC_ALL (RIG_FUNC_TSQL|RIG_FUNC_LOCK|RIG_FUNC_MUTE) #define TS790_LEVEL_ALL (RIG_LEVEL_STRENGTH) #define TS790_VFO (RIG_VFO_A|RIG_VFO_B) #define TS790_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS790_SCAN_OP (RIG_SCAN_VFO) #define TS790_CHANNEL_CAPS \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .flags=RIG_CHFLAG_SKIP, \ .ctcss_tone=1 /* * Function definitions below */ static struct kenwood_priv_caps ts790_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; /* * TS790 A/E rig capabilities. * Interface provided by optional IF-232C * * TODO: get_ts, ctcss_sql, set_rptr_shift * * part of infos comes from http://www.kenwood.net/ */ struct rig_caps ts790_caps = { RIG_MODEL(RIG_MODEL_TS790), .model_name = "TS-790", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 0, .timeout = 1000, .retry = 10, .has_get_func = TS790_FUNC_ALL, .has_set_func = TS790_FUNC_ALL, .has_get_level = TS790_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS790_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .vfo_ops = TS790_VFO_OP, .scan_ops = TS790_SCAN_OP, .ctcss_list = kenwood38_ctcss_list, .preamp = { RIG_DBLST_END, }, .attenuator = { /* 12, */ RIG_DBLST_END, }, .max_rit = kHz(9.9), /* this is for FM, SSB/CW is 1.9kHz */ .max_xit = 0, .max_ifshift = 0, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, // No AGC levels .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 59, RIG_MTYPE_MEM, { TS790_CHANNEL_CAPS } }, RIG_CHAN_END, }, .rx_range_list1 = { {MHz(144), MHz(146), TS790_ALL_MODES, -1, -1, TS790_VFO}, {MHz(430), MHz(440), TS790_ALL_MODES, -1, -1, TS790_VFO}, #if 0 /* 23 cm option */ {MHz(1240), MHz(1300), TS790_ALL_MODES, -1, -1, TS790_VFO}, #endif RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(144), MHz(146), TS790_LO_MODES, W(5), W(35), TS790_VFO}, {MHz(144), MHz(146), TS790_HI_MODES, W(5), W(45), TS790_VFO}, {MHz(430), MHz(440), TS790_LO_MODES, W(5), W(30), TS790_VFO}, {MHz(430), MHz(440), TS790_HI_MODES, W(5), W(40), TS790_VFO}, #if 0 {MHz(1240), MHz(1300), TS790_ALL_MODES, W(5), W(10), TS790_VFO}, #endif RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {MHz(144), MHz(148), TS790_ALL_MODES, -1, -1, TS790_VFO}, {MHz(430), MHz(450), TS790_ALL_MODES, -1, -1, TS790_VFO}, #if 0 {MHz(1240), MHz(1300), TS790_ALL_MODES, -1, -1, TS790_VFO}, #endif RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(144), MHz(148), TS790_LO_MODES, W(5), W(35), TS790_VFO}, {MHz(144), MHz(148), TS790_HI_MODES, W(5), W(45), TS790_VFO}, {MHz(430), MHz(450), TS790_LO_MODES, W(5), W(30), TS790_VFO}, {MHz(430), MHz(450), TS790_HI_MODES, W(5), W(40), TS790_VFO}, #if 0 {MHz(1240), MHz(1300), TS790_ALL_MODES, W(5), W(10), TS790_VFO}, #endif RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS790_ALL_MODES, 50}, {TS790_ALL_MODES, 100}, {TS790_ALL_MODES, kHz(1)}, {TS790_ALL_MODES, kHz(5)}, {TS790_ALL_MODES, kHz(9)}, {TS790_ALL_MODES, kHz(10)}, {TS790_ALL_MODES, 12500}, {TS790_ALL_MODES, kHz(20)}, {TS790_ALL_MODES, kHz(25)}, {TS790_ALL_MODES, kHz(100)}, {TS790_ALL_MODES, MHz(1)}, {TS790_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_CWR, kHz(2.1)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts790_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .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, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .set_channel = kenwood_set_channel, .get_channel = kenwood_get_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .get_info = kenwood_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/tx500.c0000644000175000017500000010544314752216205013351 00000000000000/* * Hamlib Lab599 backend - TX-500 description * Copyright (c) 2021 by Michael Black W9MDB - borrowed from ts2000.c * Copyright (c) 2000-2011 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "kenwood.h" #define TX500_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TX500_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TX500_AM_TX_MODES RIG_MODE_AM #define TX500_FUNC_ALL (RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_BC|RIG_FUNC_NB|RIG_FUNC_NR|RIG_FUNC_ANF|RIG_FUNC_COMP|RIG_FUNC_RIT|RIG_FUNC_XIT) #define TX500_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_CWPITCH|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_COMP|RIG_LEVEL_AGC|RIG_LEVEL_BKINDL|RIG_LEVEL_METER|RIG_LEVEL_VOXGAIN|RIG_LEVEL_ANTIVOX|RIG_LEVEL_RAWSTR|RIG_LEVEL_STRENGTH) #define TX500_MAINVFO (RIG_VFO_A|RIG_VFO_B) #define TX500_SUBVFO (RIG_VFO_C) #define TX500_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN) #define TX500_SCAN_OP (RIG_SCAN_VFO) #define TX500_ANTS (RIG_ANT_1|RIG_ANT_2) #define TX500_STR_CAL {9, {\ {0x00, -54},\ {0x03, -48},\ {0x06, -36},\ {0x09, -24},\ {0x0C, -12},\ {0x0F, 0},\ {0x14, 20},\ {0x19, 40},\ {0x1E, 60}}\ } /* prototypes */ static int ts2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); static int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); static int ts2000_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); /* * 38 CTCSS sub-audible tones + 1750 tone */ tone_t tx500_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 17500, 0, }; /* * 103 available DCS codes */ tone_t tx500_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0, }; static struct kenwood_priv_caps tx500_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, /* TS-2000 compatible ??? */ }; /* memory capabilities */ #define TX500_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .dcs_code=1, \ .dcs_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* * TX-500 rig capabilities. * */ struct rig_caps tx500_caps = { RIG_MODEL(RIG_MODEL_LAB599_TX500), .model_name = "TX-500", .mfg_name = "Lab599", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, /* ms */ .timeout = 500, .retry = 10, .has_get_func = TX500_FUNC_ALL, .has_set_func = TX500_FUNC_ALL, .has_get_level = TX500_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TX500_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, /* FIXME: granularity */ .parm_gran = {}, .vfo_ops = TX500_VFO_OP, .scan_ops = TX500_SCAN_OP, .ctcss_list = tx500_ctcss_list, .dcs_list = tx500_dcs_list, .preamp = { 20, RIG_DBLST_END, }, /* FIXME: real preamp? */ .attenuator = { 20, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TX500_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TX500_ALL_MODES, -1, -1, TX500_MAINVFO, TX500_ANTS}, {MHz(144), MHz(146), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(430), MHz(440), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(144), MHz(146), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, {MHz(430), MHz(440), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(1830), kHz(1850), TX500_AM_TX_MODES, 2000, 25000, TX500_MAINVFO, TX500_ANTS}, {kHz(3500), kHz(3800), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(3500), kHz(3800), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7100), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7100), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(50.2), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(50.2), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(144), MHz(146), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO}, {MHz(144), MHz(146), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO}, {MHz(430), MHz(440), TX500_OTHER_TX_MODES, W(5), W(50), TX500_MAINVFO}, {MHz(430), MHz(440), TX500_AM_TX_MODES, W(5), W(12.5), TX500_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TX500_ALL_MODES, -1, -1, TX500_MAINVFO, TX500_ANTS}, {MHz(142), MHz(152), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(420), MHz(450), TX500_ALL_MODES, -1, -1, TX500_MAINVFO}, {MHz(118), MHz(174), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, {MHz(220), MHz(512), TX500_ALL_MODES, -1, -1, TX500_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(1800), MHz(2), TX500_AM_TX_MODES, 2000, 25000, TX500_MAINVFO, TX500_ANTS}, {kHz(3500), MHz(4), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(3500), MHz(4), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7300), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(7), kHz(7300), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(10.1), MHz(10.15), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(14), kHz(14350), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(18068), kHz(18168), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(21), kHz(21450), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {kHz(24890), kHz(24990), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(28), kHz(29700), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(54), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO, TX500_ANTS}, {MHz(50), MHz(54), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO, TX500_ANTS}, {MHz(144), MHz(148), TX500_OTHER_TX_MODES, W(5), W(100), TX500_MAINVFO}, {MHz(144), MHz(148), TX500_AM_TX_MODES, W(5), W(25), TX500_MAINVFO}, {MHz(430), MHz(450), TX500_OTHER_TX_MODES, W(5), W(50), TX500_MAINVFO}, {MHz(430), MHz(450), TX500_AM_TX_MODES, W(5), W(12.5), TX500_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {TX500_ALL_MODES, 10}, {TX500_ALL_MODES, 100}, {TX500_ALL_MODES, kHz(1)}, {TX500_ALL_MODES, kHz(2.5)}, {TX500_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {TX500_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {TX500_ALL_MODES, MHz(1)}, {TX500_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, Hz(600)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM | RIG_MODE_AM, kHz(12)}, RIG_FLT_END, }, .str_cal = TX500_STR_CAL, .priv = (void *)& tx500_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = ts2000_get_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = ts2000_get_channel, .set_channel = ts2000_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, //.set_powerstat = kenwood_set_powerstat, //.get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * ts2000_get_channel * Read command format: M|R|P1|P2|P3|P3|;| * P1: 0 - RX frequency, 1 - TX frequency Memory channel 290 ~ 299: P1=0 (start frequency), P1=1 (end frequency) P2 - bank number allowed values: , 0, 1 or 2 P3 - channel number 00-99 Returned value: M | R |P1 |P2 |P3 |P3 |P4 |P4 |P4 |P4 | P4 |P4 |P4 |P4 |P4 |P4 |P4 |P5 |P6 |P7 | P8 |P8 |P9 |P9 |P10|P10|P10|P11|P12|P13| P13|P13|P13|P13|P13|P13|P13|P13|P14|P14| P15|P16|P16|P16|P16|P16|P16|P16|P16| ; | P1 - P3 described above P4: Frequency in Hz (11-digit). P5: Mode. 1: LSB, 2: USB, 3: CW, 4: FM, 5: AM, 6: FSK, 7: CR-R, 8: Reserved, 9: FSK-R P6: Lockout status. 0: Lockout OFF, 1: Lockout ON. P7: 0: OFF, 1: TONE, 2: CTCSS, 3: DCS. P8: Tone Number. Allowed values 01 (67Hz) - 38 (250.3Hz) P9: CTCSS tone number. Allowed values 01 (67Hz) - 38 (250.3Hz) P10: DCS code. Allowed values 000 (023 DCS code) to 103 (754 DCS code). P11: REVERSE status. P12: SHIFT status. 0: Simplex, 1: +, 2: –, 3: = (All E-types) P13: Offset frequency in Hz (9-digit). Allowed values 000000000 - 059950000 in steps of 50000. Unused digits must be 0. P14: Step size. Allowed values: for SSB, CW, FSK mode: 00 - 03 00: 1 kHz, 01: 2.5 kHz, 02: 5 kHz, 03: 10 kHz for AM, FM mode: 00 - 09 00: 5 kHz, 01: 6.25 kHz, 02: 10 kHz, 03: 12.5 kHz, 04: 15 kHz, 05: 20 kHz, 06: 25 kHz, 07: 30 kHz, 08: 50 kHz, 09: 100 kHz P15: Memory Group number (0 ~ 9). P16: Memory name. A maximum of 8 characters. */ int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; int tmp; size_t length; char buf[52]; char cmd[8]; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan || chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* put channel num in the command string */ SNPRINTF(cmd, sizeof(cmd), "MR0%03d;", chan->channel_num); err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } length = strlen(buf); memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ /* First check if a name is assigned. Name is returned at positions 41-48 (counting from 0) */ if (length > 41) { // rig_debug(RIG_DEBUG_VERBOSE, "Copying channel description: %s\n", &buf[ 41 ] ); strcpy(chan->channel_desc, &buf[ 41 ]); } /* Memory group no */ chan->scan_group = buf[ 40 ] - '0'; /* Fields 38-39 contain tuning step as a number 00 - 09. Tuning step depends on this number and the mode, just save it for now */ buf[ 40 ] = '\0'; tmp = atoi(&buf[ 38]); /* Offset frequency */ buf[ 38 ] = '\0'; chan->rptr_offs = atoi(&buf[ 29 ]); /* Shift type WARNING: '=' shift type not programmed */ if (buf[ 28 ] == '1') { chan->rptr_shift = RIG_RPT_SHIFT_PLUS; } else { if (buf[ 28 ] == '2') { chan->rptr_shift = RIG_RPT_SHIFT_MINUS; } else { chan->rptr_shift = RIG_RPT_SHIFT_NONE; } } /* Reverse status */ if (buf[27] == '1') { chan->funcs |= RIG_FUNC_REV; } /* Check for tone, CTCSS and DCS */ /* DCS code first */ if (buf[ 19 ] == '3') { if (rig->caps->dcs_list) { buf[ 27 ] = '\0'; chan->dcs_code = rig->caps->dcs_list[ atoi(&buf[ 24 ]) ]; chan->dcs_sql = chan->dcs_code; chan->ctcss_tone = 0; chan->ctcss_sql = 0; } } else { chan->dcs_code = 0; chan->dcs_sql = 0; /* CTCSS code Caution, CTCSS codes, unlike DCS codes, are numbered from 1! */ buf[ 24 ] = '\0'; if (buf[ 19 ] == '2') { chan->funcs |= RIG_FUNC_TSQL; if (rig->caps->ctcss_list) { chan->ctcss_sql = rig->caps->ctcss_list[ atoi(&buf[22]) - 1 ]; chan->ctcss_tone = 0; } } else { chan->ctcss_sql = 0; /* CTCSS tone */ if (buf[ 19 ] == '1') { chan->funcs |= RIG_FUNC_TONE; buf[ 22 ] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[ atoi(&buf[20]) - 1 ]; } } else { chan->ctcss_tone = 0; } } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } /* mode */ chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); /* Now we have the mode, let's finish the tuning step */ if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (tmp) { case 0: chan->tuning_step = kHz(5); break; case 1: chan->tuning_step = kHz(6.25); break; case 2: chan->tuning_step = kHz(10); break; case 3: chan->tuning_step = kHz(12.5); break; case 4: chan->tuning_step = kHz(15); break; case 5: chan->tuning_step = kHz(20); break; case 6: chan->tuning_step = kHz(25); break; case 7: chan->tuning_step = kHz(30); break; case 8: chan->tuning_step = kHz(50); break; case 9: chan->tuning_step = kHz(100); break; default: chan->tuning_step = 0; } } else { switch (tmp) { case 0: chan->tuning_step = kHz(1); break; case 1: chan->tuning_step = kHz(2.5); break; case 2: chan->tuning_step = kHz(5); break; case 3: chan->tuning_step = kHz(10); break; default: chan->tuning_step = 0; } } /* Frequency */ buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[3]); /* Check split freq */ cmd[2] = '1'; err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ts2000_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char sqltype = '0'; char buf[128]; char mode, tx_mode = 0; char shift = '0'; short dcscode = 0; short code = 0; int tstep = 0; int err; int tone = 0; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan) { return -RIG_EINVAL; } mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ if (chan->ctcss_tone) { for (; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = -1; } else { sqltype = '1'; } } else { tone = -1; /* -1 because we will add 1 when outputting; this is necessary as CTCSS codes are numbered from 1 */ } /* find CTCSS code */ if (chan->ctcss_sql) { for (; rig->caps->ctcss_list[code] != 0; code++) { if (chan->ctcss_sql == rig->caps->ctcss_list[code]) { break; } } if (chan->ctcss_sql != rig->caps->ctcss_list[code]) { code = -1; } else { sqltype = '2'; } } else { code = -1; } /* find DCS code */ if (chan->dcs_code) { for (; rig->caps->dcs_list[dcscode] != 0; dcscode++) { if (chan->dcs_code == rig->caps->dcs_list[dcscode]) { break; } } if (chan->dcs_code != rig->caps->dcs_list[dcscode]) { dcscode = 0; } else { sqltype = '3'; } } else { dcscode = 0; } if (chan->rptr_shift == RIG_RPT_SHIFT_PLUS) { shift = '1'; } if (chan->rptr_shift == RIG_RPT_SHIFT_MINUS) { shift = '2'; } if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (chan->tuning_step) { case s_kHz(6.25): tstep = 1; break; case s_kHz(10): tstep = 2; break; case s_kHz(12.5): tstep = 3; break; case s_kHz(15): tstep = 4; break; case s_kHz(20): tstep = 5; break; case s_kHz(25): tstep = 6; break; case s_kHz(30): tstep = 7; break; case s_kHz(50): tstep = 8; break; case s_kHz(100): tstep = 9; break; default: tstep = 0; } } else { switch (chan->tuning_step) { case s_kHz(2.5): tstep = 1; break; case s_kHz(5): tstep = 2; break; case s_kHz(10): tstep = 3; break; default: tstep = 0; } } /* P-number 2-3 4 5 6 7 8 9 101112 13 141516 */ SNPRINTF(buf, sizeof(buf), "MW0%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;", chan->channel_num, (unsigned) chan->freq, /* 4 - frequency */ '0' + mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* 15 - Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "The command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (chan->split == RIG_SPLIT_ON) { SNPRINTF(buf, sizeof(buf), "MW1%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;\n", chan->channel_num, (unsigned) chan->tx_freq, /* 4 - frequency */ '0' + tx_mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode + 1, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "Split, the command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); } return err; } /* * ts2000_get_level * Assumes rig!=NULL, val!=NULL */ int ts2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[50]; size_t lvl_len; int lvl, retval, ret, agclevel; lvl_len = 50; switch (level) { case RIG_LEVEL_PREAMP: retval = kenwood_transaction(rig, "PA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 4)) /*TS-2000 returns 4 chars for PA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 10) /* just checking for main receiver preamp setting */ { val->i = 0; } if (lvl > 9) { val->i = STATE(rig)->preamp[0]; } break; case RIG_LEVEL_ATT: retval = kenwood_transaction(rig, "RA", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if ((lvl_len != 6)) /* TS-2000 returns 6 chars for RA; */ { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl < 100) /* just checking main band attenuator */ { val->i = 0; } if (lvl > 99) { val->i = STATE( rig)->attenuator[0]; /* Since the TS-2000 only has one step on the attenuator */ } break; case RIG_LEVEL_VOXDELAY: retval = kenwood_transaction(rig, "VD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_AF: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 255.0; break; case RIG_LEVEL_CWPITCH: retval = kenwood_transaction(rig, "EX0310000", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 15) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d answer=%s\n", __func__, (int)lvl_len, lvlbuf); return -RIG_ERJCTED; } sscanf(lvlbuf + 8, "%d", &lvl); val->i = 400 + (50 * lvl); break; case RIG_LEVEL_RFPOWER: retval = kenwood_transaction(rig, "PC", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 3, "%d", &lvl); val->f = lvl / 100.0; /* FIXME: for 1.2GHZ need to divide by 10 */ break; case RIG_LEVEL_MICGAIN: return kenwood_get_level(rig, vfo, level, val); case RIG_LEVEL_KEYSPD: retval = kenwood_transaction(rig, "KS", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl; break; case RIG_LEVEL_NOTCHF: return -RIG_ENIMPL; break; case RIG_LEVEL_COMP: retval = kenwood_transaction(rig, "PL", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 8) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); lvl = lvl / 1000; val->f = lvl / 100.0; break; case RIG_LEVEL_AGC: /* FIX ME: ts2000 returns 0 -20 for AGC */ ret = get_kenwood_level(rig, "GT", &val->f, NULL); agclevel = 255.0 * val->f; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } return ret; break; case RIG_LEVEL_BKINDL: retval = kenwood_transaction(rig, "SD", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 100; break; case RIG_LEVEL_BALANCE: return -RIG_ENIMPL; break; case RIG_LEVEL_METER: retval = kenwood_transaction(rig, "RM", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 7) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->i = lvl / 10000; break; case RIG_LEVEL_VOXGAIN: retval = kenwood_transaction(rig, "VG", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (lvl_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } sscanf(lvlbuf + 2, "%d", &lvl); val->f = lvl / 9.0; break; case RIG_LEVEL_ANTIVOX: return -RIG_ENIMPL; break; case RIG_LEVEL_RAWSTR: case RIG_LEVEL_STRENGTH: retval = kenwood_transaction(rig, "SM0", lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { return retval; } lvl_len = strlen(lvlbuf); if (((lvl_len != 7)) || lvlbuf[1] != 'M') { /* TS-2000 returns 8 bytes for S meter level */ rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)lvl_len); return -RIG_ERJCTED; } /* Frontend expects: -54 = S0, 0 = S9 */ sscanf(lvlbuf + 3, "%d", &val->i); /* TS-2000 main receiver returns values from 0 - 30 */ /* so scale the value */ if (level == RIG_LEVEL_STRENGTH) { val->i = (val->i * 3.6) - 54; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } hamlib-4.6.2/rigs/kenwood/flex6xxx.c0000644000175000017500000013356714752216205014275 00000000000000/* * Hamlib FlexRadio backend - 6K series rigs * Copyright (c) 2002-2009 by Stephane Fillod * Copyright (C) 2010,2011,2012,2013 by Nate Bargmann, n0nb@arrl.net * Copyright (C) 2013 by Steve Conklin AI4QR, steve@conklinhouse.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include #include "kenwood.h" #include "bandplan.h" #include "misc.h" #include "flex.h" #define F6K_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define F6K_FUNC_ALL (RIG_FUNC_VOX|RIG_FUNC_TUNER) #define F6K_LEVEL_ALL (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER) #define F6K_VFO (RIG_VFO_A|RIG_VFO_B) #define POWERSDR_VFO_OP (RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_UP|RIG_OP_DOWN) #define F6K_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3) /* PowerSDR differences */ #define POWERSDR_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB|RIG_MODE_SPEC) #define POWERSDR_FUNC_ALL (RIG_FUNC_VOX|RIG_FUNC_SQL|RIG_FUNC_NB|RIG_FUNC_ANF|RIG_FUNC_MUTE|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_TUNER) #define POWERSDR_LEVEL_ALL (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_MICGAIN|RIG_LEVEL_VOXGAIN|RIG_LEVEL_SQL|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_IF|RIG_LEVEL_STRENGTH|RIG_LEVEL_SWR) #define POWERSDR_LEVEL_SET (RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_KEYSPD|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_VOXGAIN|RIG_LEVEL_SQL|RIG_LEVEL_AF|RIG_LEVEL_AGC|RIG_LEVEL_RF|RIG_LEVEL_IF) static rmode_t flex_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_PKTLSB, [7] = RIG_MODE_NONE, [8] = RIG_MODE_NONE, [9] = RIG_MODE_PKTUSB }; static rmode_t powersdr_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_LSB, [1] = RIG_MODE_USB, [2] = RIG_MODE_DSB, [3] = RIG_MODE_CWR, [4] = RIG_MODE_CW, [5] = RIG_MODE_FM, [6] = RIG_MODE_AM, [7] = RIG_MODE_PKTUSB, [8] = RIG_MODE_NONE, // SPEC -- not implemented [9] = RIG_MODE_PKTLSB, [10] = RIG_MODE_SAM, [11] = RIG_MODE_NONE // DRM -- not implemented }; static struct kenwood_priv_caps f6k_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = flex_mode_table, .if_len = 37 }; static struct kenwood_priv_caps powersdr_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = powersdr_mode_table, .if_len = 37, .swr = 0 }; #define DSP_BW_NUM 8 static int dsp_bw_ssb[DSP_BW_NUM] = { 4000, 3300, 2900, 2700, 2400, 2100, 1800, 1600 }; static int dsp_bw_am[DSP_BW_NUM] = { 20000, 16000, 14000, 12000, 10000, 8000, 6000, 5600 }; static int dsp_bw_cw[DSP_BW_NUM] = { 3000, 1500, 1000, 800, 400, 250, 100, 50 }; static int dsp_bw_dig[DSP_BW_NUM] = { 3000, 2000, 1500, 1000, 600, 300, 150, 100 }; // PowerSDR settings #define DSP_BW_NUM_POWERSDR 12 static int dsp_bw_ssb_powersdr[DSP_BW_NUM_POWERSDR] = { 5000, 4400, 3800, 3300, 2900, 2700, 2400, 2100, 1800, 1000, 0, 0 }; static int dsp_bw_am_powersdr[DSP_BW_NUM_POWERSDR] = { 16000, 12000, 10000, 8000, 6600, 5200, 4000, 3100, 2900, 2400, 0, 0 }; static int dsp_bw_cw_powersdr[DSP_BW_NUM_POWERSDR] = { 1000, 800, 600, 500, 400, 250, 150, 100, 50, 25, 0, 0 }; static int dsp_bw_dig_powersdr[DSP_BW_NUM_POWERSDR] = { 3000, 2500, 2000, 1500, 1000, 800, 600, 300, 150, 75, 0, 0 }; #if 0 // not used yet static int dsp_bw_sam_powersdr[DSP_BW_NUM_POWERSDR] = { 20000, 18000, 16000, 12000, 10000, 9000, 8000, 7000, 6000, 5000, 0, 0 }; #endif /* Private helper functions */ static int flex6k_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char modebuf[10]; int index; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "MD", modebuf, 6, 3); if (retval != RIG_OK) { return retval; } *mode = kenwood2rmode(modebuf[2] - '0', caps->mode_table); if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI * Have to determine what to do with receiver#2 if anybody ever asks */ switch (vfo) { case RIG_VFO_A: retval = kenwood_safe_transaction(rig, "ZZFI", modebuf, 10, 6); break; case RIG_VFO_B: retval = kenwood_safe_transaction(rig, "ZZFJ", modebuf, 10, 6); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } if (retval != RIG_OK) { return retval; } index = atoi(&modebuf[4]); if (index >= DSP_BW_NUM) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected ZZF[IJ] answer, index=%d\n", __func__, index); return -RIG_ERJCTED; } switch (*mode) { case RIG_MODE_AM: case RIG_MODE_DSB: *width = dsp_bw_am[index]; break; case RIG_MODE_CW: *width = dsp_bw_cw[index]; break; case RIG_MODE_USB: case RIG_MODE_LSB: *width = dsp_bw_ssb[index]; break; //case RIG_MODE_FM: //*width = 3000; /* not supported yet, needs followup */ //break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: *width = dsp_bw_dig[index]; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s, setting default BW\n", __func__, rig_strrmode(*mode)); *width = 3000; break; } return RIG_OK; } static int powersdr_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char modebuf[10]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "ZZMD", modebuf, 10, 6); if (retval != RIG_OK) { return retval; } *mode = kenwood2rmode(atoi(&modebuf[4]), caps->mode_table); if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI or ZZFJ command */ switch (vfo) { int lo, hi; case RIG_VFO_A: case RIG_VFO_B: retval = kenwood_safe_transaction(rig, "ZZFL", modebuf, 10, 9); if (retval != RIG_OK) { return retval; } lo = atoi(&modebuf[4]); retval = kenwood_safe_transaction(rig, "ZZFH", modebuf, 10, 9); if (retval != RIG_OK) { return retval; } hi = atoi(&modebuf[4]); rig_debug(RIG_DEBUG_VERBOSE, "%s: lo=%d, hi=%d\n", __func__, lo, hi); *width = hi - lo; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } return RIG_OK; } /* Private helper functions */ static int flex6k_find_width(rmode_t mode, pbwidth_t width, int *ridx) { int *w_a; // Width array, these are all ordered in descending order! int idx = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (mode) { case RIG_MODE_AM: w_a = dsp_bw_am; break; case RIG_MODE_CW: w_a = dsp_bw_cw; break; case RIG_MODE_USB: case RIG_MODE_LSB: w_a = dsp_bw_ssb; break; //case RIG_MODE_FM: //*width = 3000; /* not supported yet, needs followup */ //break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: w_a = dsp_bw_dig; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } // return the first smaller or equal possibility while ((idx < DSP_BW_NUM) && (w_a[idx] > width)) { idx++; } if (idx >= DSP_BW_NUM) { idx = DSP_BW_NUM - 1; } *ridx = idx; return RIG_OK; } static int powersdr_find_width(rmode_t mode, pbwidth_t width, int *ridx) { int *w_a; // Width array, these are all ordered in descending order! int idx = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (mode) { case RIG_MODE_AM: w_a = dsp_bw_am_powersdr; break; case RIG_MODE_CW: case RIG_MODE_CWR: w_a = dsp_bw_cw_powersdr; break; case RIG_MODE_USB: case RIG_MODE_LSB: w_a = dsp_bw_ssb_powersdr; break; //case RIG_MODE_FM: //*width = 3000; /* not supported yet, needs followup */ //break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: w_a = dsp_bw_dig_powersdr; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } // return the first smaller or equal possibility while ((idx < DSP_BW_NUM) && (w_a[idx] > width)) { idx++; } if (idx >= DSP_BW_NUM) { idx = DSP_BW_NUM - 1; } *ridx = idx; return RIG_OK; } static int flex6k_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char buf[10]; char kmode; int idx; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD%c", '0' + kmode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } if (RIG_PASSBAND_NOCHANGE == width) { return err; } err = flex6k_find_width(mode, width, &idx); if (err != RIG_OK) { return err; } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI or ZZFJ command */ switch (vfo) { case RIG_VFO_A: SNPRINTF(buf, sizeof(buf), "ZZFI%02d;", idx); break; case RIG_VFO_B: SNPRINTF(buf, sizeof(buf), "ZZFJ%02d;", idx); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } static int powersdr_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char buf[64]; char kmode; int idx; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called mode=%s, width=%d\n", __func__, rig_strrmode(mode), (int)width); kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "ZZMD%02d", kmode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if ((vfo == RIG_VFO_VFO) || (vfo == RIG_VFO_CURR)) { vfo = STATE(rig)->current_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: setting VFO to current\n", __func__); } if (RIG_PASSBAND_NOCHANGE == width) { return err; } err = powersdr_find_width(mode, width, &idx); if (err != RIG_OK) { return err; } /* * The Flex CAT interface does not support FW for reading filter width, * so use the ZZFI or ZZFJ command */ switch (vfo) { case RIG_VFO_B: case RIG_VFO_A: if ((mode == RIG_MODE_PKTUSB || mode == RIG_MODE_PKTLSB) && width > 3000) { // 150Hz on the low end should be enough // Set high to the width requested SNPRINTF(buf, sizeof(buf), "ZZFL00150;ZZFH%05d;", (int)width); } else { SNPRINTF(buf, sizeof(buf), "ZZFI%02d;", idx); } break; // what do we do about RX2 ?? default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); return -RIG_EINVAL; } err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* * flex6k_get_ptt */ int flex6k_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { const char *ptt_cmd; int err; char response[16] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ptt) { return -RIG_EINVAL; } ptt_cmd = "ZZTX"; err = kenwood_transaction(rig, ptt_cmd, response, sizeof(response)); if (err != RIG_OK) { return err; } *ptt = response[4] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; return RIG_OK; } int flex6k_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; char response[16] = ""; int err; int retry = 3; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (ptt) { case RIG_PTT_ON_DATA: case RIG_PTT_ON_MIC: case RIG_PTT_ON: ptt_cmd = "ZZTX1;ZZTX"; break; case RIG_PTT_OFF: ptt_cmd = "ZZTX0;ZZTX"; break; default: return -RIG_EINVAL; } do { err = kenwood_transaction(rig, ptt_cmd, response, sizeof(response)); if (ptt_cmd[4] != response[4]) { rig_debug(RIG_DEBUG_ERR, "%s: %s != %s\n", __func__, ptt_cmd, response); hl_usleep(20 * 1000); // takes a bit to do PTT off } } while (ptt_cmd[4] != response[4] && --retry); return err; } /* * powersdr_set_level */ int powersdr_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmd[KENWOOD_MAX_BUF_LEN]; int retval; int ival; rmode_t mode; pbwidth_t width; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_AF: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * 100; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZAG%03d", ival); break; case RIG_LEVEL_IF: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZIT%+05d", val.i); break; case RIG_LEVEL_RF: if (val.f > 1.0) { return -RIG_EINVAL; } if (rig->caps->rig_model == RIG_MODEL_POWERSDR) { ival = val.f * (120 - -20) - 20; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZAR%+04d", ival); } else { ival = val.f * 100; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZAR%03d", ival); } break; case RIG_LEVEL_MICGAIN: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * (10 - -40) - 40; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZMG%03d", ival); break; case RIG_LEVEL_AGC: if (val.i > 5) { val.i = 5; /* 0.. 255 */ } SNPRINTF(cmd, sizeof(cmd), "GT%03d", (int)val.i); break; case RIG_LEVEL_VOXGAIN: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * 1000; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZVG%04d", ival); break; case RIG_LEVEL_SQL: if (val.f > 1.0) { return -RIG_EINVAL; } powersdr_get_mode(rig, vfo, &mode, &width); if (mode == RIG_MODE_FM) { ival = val.f * 100; // FM mode is 0 to 100 } else { ival = 160 - (val.f * 160); // all other modes 0 to 160 } SNPRINTF(cmd, sizeof(cmd) - 1, "ZZSQ%03d", ival); break; default: return kenwood_set_level(rig, vfo, level, val); } retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s exiting\n", __func__); return RIG_OK; } /* * flek6k_set_level */ int flex6k_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char cmd[KENWOOD_MAX_BUF_LEN]; int retval; int ival; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RFPOWER: if (val.f > 1.0) { return -RIG_EINVAL; } ival = val.f * 100; SNPRINTF(cmd, sizeof(cmd) - 1, "ZZPC%03d", ival); break; default: return kenwood_set_level(rig, vfo, level, val); } retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } rig_debug(RIG_DEBUG_VERBOSE, "%s exiting\n", __func__); return RIG_OK; } /* * flex6k_get_level */ int flex6k_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int len, ans; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RFPOWER: cmd = "ZZPC"; len = 4; ans = 3; break; default: return kenwood_get_level(rig, vfo, level, val); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), len + ans); if (retval != RIG_OK) { return retval; } int n; switch (level) { case RIG_LEVEL_RFPOWER: n = sscanf(lvlbuf, "ZZPC%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } val->f /= 100; break; default: rig_debug(RIG_DEBUG_ERR, "%s: should never get here\n", __func__); } return RIG_OK; } /* * powersdr_get_level */ int powersdr_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int len, ans; rmode_t mode; pbwidth_t width; ptt_t ptt; double dval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_AGC: cmd = "GT"; len = 2; ans = 3; break; case RIG_LEVEL_AF: cmd = "ZZAG"; len = 4; ans = 3; break; case RIG_LEVEL_IF: cmd = "ZZIT"; len = 4; ans = 5; break; case RIG_LEVEL_RF: cmd = "ZZAR"; len = 4; ans = 4; break; case RIG_LEVEL_STRENGTH: flex6k_get_ptt(rig, vfo, &ptt); if (ptt) // not applicable if transmitting { val->f = 0; return RIG_OK; } cmd = "ZZRM0"; len = 5; ans = 9; break; case RIG_LEVEL_RFPOWER: cmd = "ZZPC"; len = 4; ans = 8; break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: flex6k_get_ptt(rig, vfo, &ptt); if (!ptt) { val->f = 0; return RIG_OK; } cmd = "ZZRM5"; len = 5; ans = 3; break; case RIG_LEVEL_MICGAIN: cmd = "ZZMG"; len = 4; ans = 3; break; case RIG_LEVEL_VOXGAIN: cmd = "ZZVG"; len = 4; ans = 4; break; case RIG_LEVEL_SQL: cmd = "ZZSQ"; len = 4; ans = 3; break; case RIG_LEVEL_SWR: { struct kenwood_priv_caps *priv = kenwood_caps(rig); ptt = 0; rig_get_ptt(rig, RIG_VFO_CURR, &ptt); if (ptt == RIG_PTT_OFF) { val->f = priv->swr; return RIG_OK;} cmd = "ZZRM8"; // get SWR retval = kenwood_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf)); if (retval != RIG_OK) { val->f = priv->swr; return RIG_OK;}; sscanf(lvlbuf, "ZZRM8%lg", &priv->swr); val->f = priv->swr; rig_debug(RIG_DEBUG_ERR, "%s(%d) swr=%.1f\n", __func__, __LINE__, val->f); return RIG_OK; } default: return kenwood_get_level(rig, vfo, level, val); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, sizeof(lvlbuf), len + ans); if (retval != RIG_OK) { return retval; } int n; switch (level) { case RIG_LEVEL_AGC: n = sscanf(lvlbuf + len, "%d", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } break; case RIG_LEVEL_IF: n = sscanf(lvlbuf + len, "%d", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } break; case RIG_LEVEL_STRENGTH: n = sscanf(lvlbuf, "ZZRM0%lf", &dval); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->i = 0; return -RIG_EPROTO; } val->i = dval + 73; // dbm to S9-based=0dB break; case RIG_LEVEL_AF: n = sscanf(lvlbuf, "ZZAG%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } val->f /= 100.0; break; case RIG_LEVEL_RFPOWER: n = sscanf(lvlbuf, "ZZPC%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } val->f /= 100; break; case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: { // if not ptt then no power is going out so return 0W ptt = 0; rig_get_ptt(rig, RIG_VFO_TX, &ptt); if (!ptt) { val->f = 0; return RIG_OK; } n = sscanf(lvlbuf, "ZZRM5%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); val->f = 0; return -RIG_EPROTO; } } if (level != RIG_LEVEL_RFPOWER_METER_WATTS) { val->f /= 100; } break; case RIG_LEVEL_RF: n = sscanf(lvlbuf + len, "%d", &val->i); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } n = val->i; val->f = (n + 20.0) / (120.0 - -20.0); break; case RIG_LEVEL_MICGAIN: n = sscanf(lvlbuf + len, "%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } // Thetis returns -40 to 10 -- does PowerSDR do the same? // Setting val->f = (val->f - -40) / (10 - -40); break; case RIG_LEVEL_VOXGAIN: // return is 0-1000 n = sscanf(lvlbuf + len, "%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } val->f /= 1000; break; case RIG_LEVEL_SQL: n = sscanf(lvlbuf + len, "%f", &val->f); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: Error parsing value from lvlbuf='%s'\n", __func__, lvlbuf); return -RIG_EPROTO; } powersdr_get_mode(rig, vfo, &mode, &width); if (mode == RIG_MODE_FM) { val->f /= 100; // FM mode is 0 to 100 } else { val->f = fabs((val->f - 160) / -160); // all other modes 0 to 160 } break; default: rig_debug(RIG_DEBUG_ERR, "%s: should never get here\n", __func__); } return RIG_OK; } int powersdr_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmd[KENWOOD_MAX_BUF_LEN]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (func) { case RIG_FUNC_MUTE: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZMA%01d", status); break; case RIG_FUNC_VOX: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZVE%01d", status); break; case RIG_FUNC_SQL: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZSO%01d", status); break; case RIG_FUNC_TUNER: SNPRINTF(cmd, sizeof(cmd) - 1, "ZZTU%01d", status); break; default: return kenwood_set_func(rig, vfo, func, status); } return kenwood_transaction(rig, cmd, NULL, 0); } int powersdr_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int len, ans; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_MUTE: cmd = "ZZMA"; len = 4; ans = 1; break; case RIG_FUNC_VOX: cmd = "ZZVE"; len = 4; ans = 1; break; case RIG_FUNC_SQL: cmd = "ZZSO"; len = 4; ans = 1; break; default: return kenwood_get_func(rig, vfo, func, status); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + ans); if (retval != RIG_OK) { return retval; } switch (func) { case RIG_FUNC_MUTE: case RIG_FUNC_VOX: case RIG_FUNC_SQL: sscanf(lvlbuf + len, "%d", status); break; default: rig_debug(RIG_DEBUG_ERR, "%s: should never get here\n", __func__); } return RIG_OK; } int powersdr_set_parm(RIG *rig, setting_t parm, value_t val) { ENTERFUNC; char cmd[KENWOOD_MAX_BUF_LEN]; int retval = -RIG_EINTERNAL; int band = 999; // default to the weird WWV band rig_debug(RIG_DEBUG_VERBOSE, "%s: val=%s\n", __func__, val.s); switch (parm) { case RIG_PARM_BANDSELECT: if (strcmp(val.s, "BANDWWV") != 0) { int n = sscanf(val.s, "BAND%d", &band); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unknown band=%s\n", __func__, val.s); } } SNPRINTF(cmd, sizeof(cmd), "ZZBS%03d;", band); retval = kenwood_transaction(rig, cmd, NULL, 0); } RETURNFUNC(retval); } int powersdr_get_parm(RIG *rig, setting_t parm, value_t *val) { char cmd[KENWOOD_MAX_BUF_LEN]; char buf[KENWOOD_MAX_BUF_LEN]; int retval; int len, ans; ENTERFUNC; switch (parm) { case RIG_PARM_BANDSELECT: len = 4; ans = 3; SNPRINTF(cmd, sizeof(cmd), "%s", "ZZBS;"); break; default: RETURNFUNC(-RIG_EINVAL); } retval = kenwood_safe_transaction(rig, cmd, buf, 10, len + ans); if (retval != RIG_OK) { RETURNFUNC(retval); } int band; int n = sscanf(buf, "ZZBS%3d", &band); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unknown band=%s\n", __func__, buf); RETURNFUNC(-RIG_EPROTO); } switch (band) { case 160: val->cs = "BAND160M"; break; case 80: val->cs = "BAND80M"; break; case 60: val->cs = "BAND60M"; break; case 40: val->cs = "BAND40M"; break; case 30: val->cs = "BAND30M"; break; case 20: val->cs = "BAND20M"; break; case 17: val->cs = "BAND17M"; break; case 15: val->cs = "BAND15M"; break; case 12: val->cs = "BAND12M"; break; case 10: val->cs = "BAND10M"; break; case 6: val->cs = "BAND6M"; break; case 999: val->cs = "BANDWWV"; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown band=%d\n", __func__, band); val->cs = "BAND???"; } RETURNFUNC(RIG_OK); } #define NO_LVL_KEYSPD #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH /* * F6K rig capabilities. */ struct rig_caps f6k_caps = { RIG_MODEL(RIG_MODEL_F6K), .model_name = "6xxx", .mfg_name = "FlexRadio", .version = "20240829.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_NETWORK, // The combination of timeout and retry is important // We need at least 3 seconds to do profile switches // Hitting the timeout is OK as long as we retry // Previous note showed FA/FB may take up to 500ms on band change .timeout = 700, .retry = 13, .has_get_func = RIG_FUNC_NONE, /* has VOX but not implemented here */ .has_set_func = RIG_FUNC_NONE, .has_get_level = F6K_LEVEL_ALL, .has_set_level = F6K_LEVEL_ALL, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { [LVL_KEYSPD] = { .min = { .i = 5 }, .max = { .i = 60 }, .step = { .i = 1 } }, [LVL_SLOPE_LOW] = { .min = { .i = 10}, .max = { .i = 1000}, .step = { .i = 50} }, [LVL_SLOPE_HIGH] = { .min = { .i = 1000}, .max = { .i = 5000}, .step = { .i = 10} }, }, /* FIXME: granularity */ .parm_gran = {}, //.extlevels = elecraft_ext_levels, //.extparms = kenwood_cfg_params, .post_write_delay = 20, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(99999), .max_xit = Hz(99999), .max_ifshift = Hz(0), .vfo_ops = RIG_OP_NONE, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(30), MHz(77), F6K_MODES, -1, -1, F6K_VFO, F6K_ANTS}, {MHz(135), MHz(165), F6K_MODES, -1, - 1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(1, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(1, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(30), MHz(77), F6K_MODES, -1, -1, F6K_VFO, F6K_ANTS}, { MHz(135), MHz(165), F6K_MODES, -1, -1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(2, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(2, F6K_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {F6K_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(4.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, kHz(0.4)}, {RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(1.5)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.0)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(0.1)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(14)}, {RIG_MODE_AM, kHz(5.6)}, {RIG_MODE_AM, kHz(20.0)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& f6k_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = flexradio_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = flex6k_set_mode, .get_mode = flex6k_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, // TODO copy over kenwood_[set|get]_level and modify to handle DSP filter values // correctly - use actual values instead of indices .set_level = flex6k_set_level, .get_level = flex6k_get_level, //.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 }; /* * PowerSDR rig capabilities. */ struct rig_caps powersdr_caps = { RIG_MODEL(RIG_MODEL_POWERSDR), .model_name = "PowerSDR", .mfg_name = "FlexRadio/Apache", .version = "20231107.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, // The combination of timeout and retry is important // We need at least 3 seconds to do profile switches // Hitting the timeout is OK as long as we retry // Previous note showed FA/FB may take up to 500ms on band change // Flex 1500 needs about 6 seconds for a band change in PowerSDR .timeout = 800, // some band transitions can take 600ms .retry = 10, .has_get_func = POWERSDR_FUNC_ALL, .has_set_func = POWERSDR_FUNC_ALL, .has_get_level = POWERSDR_LEVEL_ALL, .has_set_level = POWERSDR_LEVEL_SET, .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_KEYSPD #include "level_gran_kenwood.h" #undef NO_LVL_KEYSPD [LVL_KEYSPD] = { .min = { .i = 5 }, .max = { .i = 60 }, .step = { .i = 1 } }, }, /* FIXME: granularity */ .parm_gran = { // there are V00 thru V13 but we don't cover them as of yet -- what rig? [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BAND2M,BANDWWV,BANDGEN"}} }, //.extlevels = elecraft_ext_levels, //.extparms = kenwood_cfg_params, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_op = kenwood_vfo_op, .vfo_ops = POWERSDR_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 6, .agc_levels = { RIG_AGC_OFF, RIG_AGC_LONG, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_USER }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, {MHz(135), MHz(165), POWERSDR_MODES, -1, - 1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, { MHz(135), MHz(165), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {POWERSDR_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(4.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, kHz(0.4)}, {RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(1.5)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.0)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(0.1)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(14)}, {RIG_MODE_AM, kHz(5.6)}, {RIG_MODE_AM, kHz(20.0)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& powersdr_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = flexradio_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = powersdr_set_mode, .get_mode = powersdr_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 = flex6k_get_ptt, .set_ptt = flex6k_set_ptt, .get_powerstat = kenwood_get_powerstat, .set_powerstat = kenwood_set_powerstat, // TODO copy over kenwood_[set|get]_level and modify to handle DSP filter values // correctly - use actual values instead of indices .set_level = powersdr_set_level, .get_level = powersdr_get_level, .get_func = powersdr_get_func, .set_func = powersdr_set_func, .get_parm = powersdr_get_parm, .set_parm = powersdr_set_parm, //.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 }; /* * Thetis rig capabilities. Same as PowerSDR for now but may get new functions */ struct rig_caps thetis_caps = { RIG_MODEL(RIG_MODEL_THETIS), .model_name = "", .mfg_name = "Thetis", .version = "20231222.0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 300, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, // The combination of timeout and retry is important // We need at least 3 seconds to do profile switches // Hitting the timeout is OK as long as we retry // Previous note showed FA/FB may take up to 500ms on band change // Flex 1500 needs about 6 seconds for a band change in PowerSDR .timeout = 800, // some band transitions can take 600ms .retry = 10, .has_get_func = POWERSDR_FUNC_ALL, .has_set_func = POWERSDR_FUNC_ALL, .has_get_level = POWERSDR_LEVEL_ALL, .has_set_level = POWERSDR_LEVEL_SET, .has_get_parm = RIG_PARM_BANDSELECT, .has_set_parm = RIG_PARM_BANDSELECT, .level_gran = { #define NO_LVL_KEYSPD #include "level_gran_kenwood.h" #undef NO_LVL_KEYSPD [LVL_KEYSPD] = { .min = { .i = 5 }, .max = { .i = 60 }, .step = { .i = 1 } }, }, /* FIXME: granularity */ .parm_gran = { // there are V00 thru V13 but we don't cover them as of yet -- what rig? [PARM_BANDSELECT] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.s = "BAND160M,BAND80M,BAND60M,BAND40M,BAND30M,BAND20M,BAND17M,BAND15M,BAND12M,BAND10M,BAND6M,BAND2M,BANDWWV,BANDGEN"}} }, //.extlevels = elecraft_ext_levels, //.extparms = kenwood_cfg_params, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_op = kenwood_vfo_op, .vfo_ops = POWERSDR_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 6, .agc_levels = { RIG_AGC_OFF, RIG_AGC_LONG, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_USER }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { RIG_CHAN_END }, .rx_range_list1 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, {MHz(135), MHz(165), POWERSDR_MODES, -1, - 1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(1, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(30), MHz(77), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, { MHz(135), MHz(165), POWERSDR_MODES, -1, -1, F6K_VFO, F6K_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_6m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), FRQ_RNG_2m(2, POWERSDR_MODES, mW(10), W(100), F6K_VFO, F6K_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {POWERSDR_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(4.0)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW, kHz(0.4)}, {RIG_MODE_CW, kHz(1.5)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, kHz(3.0)}, {RIG_MODE_CW, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(1.5)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.0)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(0.1)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(14)}, {RIG_MODE_AM, kHz(5.6)}, {RIG_MODE_AM, kHz(20.0)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& powersdr_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = flexradio_open, .rig_close = kenwood_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = powersdr_set_mode, .get_mode = powersdr_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 = flex6k_get_ptt, .set_ptt = flex6k_set_ptt, .get_powerstat = kenwood_get_powerstat, .set_powerstat = kenwood_set_powerstat, // TODO copy over kenwood_[set|get]_level and modify to handle DSP filter values // correctly - use actual values instead of indices .set_level = powersdr_set_level, .get_level = powersdr_get_level, .get_func = powersdr_get_func, .set_func = powersdr_set_func, .get_parm = powersdr_get_parm, .set_parm = powersdr_set_parm, //.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 }; hamlib-4.6.2/rigs/kenwood/kenwood.c0000644000175000017500000050633714752216205014146 00000000000000/* * Hamlib Kenwood backend - main file * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include "hamlib/rig.h" #include "serial.h" #include "register.h" #include "cal.h" #include "cache.h" #include "misc.h" #include "kenwood.h" #include "ts990s.h" #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif struct kenwood_id { rig_model_t model; int id; }; struct kenwood_id_string { rig_model_t model; const char *id; }; #define UNKNOWN_ID -1 /* * Identification number as returned by "ID;" * Please, if the model number of your rig is listed as UNKNOWN_ID, * send the value to for inclusion. Thanks --SF * * TODO: sort this list with most frequent rigs first. */ static const struct kenwood_id kenwood_id_list[] = { { RIG_MODEL_TS940, 1 }, { RIG_MODEL_TS811, 2 }, { RIG_MODEL_TS711, 3 }, { RIG_MODEL_TS440, 4 }, { RIG_MODEL_R5000, 5 }, { RIG_MODEL_TS140S, 6 }, // { RIG_MODEL_TS680S, 6 }, // The TS680S is supposed #6 too but it will return as TS140S since it matches it { RIG_MODEL_TS790, 7 }, { RIG_MODEL_TS950S, 8 }, { RIG_MODEL_TS850, 9 }, { RIG_MODEL_TS450S, 10 }, { RIG_MODEL_TS690S, 11 }, { RIG_MODEL_TS950SDX, 12 }, { RIG_MODEL_TS50, 13 }, { RIG_MODEL_TS870S, 15 }, { RIG_MODEL_TRC80, 16 }, { RIG_MODEL_TS570D, 17 }, /* Elecraft K2|K3 also returns 17 */ { RIG_MODEL_TS570S, 18 }, { RIG_MODEL_TS2000, 19 }, { RIG_MODEL_TS480, 20 }, { RIG_MODEL_TS590S, 21 }, { RIG_MODEL_TS990S, 22 }, { RIG_MODEL_TS590SG, 23 }, { RIG_MODEL_TS890S, 24 }, { RIG_MODEL_NONE, UNKNOWN_ID }, /* end marker */ }; /* XXX numeric ids have been tested only with the TS-450 */ static const struct kenwood_id_string kenwood_id_string_list[] = { { RIG_MODEL_TS940, "001" }, { RIG_MODEL_TS811, "002" }, { RIG_MODEL_TS711, "003" }, { RIG_MODEL_TS440, "004" }, { RIG_MODEL_R5000, "005" }, { RIG_MODEL_TS140S, "006" }, { RIG_MODEL_TS790, "007" }, { RIG_MODEL_TS950S, "008" }, { RIG_MODEL_TS850, "009" }, { RIG_MODEL_TS450S, "010" }, { RIG_MODEL_TS690S, "011" }, { RIG_MODEL_TS950SDX, "012" }, { RIG_MODEL_TS50, "013" }, { RIG_MODEL_TS870S, "015" }, { RIG_MODEL_TS570D, "017" }, /* Elecraft K2|K3|KX3 also returns 17 */ { RIG_MODEL_TS570S, "018" }, { RIG_MODEL_TS2000, "019" }, { RIG_MODEL_TS480, "020" }, { RIG_MODEL_PT8000A, "020" }, // TS480 ID but behaves differently { RIG_MODEL_SDRUNO, "020" }, // TS480 ID but behaves differently { RIG_MODEL_TS590S, "021" }, { RIG_MODEL_TS990S, "022" }, { RIG_MODEL_TS590SG, "023" }, { RIG_MODEL_TS890S, "024" }, { RIG_MODEL_THD7A, "TH-D7" }, { RIG_MODEL_THD7AG, "TH-D7G" }, { RIG_MODEL_TMD700, "TM-D700" }, { RIG_MODEL_TMD710, "TM-D710" }, { RIG_MODEL_THD72A, "TH-D72" }, { RIG_MODEL_THD74, "TH-D74" }, { RIG_MODEL_TMV7, "TM-V7" }, { RIG_MODEL_TMV71, "TM-V71" }, { RIG_MODEL_THF6A, "TH-F6" }, { RIG_MODEL_THF7E, "TH-F7" }, { RIG_MODEL_THG71, "TH-G71" }, { RIG_MODEL_MALACHITE, "020" }, { RIG_MODEL_NONE, NULL }, /* end marker */ }; rmode_t kenwood_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_FM, [5] = RIG_MODE_AM, [6] = RIG_MODE_RTTY, // FSK Mode [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, /* TUNE mode or PKTUSB for SDRUNO */ [9] = RIG_MODE_RTTYR, // FSKR Mode [10] = RIG_MODE_PSK, [11] = RIG_MODE_PSKR, [12] = RIG_MODE_PKTLSB, [13] = RIG_MODE_PKTUSB, [14] = RIG_MODE_PKTFM, // FM-D1 not supported yet [15] = RIG_MODE_PKTAM, // AM-D1 not supported yet [16] = RIG_MODE_LSBD2, [17] = RIG_MODE_USBD2, [18] = RIG_MODE_NONE, // FM-D2 not supported yet [19] = RIG_MODE_NONE, // AM-D2 not supported yet [20] = RIG_MODE_LSBD3, [21] = RIG_MODE_USBD3, [22] = RIG_MODE_NONE, // FM-D3 not supported yet [23] = RIG_MODE_NONE, // AM-D3 not supported yet }; /* * 38 CTCSS sub-audible tones */ tone_t kenwood38_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 0, }; /* * 42 CTCSS sub-audible tones */ tone_t kenwood42_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0, }; /* * 51 CTCSS sub-audible tones */ tone_t kenwood51_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, /* 0- 9 */ 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, /* 10-19 */ 1318, 1365, 1413, 1462, 1514, 1567, 1598, 1622, 1655, 1679, /* 20-29 */ 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928, 1966, 1995, /* 30-39 */ 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, /* 40-49 */ 17500, 0 /* 50-99 */ }; /* Token definitions for .cfgparams in rig_caps * * See enum rig_conf_e and struct confparams in rig.h */ struct confparams kenwood_cfg_params[] = { { TOK_FINE, "fine", "Fine", "Fine step mode", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_VOICE, "voice", "Voice", "Voice recall", NULL, RIG_CONF_BUTTON, { } }, { TOK_XIT, "xit", "XIT", "XIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_RIT, "rit", "RIT", "RIT", NULL, RIG_CONF_CHECKBUTTON, { } }, { TOK_NO_ID, "no_id", "No ID", "If true do not send ID; with set commands", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; int remove_nonprint(char *s) { int i, j = 0; if (s == NULL) return 0; for (i = 0; s[i] != '\0'; ++i) { if (isprint((unsigned char)s[i])) { s[j++] = s[i]; // Copy printable character } } s[j] = '\0'; // Null-terminate the string return j; // Return the new length of the string } /** * kenwood_transaction * Assumes rig!=NULL STATE(rig)!=NULL rig->caps!=NULL * * Parameters: * cmdstr: Command to be sent to the rig. cmdstr can also be NULL, * indicating that only a reply is needed (nothing will be sent). * data: Buffer for reply string. Can be NULL, indicating that no reply * is needed and will return with RIG_OK after command was sent. * datasize: Size of buffer. It is the caller's responsibily to provide * a large enough buffer for all possible replies for a command. * * returns: * RIG_OK - if no error occurred. * RIG_EIO - if an I/O error occurred while sending/receiving data. * RIG_ETIMEOUT - if timeout expires without any characters received. * RIG_REJECTED - if a negative acknowledge was received or command not * recognized by rig. */ int kenwood_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize) { char buffer[KENWOOD_MAX_BUF_LEN]; /* use our own buffer since verification may need a longer buffer than the user supplied one */ char cmdtrm_str[2]; /* Default Command/Reply termination char */ int retval = -RIG_EINTERNAL; char *cmd; int len; int retry_read = 0; struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct rig_state *rs; struct hamlib_port *rp; /* Pointer to rigport structure */ if (datasize > 0 && datasize < (cmdstr ? strlen(cmdstr) : 0)) { rig_debug(RIG_DEBUG_WARN, "%s called cmd=%.4095s datasize=%d, datasize < cmd length?\n", __func__, cmdstr ? cmdstr : "(NULL)", (int)datasize); } else { rig_debug(RIG_DEBUG_VERBOSE, "%s called cmd=%s\n", __func__, cmdstr ? cmdstr : "(NULL)"); } if ((!cmdstr && !datasize) || (datasize && !data)) { RETURNFUNC2(-RIG_EINVAL); } rs = STATE(rig); rp = RIGPORT(rig); rs->transaction_active = 1; /* Emulators don't need any post_write_delay */ if (priv->is_emulation) { rp->post_write_delay = 0; } // if this is an IF cmdstr and not the first time through check cache if (cmdstr && strcmp(cmdstr, "IF") == 0 && priv->cache_start.tv_sec != 0) { int cache_age_ms; cache_age_ms = elapsed_ms(&priv->cache_start, HAMLIB_ELAPSED_GET); if (cache_age_ms < 500) // 500ms cache time { rig_debug(RIG_DEBUG_TRACE, "%s(%d): cache hit, age=%dms\n", __func__, __LINE__, cache_age_ms); if (data) { strncpy(data, priv->last_if_response, datasize); } RETURNFUNC2(RIG_OK); } // else we drop through and do the real IF command } if (cmdstr && (strlen(cmdstr) > 2 || strcmp(cmdstr, "RX") == 0 || strncmp(cmdstr, "TX", 2) == 0 || strncmp(cmdstr, "ZZTX", 4)) == 0) { // then we must be setting something so we'll invalidate the cache rig_debug(RIG_DEBUG_TRACE, "%s: cache invalidated\n", __func__); priv->cache_start.tv_sec = 0; } cmdtrm_str[0] = caps->cmdtrm; cmdtrm_str[1] = '\0'; transaction_write: if (cmdstr) { rig_debug(RIG_DEBUG_TRACE, "%s: cmdstr = %s\n", __func__, cmdstr); len = strlen(cmdstr); cmd = calloc(1, len + 2); if (cmd == NULL) { retval = -RIG_ENOMEM; goto transaction_quit; } memcpy(cmd, cmdstr, len); /* XXX the if is temporary, until all invocations are fixed */ if (cmdstr[len - 1] != ';' && cmdstr[len - 1] != '\r') { cmd[len] = caps->cmdtrm; len++; } /* flush anything in the read buffer before command is sent */ rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, len); free(cmd); if (retval != RIG_OK) { goto transaction_quit; } } // we're not going to do the verify on RX cmd // Seems some rigs (like TS-480) return "?" when RX is done while PTT=OFF // So we'll skip the checks just on this one command for now // The TS-480 PC Control says RX; should return RX0; but it doesn't // We may eventually want to verify PTT with rig_get_ptt instead // The TS-2000 doesn't like doing an ID right after RU or RD if (retval == RIG_OK) { int skip = strncmp(cmdstr, "RX", 2) == 0; skip |= strncmp(cmdstr, "RU", 2) == 0; skip |= strncmp(cmdstr, "RD", 2) == 0; skip |= strncmp(cmdstr, "KYW", 3) == 0; skip |= strncmp(cmdstr, "KY ", 3) == 0; skip |= strncmp(cmdstr, "KY2", 3) == 0; skip |= strncmp(cmdstr, "PS1", 3) == 0; skip |= strncmp(cmdstr, "PS0", 3) == 0; skip |= strncmp(cmdstr, "K22", 3) == 0; if (skip) { // most command we give them a little time -- but not KY if (strncmp(cmdstr, "KY ", 3) != 0 && strncmp(cmdstr, "KY2", 3) != 0) { hl_usleep(200 * 1000); // give little settle time for these commands } goto transaction_quit; } } // Malachite SDR cannot send ID after FA if (!datasize && priv->no_id) { RETURNFUNC2(RIG_OK); } if (!datasize && strncmp(cmdstr, "KY", 2) != 0) { rs->transaction_active = 0; // there are some commands that have problems with immediate follow-up // so we'll just ignore them /* no reply expected so we need to write a command that always gives a reply so we can read any error replies from the actual command being sent without blocking */ if (RIG_OK != (retval = write_block(rp, (unsigned char *) priv->verify_cmd, strlen(priv->verify_cmd)))) { goto transaction_quit; } } transaction_read: /* allow room for most any response */ // this len/expected stuff is confusing -- logic in some places includes the semicolon // so we add 1 to our read_string length to cover these cases // eventually we should be able to get rid of this but requires testing all Kenwood rigs len = min(datasize ? datasize + 1 : strlen(priv->verify_cmd) + 48, KENWOOD_MAX_BUF_LEN); retval = read_string(rp, (unsigned char *) buffer, len, cmdtrm_str, strlen(cmdtrm_str), 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string len=%d '%s'\n", __func__, (int)strlen(buffer), buffer); // this fixes the case when some corrupt data is returned // let's us be a little more robust about funky serial data remove_nonprint(buffer); if (retval < 0) { rig_debug(RIG_DEBUG_WARN, "%s: read_string retval < 0, retval = %d, retry_read=%d, rp->retry=%d\n", __func__, retval, retry_read, rp->retry); // only retry if we expect a response from the command if (retry_read++ < rp->retry) { goto transaction_write; // we use to not re-do the write // but now we use ID; to verify commands are working // so in order to retry commands need to re-write them // https://github.com/Hamlib/Hamlib/issues/983 #if 0 if (datasize) { goto transaction_write; } else if (-RIG_ETIMEOUT == retval) { goto transaction_read; } #endif } goto transaction_quit; } /* Check that command termination is correct */ if (strchr(cmdtrm_str, buffer[strlen(buffer) - 1]) == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: Command is not correctly terminated '%s'\n", __func__, buffer); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } if (strlen(buffer) == 2) { switch (buffer[0]) { case 'N': /* Command recognised by rig but invalid data entered. */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: NegAck for '%s'\n", __func__, cmdstr); } retval = -RIG_ENAVAIL; goto transaction_quit; case 'O': /* Too many characters sent without a carriage return */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Overflow for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; case 'E': /* Communication error */ if (cmdstr) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Communication error for '%s'\n", __func__, cmdstr); } if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EIO; goto transaction_quit; case '?': /* The ? response is an ambiguous response, but for get commands it seems to * indicate that the rig rejected the command because the state of the rig is not valid for the command * or that the command parameter is invalid. Retrying the command does not fix the issue, * as the error is caused by the an invalid combination of rig state. * * For example, the following cases have been observed: * - NL (NB level) and RL (NR level) commands fail if NB / NR are not enabled on TS-590SG * - SH and SL (filter width) fail in CW mode on TS-590SG * - GT (AGC) fails in FM mode on TS-590SG * * There are more cases like these and they vary by rig model. */ if (priv->question_mark_response_means_rejected) { rig_debug(RIG_DEBUG_ERR, "%s: Command rejected by the rig (get): '%s'\n", __func__, cmdstr); RETURNFUNC2(-RIG_ERJCTED); } /* Command not understood by rig or rig busy */ if (cmdstr) { rig_debug(RIG_DEBUG_ERR, "%s: Unknown command or rig busy '%s'\n", __func__, cmdstr); // sometimes IF; command after TX; will return ? but still return IF response if (retry_read++ <= 1) { hl_usleep(100 * 1000); goto transaction_read; } } if (retry_read++ < rp->retry) { rig_debug(RIG_DEBUG_ERR, "%s: Retrying shortly %d of %d\n", __func__, retry_read, rp->retry); hl_usleep(rig->caps->timeout * 1000); goto transaction_write; } retval = -RIG_ERJCTED; goto transaction_quit; } } /* * Check that we received the correct reply. The first two characters * should be the same as command. Because the Elecraft XG3 uses * single character commands we only check the first character in * that case. */ if (datasize) { // we ignore the special PS command if (cmdstr && strcmp(cmdstr, "PS") != 0 && (buffer[0] != cmdstr[0] || (cmdstr[1] && buffer[1] != cmdstr[1]))) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %c%c for command %c%c\n", __func__, buffer[0], buffer[1], cmdstr[0], cmdstr[1]); rig_debug(RIG_DEBUG_ERR, "%s: retry_read=%d, rp->retry=%d\n", __func__, retry_read, rp->retry); if (retry_read++ < rp->retry) { if (strlen(buffer) == 0) { goto transaction_write; // didn't get an answer so send again } else { // should be able to handle transceive mode here goto transaction_read; // might be an async or corrupt reply so we'll read until timeout } } retval = -RIG_EPROTO; goto transaction_quit; } if (retval > 0) { /* move the result excluding the command terminator into the caller buffer */ len = min(datasize, retval) - 1; strncpy(data, buffer, len); data[len] = '\0'; } } else { rig_debug(RIG_DEBUG_TRACE, "%s: No data expected, checking %s in %s\n", __func__, priv->verify_cmd, buffer); // seems some rigs will send back an IF response to RX/TX when it changes the status // normally RX/TX returns nothing when it's a null effect // TS-950SDX is known to behave this way if (strncmp(cmdstr, "RX", 2) == 0 || strncmp(cmdstr, "TX", 2) == 0) { if (strncmp(priv->verify_cmd, "IF", 2) == 0) { rig_debug(RIG_DEBUG_TRACE, "%s: RX/TX got IF response so we're good\n", __func__); goto transaction_quit; } } if (priv->verify_cmd[0] != buffer[0] || (priv->verify_cmd[1] && priv->verify_cmd[1] != buffer[1])) { /* * TODO: When RIG_TRN is enabled, we can pass the string to * the decoder for callback. That way we don't ignore any * commands. */ // if we got FA or FB unexpectedly then perhaps RIG_TRN is enabled and we just need to handle it if (strncmp(buffer, "FA", 2) == 0) { freq_t freq; sscanf(buffer, "FA%lg", &freq); rig_set_cache_freq(rig, RIG_VFO_A, freq); goto transaction_read; } else if (strncmp(buffer, "FB", 2) == 0) { freq_t freq; sscanf(buffer, "FB%lg", &freq); rig_set_cache_freq(rig, RIG_VFO_B, freq); goto transaction_read; } rig_debug(RIG_DEBUG_ERR, "%s: wrong reply %c%c for command verification %c%c\n", __func__, buffer[0], buffer[1] , priv->verify_cmd[0], priv->verify_cmd[1]); if (retry_read++ < rp->retry) { goto transaction_write; } retval = -RIG_EPROTO; goto transaction_quit; } } retval = RIG_OK; rig_debug(RIG_DEBUG_TRACE, "%s: returning RIG_OK, retval=%d\n", __func__, retval); transaction_quit: // update the cache if (retval == RIG_OK && cmdstr && strcmp(cmdstr, "IF") == 0) { elapsed_ms(&priv->cache_start, HAMLIB_ELAPSED_SET); strncpy(priv->last_if_response, buffer, caps->if_len); } rs->transaction_active = 0; RETURNFUNC2(retval); } /** * kenwood_safe_transaction * A wrapper for kenwood_transaction to check returned data against * expected length, * * Parameters: * cmd Same as kenwood_transaction() cmdstr * buf Same as kenwwod_transaction() data * buf_size Same as kenwood_transaction() datasize * expected Value of expected string length * * Returns: * RIG_OK - if no error occurred. * RIG_EPROTO if returned string and expected are not equal * Error from kenwood_transaction() if any * */ int kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected) { int err; int retry = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called, cmd=%s, expected=%d\n", __func__, cmd, (int)expected); if (!cmd) { RETURNFUNC2(-RIG_EINVAL); } memset(buf, 0, buf_size); if (expected == 0) { buf_size = 0; } do { size_t length; // some PowerSDR commands have variable len int checklen = !RIG_IS_POWERSDR && !RIG_IS_THETIS; err = kenwood_transaction(rig, cmd, buf, buf_size); if (err != RIG_OK) /* return immediately on error as any retries handled at lower level */ { RETURNFUNC2(err); } length = strlen(buf); if (checklen && length != expected) /* worth retrying as some rigs occasionally send short results */ { // QRPLABS can't seem top decide if they give 37 or 38 bytes for IF command if (strncmp(cmd, "IF", 2) == 0 && rig->caps->rig_model == RIG_MODEL_QRPLABS) { break; } struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_ERR, "%s: wrong answer; len for cmd %s: expected = %d, got %d\n", __func__, cmd, (int)expected, (int)length); err = -RIG_EPROTO; elapsed_ms(&priv->cache_start, HAMLIB_ELAPSED_INVALIDATE); hl_usleep(50 * 1000); // let's do a short wait } } while (err != RIG_OK && ++retry < RIGPORT(rig)->retry); RETURNFUNC2(err); } rmode_t kenwood2rmode(unsigned char mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (mode >= KENWOOD_MODE_TABLE_MAX) { return (RIG_MODE_NONE); } return (mode_table[mode]); } char rmode2kenwood(rmode_t mode, const rmode_t mode_table[]) { rig_debug(RIG_DEBUG_VERBOSE, "%s called, mode=%s\n", __func__, rig_strrmode(mode)); if (mode != RIG_MODE_NONE) { int i; for (i = 0; i < KENWOOD_MODE_TABLE_MAX; i++) { if (mode_table[i] == mode) { rig_debug(RIG_DEBUG_VERBOSE, "%s: returning %d\n", __func__, i); return (i); } } } return (-1); } int kenwood_init(RIG *rig) { struct kenwood_priv_data *priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called, version %s/%s\n", __func__, BACKEND_VER, rig->caps->version); STATE(rig)->priv = calloc(1, sizeof(struct kenwood_priv_data)); if (STATE(rig)->priv == NULL) { RETURNFUNC2(-RIG_ENOMEM); } priv = STATE(rig)->priv; memset(priv, 0x00, sizeof(struct kenwood_priv_data)); if (RIG_IS_XG3) { priv->verify_cmd[0] = caps->cmdtrm; priv->verify_cmd[1] = '\0'; } else { priv->verify_cmd[0] = 'I'; priv->verify_cmd[1] = 'D'; priv->verify_cmd[2] = caps->cmdtrm; priv->verify_cmd[3] = '\0'; } priv->split = RIG_SPLIT_OFF; priv->trn_state = -1; priv->curr_mode = 0; priv->micgain_min = -1; priv->micgain_max = -1; priv->has_ps = 1; // until proven otherwise if (rig->caps->rig_model == RIG_MODEL_TS450S || rig->caps->rig_model == RIG_MODEL_TS50 || rig->caps->rig_model == RIG_MODEL_TS140S || rig->caps->rig_model == RIG_MODEL_TS2000 || rig->caps->rig_model == RIG_MODEL_TS440 || rig->caps->rig_model == RIG_MODEL_QRPLABS) { priv->has_ps = 0; } /* default mode_table */ if (caps->mode_table == NULL) { caps->mode_table = kenwood_mode_table; } /* default if_len */ if (caps->if_len == 0) { caps->if_len = 37; } priv->ag_format = -1; // force determination of AG format rig_debug(RIG_DEBUG_TRACE, "%s: if_len = %d\n", __func__, caps->if_len); // SDRUno uses mode 8 for DIG if (rig->caps->rig_model == RIG_MODEL_SDRUNO) { kenwood_mode_table[8] = RIG_MODE_PKTUSB; } RETURNFUNC2(RIG_OK); } int kenwood_cleanup(RIG *rig) { ENTERFUNC; free(STATE(rig)->priv); STATE(rig)->priv = NULL; RETURNFUNC(RIG_OK); } int kenwood_open(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); int err, i; char *idptr; char id[KENWOOD_MAX_BUF_LEN]; int retry_save = RIGPORT(rig)->retry; ENTERFUNC; id[0] = 0; RIGPORT(rig)->retry = 0; priv->question_mark_response_means_rejected = 0; if (STATE(rig)->auto_power_on) { // Ensure rig is on rig_set_powerstat(rig, 1); sleep(1); } err = kenwood_get_id(rig, id); if (err != RIG_OK) { // TS450S is flaky on the 1st ID call so we'll try again hl_usleep(200 * 1000); err = kenwood_get_id(rig, id); } if (err == RIG_OK && priv->has_ps) // some rigs give ID while in standby { powerstat_t powerstat = 0; rig_debug(RIG_DEBUG_TRACE, "%s: got ID so try PS\n", __func__); err = rig_get_powerstat(rig, &powerstat); if (err == RIG_OK && powerstat == 0 && priv->poweron == 0 && STATE(rig)->auto_power_on) { priv->has_ps = 1; rig_debug(RIG_DEBUG_TRACE, "%s: got PS0 so powerup\n", __func__); rig_set_powerstat(rig, 1); } else if (err == -RIG_ETIMEOUT) // Some rigs like TS-450 don't have PS cmd { priv->has_ps = 0; } priv->poweron = 1; err = RIG_OK; // reset our err back to OK for later checks } if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: no response to get_id from rig...continuing anyway\n", __func__); } if (RIG_IS_TS2000 || RIG_IS_TS480 || RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS890S || RIG_IS_TS990S) { // rig has Set 2 RIT/XIT function rig_debug(RIG_DEBUG_TRACE, "%s: rig has_rit2\n", __func__); priv->has_rit2 = 1; } if (RIG_IS_TS590S || RIG_IS_TS990S) { /* we need the firmware version for these rigs to deal with f/w defects */ static char fw_version[7]; err = kenwood_transaction(rig, "FV", fw_version, sizeof(fw_version)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version, defaulting to 1.0\n", __func__); RIGPORT(rig)->retry = retry_save; priv->fw_rev_uint = 100; } else { char *dot_pos; /* store the data after the "FV" which should be a f/w version string of the form n.n e.g. 1.07 */ priv->fw_rev = &fw_version[2]; dot_pos = strchr(fw_version, '.'); if (dot_pos) { priv->fw_rev_uint = atoi(&fw_version[2]) * 100 + atoi(dot_pos + 1); } else { rig_debug(RIG_DEBUG_ERR, "%s: cannot get f/w version\n", __func__); RIGPORT(rig)->retry = retry_save; RETURNFUNC(-RIG_EPROTO); } } rig_debug(RIG_DEBUG_TRACE, "%s: found f/w version %.2f\n", __func__, priv->fw_rev_uint / 100.0); } if (!RIG_IS_XG3 && -RIG_ETIMEOUT == err) { char buffer[KENWOOD_MAX_BUF_LEN]; /* Some Kenwood emulations have no ID command response :( * Try an FA command to see if anyone is listening */ err = kenwood_transaction(rig, "FA", buffer, sizeof(buffer)); if (RIG_OK != err) { rig_debug(RIG_DEBUG_ERR, "%s: no response from rig\n", __func__); RIGPORT(rig)->retry = retry_save; RETURNFUNC(err); } /* here we know there is something that responds to FA but not to ID so use FA as the command verification command */ priv->verify_cmd[0] = 'F'; priv->verify_cmd[1] = 'A'; priv->verify_cmd[2] = caps->cmdtrm; priv->verify_cmd[3] = '\0'; strcpy(id, "ID019"); /* fake a TS-2000 */ } else { if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: cannot get identification\n", __func__); RIGPORT(rig)->retry = retry_save; RETURNFUNC(err); } } /* id is something like 'IDXXX' or 'ID XXX' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_ERR, "%s: unknown id type (%s)...continuing\n", __func__, id); // Malachite SDR gives no response to ID and is supposed to be TS480 compatible if (RIG_IS_MALACHITE) { strcpy(id, "ID020"); } } if (!strcmp("IDID900", id) /* DDUtil in TS-2000 mode */ || !strcmp("ID900", id) /* PowerSDR after ZZID; command */ || !strcmp("ID904", id) /* SmartSDR Flex-6700 */ || !strcmp("ID905", id) /* PowerSDR Flex-6500 */ || !strcmp("ID906", id) /* PowerSDR Flex-6700R */ || !strcmp("ID907", id) /* PowerSDR Flex-6300 */ || !strcmp("ID908", id) /* PowerSDR Flex-6400 */ || !strcmp("ID909", id) /* PowerSDR Flex-6600 */ ) { priv->is_emulation = 1; /* Emulations don't have SAT mode */ strcpy(id, "ID019"); /* fake it */ } /* check for a white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } /* compare id string */ for (i = 0; kenwood_id_string_list[i].model != RIG_MODEL_NONE; i++) { //rig_debug(RIG_DEBUG_ERR, "%s: comparing '%s'=='%s'\n", __func__, kenwood_id_string_list[i].id, idptr); if (strcmp(kenwood_id_string_list[i].id, idptr) != 0) { continue; } /* found matching id, verify driver */ rig_debug(RIG_DEBUG_TRACE, "%s: found match %s\n", __func__, kenwood_id_string_list[i].id); // current vfo is rx_vfo rig_get_vfo(rig, &STATE(rig)->rx_vfo); if (kenwood_id_string_list[i].model == rig->caps->rig_model) { vfo_t tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: found the right driver for %s(%u)\n", __func__, rig->caps->model_name, rig->caps->rig_model); /* get current AI state so it can be restored */ if (rig->caps->rig_model != RIG_MODEL_PT8000A) // doesn't know AI command { kenwood_get_trn(rig, &priv->trn_state); /* ignore errors */ } /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ if (priv->trn_state != RIG_TRN_OFF) { kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ } if (!RIG_IS_THD74 && !RIG_IS_THD7A && !RIG_IS_TMD700) { int retval; // call get_split to fill in current split and tx_vfo status split_t split; retval = kenwood_get_split_vfo_if(rig, RIG_VFO_A, &split, &tx_vfo); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s\n", __func__, rigerror(retval)); } priv->tx_vfo = tx_vfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); } RIGPORT(rig)->retry = retry_save; RETURNFUNC(RIG_OK); } /* driver mismatch */ // SDRCONSOLE identifies as TS-2000 -- even though it's a sub/superset if (rig->caps->rig_model == RIG_MODEL_SDRCONSOLE && kenwood_id_string_list[i].model != 2014) { rig_debug(RIG_DEBUG_VERBOSE, "%s: not the right driver apparently (found %u, asked for %d, checked %s)\n", __func__, rig->caps->rig_model, kenwood_id_string_list[i].model, rig->caps->model_name); } // we continue to search for other matching IDs/models } rig_debug(RIG_DEBUG_VERBOSE, "%s: your rig (%s) did not match but we will continue anyways\n", __func__, id); // we're making this non fatal // mismatched IDs can still be tested RIGPORT(rig)->retry = retry_save; RETURNFUNC(RIG_OK); } int kenwood_close(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (priv->poweron == 0) { RETURNFUNC(RIG_OK); } // nothing to do if (!no_restore_ai && priv->trn_state >= 0) { /* restore AI state */ kenwood_set_trn(rig, priv->trn_state); /* ignore status in case it's not supported */ } if (STATE(rig)->auto_power_off) { rig_debug(RIG_DEBUG_TRACE, "%s: got PS1 so powerdown\n", __func__); rig_set_powerstat(rig, 0); } RETURNFUNC(RIG_OK); } /* ID * Reads transceiver ID number * * caller must give a buffer of KENWOOD_MAX_BUF_LEN size * */ int kenwood_get_id(RIG *rig, char *buf) { ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_K4) { kenwood_transaction(rig, "K40", NULL, 0); } RETURNFUNC(kenwood_transaction(rig, "ID", buf, KENWOOD_MAX_BUF_LEN)); } /* IF * Retrieves the transceiver status * */ int kenwood_get_if(RIG *rig) { struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); int retval; int post_write_delay_save = 0; ENTERFUNC; // Malachite has a 400ms delay but some get commands can work with no delay if (RIG_IS_MALACHITE) { post_write_delay_save = STATE(rig)->post_write_delay; STATE(rig)->post_write_delay = 0; } retval = kenwood_safe_transaction(rig, "IF", priv->info, KENWOOD_MAX_BUF_LEN, caps->if_len); if (RIG_IS_MALACHITE) { STATE(rig)->post_write_delay = post_write_delay_save; } RETURNFUNC(retval); } /* FN FR FT * Sets the RX/TX VFO or M.CH mode of the transceiver, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int kenwood_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[12]; int retval; char vfo_function; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s, is_emulation=%d, curr_mode=%s\n", __func__, rig_strvfo(vfo), priv->is_emulation, rig_strrmode(priv->curr_mode)); /* Emulations do not need to set VFO since VFOB is a copy of VFOA * except for frequency. And we can change freq without changing VFOS * This prevents a 1.8 second delay in PowerSDR when switching VFOs * We'll do this once if curr_mode has not been set yet */ if (vfo == RIG_VFO_B && priv->is_emulation && priv->curr_mode > 0) { HAMLIB_TRACE; RETURNFUNC(RIG_OK); } #if 0 if (STATE(rig)->current_vfo == vfo) { rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo already is %s...skipping\n", __func__, rig_strvfo(vfo)); RETURNFUNC(RIG_OK); } #endif switch (vfo) { case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_TX: vfo_function = STATE(rig)->tx_vfo == RIG_VFO_B ? '1' : '0'; break; #if 0 // VFO_RX really should NOT be VFO_CURR as VFO_CURR could be either VFO case RIG_VFO_RX: vfo_function = STATE(rig)->rx_vfo == RIG_VFO_B ? '1' : '0'; break; #endif case RIG_VFO_CURR: HAMLIB_TRACE; STATE(rig)->current_vfo = RIG_VFO_CURR; RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } //if rig=ts2000 then check Satellite mode status if (RIG_IS_TS2000 && !priv->is_emulation) { char retbuf[20]; rig_debug(RIG_DEBUG_VERBOSE, "%s: checking satellite mode status\n", __func__); SNPRINTF(cmdbuf, sizeof(cmdbuf), "SA"); retval = kenwood_transaction(rig, cmdbuf, retbuf, 18); if (retval != RIG_OK) { RETURNFUNC(retval); } rig_debug(RIG_DEBUG_VERBOSE, "%s: satellite mode status %s\n", __func__, retbuf); //Satellite mode ON if (retbuf[2] == '1') { //SAT mode doesn't allow FR command (cannot select VFO) //selecting VFO is useless in SAT MODE RETURNFUNC(RIG_OK); } } HAMLIB_TRACE; SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c", vfo_function); // as we change VFO we will change split to the other VFO // some rigs turn split off with FR command if (priv->split) { if (vfo_function == '0') { strcat(cmdbuf, ";FT1"); } else { strcat(cmdbuf, ";FT0"); } } if (RIG_IS_TS50 || RIG_IS_TS940) { cmdbuf[1] = 'N'; } /* set RX VFO */ retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } HAMLIB_TRACE; STATE(rig)->current_vfo = vfo; /* if FN command then there's no FT or FR */ /* If split mode on, the don't change TxVFO */ if ('N' == cmdbuf[1] || priv->split != RIG_SPLIT_OFF) { RETURNFUNC(RIG_OK); } HAMLIB_TRACE; // some rigs need split turned on after VFOA is set if (priv->split == RIG_SPLIT_ON) { // so let's figure out who the rx_vfo is based on the tx_vfo HAMLIB_TRACE; vfo_t rx_vfo = RIG_VFO_A; switch (priv->tx_vfo) { case RIG_VFO_A: rx_vfo = RIG_VFO_B; break; case RIG_VFO_MAIN: rx_vfo = RIG_VFO_SUB; break; case RIG_VFO_MAIN_A: rx_vfo = RIG_VFO_MAIN_B; break; case RIG_VFO_B: rx_vfo = RIG_VFO_A; break; case RIG_VFO_SUB: rx_vfo = RIG_VFO_MAIN; break; case RIG_VFO_SUB_B: rx_vfo = RIG_VFO_MAIN_A; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unhandled VFO=%s, deafaulting to VFOA\n", __func__, rig_strvfo(priv->tx_vfo)); } retval = rig_set_split_vfo(rig, rx_vfo, 1, priv->tx_vfo); } #if 0 /* set TX VFO */ cmdbuf[1] = 'T'; RETURNFUNC(kenwood_transaction(rig, cmdbuf, NULL, 0)); #else RETURNFUNC(retval); #endif } /* CB * Sets the operating VFO, does not set split * VFO, but leaves it unchanged if in split VFO mode. * */ int kenwood_set_vfo_main_sub(RIG *rig, vfo_t vfo) { char cmdbuf[6]; char vfo_function; ENTERFUNC; switch (vfo) { case RIG_VFO_MAIN: vfo_function = '0'; break; case RIG_VFO_SUB: vfo_function = '1'; break; case RIG_VFO_CURR: RETURNFUNC(RIG_OK); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "CB%c", vfo_function); RETURNFUNC(kenwood_transaction(rig, cmdbuf, NULL, 0)); } /* CB * Gets the operating VFO * */ int kenwood_get_vfo_main_sub(RIG *rig, vfo_t *vfo) { char buf[4]; int rc; ENTERFUNC; if (!vfo) { RETURNFUNC(-RIG_EINVAL); } if (RIG_OK == (rc = kenwood_safe_transaction(rig, "CB", buf, sizeof(buf), 3))) { *vfo = buf[2] == '1' ? RIG_VFO_SUB : RIG_VFO_MAIN; } RETURNFUNC(rc); } /* FR FT TB * Sets the split RX/TX VFO or M.CH mode of the transceiver. * */ int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char cmdbuf[12]; int retval; unsigned char vfo_function; split_t tsplit = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called %s,%d,%s\n", __func__, rig_strvfo(vfo), split, rig_strvfo(txvfo)); if (RIG_IS_TS990S) { if (split) { // Rx MAIN/Tx SUB is the only split method retval = kenwood_set_vfo_main_sub(rig, RIG_VFO_MAIN); if (retval != RIG_OK) { RETURNFUNC2(retval); } } SNPRINTF(cmdbuf, sizeof(cmdbuf), "TB%c", RIG_SPLIT_ON == split ? '1' : '0'); RETURNFUNC2(kenwood_transaction(rig, cmdbuf, NULL, 0)); } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } if (vfo == RIG_VFO_TX || vfo == RIG_VFO_RX) { vfo = vfo_fixup(rig, vfo, split); } switch (vfo) { case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } vfo_t tx_vfo; rig_get_split_vfo(rig, vfo, &tsplit, &tx_vfo); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): tsplit=%d, split=%d\n", __func__, __LINE__, tsplit, split); if (tsplit == split) { rig_debug(RIG_DEBUG_TRACE, "%s: split already set\n", __func__); RETURNFUNC2(RIG_OK); } /* set RX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c", vfo_function); // FR can turn off split on some Kenwood rigs // So we'll turn it back on just in case HAMLIB_TRACE; if (split) { if (vfo_function == '0') { HAMLIB_TRACE; strcat(cmdbuf, ";FT1"); } else { HAMLIB_TRACE; strcat(cmdbuf, ";FT0"); } } else { HAMLIB_TRACE; strcat(cmdbuf, ";FT0"); } retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC2(retval); } /* Split off means Rx and Tx are the same */ if (split == RIG_SPLIT_OFF) { txvfo = vfo; if (txvfo == RIG_VFO_CURR) { retval = rig_get_vfo(rig, &txvfo); if (retval != RIG_OK) { RETURNFUNC2(retval); } } } if (txvfo == RIG_VFO_CURR && vfo == RIG_VFO_A) { if (vfo == RIG_VFO_A) { txvfo = RIG_VFO_B; } else if (vfo == RIG_VFO_B) { txvfo = RIG_VFO_A; } else { rig_debug(RIG_DEBUG_ERR, "%s: unsupported split VFO=%s\n", __func__, rig_strvfo(txvfo)); RETURNFUNC2(-RIG_EINVAL); } } txvfo = vfo_fixup(rig, txvfo, RIG_SPLIT_ON); priv->tx_vfo = txvfo; /* do not attempt redundant split change commands on Elecraft as they impact output power when transmitting and all other rigs don't need to set it if it's already set correctly */ tsplit = RIG_SPLIT_OFF; // default in case rig does not set split status retval = rig_get_split_vfo(rig, vfo, &tsplit, &tx_vfo); priv->split = CACHE(rig)->split = split; CACHE(rig)->split_vfo = txvfo; elapsed_ms(&CACHE(rig)->time_split, HAMLIB_ELAPSED_SET); // and it should be OK to do a SPLIT_OFF at any time so we won's skip that if (retval == RIG_OK && split == RIG_SPLIT_ON && tsplit == RIG_SPLIT_ON) { rig_debug(RIG_DEBUG_VERBOSE, "%s: already set split=%d\n", __func__, tsplit); RETURNFUNC2(RIG_OK); } rig_debug(RIG_DEBUG_VERBOSE, "%s: split is=%d, split wants=%d\n", __func__, tsplit, split); /* set TX VFO */ // if turning on split need to do some VFOB setup on Elecraft rigs to avoid SPLIT N/A and ER59 messages if (rig->caps->rig_model == RIG_MODEL_K4 // Elecraft needs VFOB to be same band as VFOA || rig->caps->rig_model == RIG_MODEL_K3 || rig->caps->rig_model == RIG_MODEL_KX2 || rig->caps->rig_model == RIG_MODEL_KX3) { rig_set_freq(rig, RIG_VFO_B, CACHE(rig)->freqMainA); } if (retval != RIG_OK) { RETURNFUNC2(retval); } /* Remember whether split is on, for kenwood_set_vfo */ priv->split = CACHE(rig)->split = split; elapsed_ms(&CACHE(rig)->time_split, HAMLIB_ELAPSED_SET); RETURNFUNC2(RIG_OK); } /* SP * Sets the split mode of the transceivers that have the FN command. * */ int kenwood_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { struct kenwood_priv_data *priv = STATE(rig)->priv; char cmdbuf[6]; int retval; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "SP%c", RIG_SPLIT_ON == split ? '1' : '0'); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } /* Remember whether split is on, for kenwood_set_vfo */ priv->split = split; priv->tx_vfo = txvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); RETURNFUNC(RIG_OK); } /* IF * Gets split VFO status from kenwood_get_if() * */ int kenwood_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo) { int transmitting; int retval; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; ENTERFUNC; if (!split || !txvfo) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (priv->info[32]) { case '0': *split = RIG_SPLIT_OFF; break; case '1': *split = RIG_SPLIT_ON; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported split %c\n", __func__, priv->info[32]); RETURNFUNC(-RIG_EPROTO); } /* Remember whether split is on, for kenwood_set_vfo */ priv->split = *split; /* find where is the txvfo.. */ /* Elecraft info[30] does not track split VFO when transmitting */ transmitting = '1' == priv->info[28] && !RIG_IS_K2 && !RIG_IS_K3; switch (priv->info[30]) { case '0': rs->rx_vfo = STATE(rig)->current_vfo; if (rs->rx_vfo == RIG_VFO_A) { HAMLIB_TRACE; *txvfo = rs->tx_vfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else if (rs->rx_vfo == RIG_VFO_B) { HAMLIB_TRACE; *txvfo = rs->tx_vfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else if (rs->rx_vfo == RIG_VFO_CURR) { HAMLIB_TRACE; *txvfo = rs->tx_vfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else { rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown rx_vfo=%s\n", __func__, __LINE__, rig_strvfo(rs->rx_vfo)); *txvfo = RIG_VFO_A; // pick a default rs->rx_vfo = priv->tx_vfo = RIG_VFO_A; } break; case '1': if (rs->rx_vfo == RIG_VFO_A) { HAMLIB_TRACE; *txvfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_A : RIG_VFO_B; } else if (rs->rx_vfo == RIG_VFO_B) { HAMLIB_TRACE; *txvfo = priv->tx_vfo = (*split && !transmitting) ? RIG_VFO_B : RIG_VFO_A; } else { rig_debug(RIG_DEBUG_WARN, "%s(%d): unknown rx_vfo=%s\n", __func__, __LINE__, rig_strvfo(rs->rx_vfo)); *txvfo = RIG_VFO_A; // pick a default rs->rx_vfo = RIG_VFO_A; } break; case '2': *txvfo = priv->tx_vfo = RIG_VFO_MEM; /* SPLIT MEM operation doesn't involve VFO A or VFO B */ break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); RETURNFUNC(-RIG_EPROTO); } priv->tx_vfo = *txvfo; rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s, split=%d\n", __func__, rig_strvfo(priv->tx_vfo), *split); RETURNFUNC(RIG_OK); } /* * kenwood_get_vfo_if using byte 31 of the IF information field * * Specifically this needs to return the RX VFO, the IF command tells * us the TX VFO in split TX mode when transmitting so we need to swap * results sometimes. */ int kenwood_get_vfo_if(RIG *rig, vfo_t *vfo) { int retval; int split_and_transmitting; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; ENTERFUNC; if (!vfo) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } /* Elecraft info[30] does not track split VFO when transmitting */ split_and_transmitting = '1' == priv->info[28] /* transmitting */ && '1' == priv->info[32] /* split */ && !RIG_IS_K2 && !RIG_IS_K3; switch (priv->info[30]) { case '0': *vfo = rs->rx_vfo = rs->tx_vfo = priv->tx_vfo = split_and_transmitting ? RIG_VFO_B : RIG_VFO_A; if (priv->info[32] == '1') { priv->tx_vfo = rs->tx_vfo = RIG_VFO_B; } break; case '1': *vfo = split_and_transmitting ? RIG_VFO_A : RIG_VFO_B; priv->tx_vfo = RIG_VFO_B; break; case '2': *vfo = priv->tx_vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %c\n", __func__, priv->info[30]); RETURNFUNC(-RIG_EPROTO); } rig_debug(RIG_DEBUG_VERBOSE, "%s: priv->tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); RETURNFUNC(RIG_OK); } /* * kenwood_set_freq */ int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[16]; unsigned char vfo_letter = '\0'; vfo_t tvfo; freq_t tfreq = 0; int err; struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s freq=%.0f\n", __func__, rig_strvfo(vfo), freq); tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; rig_debug(RIG_DEBUG_TRACE, "%s: tvfo=%s\n", __func__, rig_strvfo(tvfo)); if (tvfo == RIG_VFO_CURR || tvfo == RIG_VFO_NONE) { /* fetch from rig */ err = rig_get_vfo(rig, &tvfo); if (RIG_OK != err) { RETURNFUNC2(err); } } // Malchite is so slow we don't do the get_freq // And when we have detected Doppler operations we just set the freq all the time // This should provide stable timing for set_ptt operation so relay delays are consistent if (!RIG_IS_MALACHITE && STATE(rig)->doppler == 0) { rig_get_freq(rig, tvfo, &tfreq); if (tfreq == freq) { rig_debug(RIG_DEBUG_TRACE, "%s: no freq change needed\n", __func__); RETURNFUNC2(RIG_OK); } } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; case RIG_VFO_TX: if (priv->tx_vfo == RIG_VFO_A) { vfo_letter = 'A'; } else if (priv->tx_vfo == RIG_VFO_B) { vfo_letter = 'B'; } else { rig_debug(RIG_DEBUG_ERR, "%s: unsupported tx_vfo, tx_vfo=%s\n", __func__, rig_strvfo(priv->tx_vfo)); } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(freqbuf, sizeof(freqbuf), "F%c%011"PRIll, vfo_letter, (int64_t)freq); // we need to modify priv->verify_cmd if ID is not being used // if FB command than we change to FB and back again to avoid VFO blinking if (priv->verify_cmd[1] == 'A' && vfo_letter == 'B') { priv->verify_cmd[1] = 'A'; } err = kenwood_transaction(rig, freqbuf, NULL, 0); hl_usleep(50 * 1000); // TS480 is slow to change freq so give it some time as well as others just in case if (priv->verify_cmd[1] == 'B' && vfo_letter == 'B') { priv->verify_cmd[1] = 'A'; } if (RIG_OK == err && RIG_IS_TS590S && priv->fw_rev_uint <= 107 && ('A' == vfo_letter || 'B' == vfo_letter)) { /* TS590s f/w rev 1.07 or earlier has a defect that means frequency set on TX VFO in split mode may not be set correctly. The symptom of the defect is either TX on the wrong frequency (i.e. TX on a frequency different from that showing on the TX VFO) or no output. We use an IF command to find out if we have just set the "back" VFO when the rig is in split mode. If we have; we then read the other VFO and set it to what we read - a null transaction that fixes the defect. */ err = kenwood_get_if(rig); if (RIG_OK != err) { RETURNFUNC2(err); } if ('1' == priv->info[32] && priv->info[30] != ('A' == vfo_letter ? '0' : '1')) { /* split mode and setting "back" VFO */ /* set other VFO to whatever it is at currently */ err = kenwood_safe_transaction(rig, 'A' == vfo_letter ? "FB" : "FA", freqbuf, 16, 13); if (RIG_OK != err) { RETURNFUNC2(err); } err = kenwood_transaction(rig, freqbuf, NULL, 0); } } RETURNFUNC2(err); } int kenwood_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq) { struct kenwood_priv_data *priv = STATE(rig)->priv; char freqbuf[50]; int retval; ENTERFUNC; if (!freq) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(freqbuf, priv->info, 15); freqbuf[14] = '\0'; sscanf(freqbuf + 2, "%"SCNfreq, freq); RETURNFUNC(RIG_OK); } /* * kenwood_get_freq */ int kenwood_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { char freqbuf[50]; char cmdbuf[4]; int retval; unsigned char vfo_letter = '\0'; vfo_t tvfo; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!freq) { RETURNFUNC(-RIG_EINVAL); } tvfo = (vfo == RIG_VFO_CURR || vfo == RIG_VFO_VFO) ? STATE(rig)->current_vfo : vfo; if (RIG_VFO_CURR == tvfo) { /* fetch from rig */ retval = rig_get_vfo(rig, &tvfo); if (RIG_OK != retval) { RETURNFUNC(retval); } } /* memory frequency cannot be read with an Fx command, use IF */ if (tvfo == RIG_VFO_MEM) { RETURNFUNC(kenwood_get_freq_if(rig, vfo, freq)); } switch (tvfo) { case RIG_VFO_A: case RIG_VFO_MAIN: vfo_letter = 'A'; break; case RIG_VFO_B: case RIG_VFO_SUB: vfo_letter = 'B'; break; case RIG_VFO_C: vfo_letter = 'C'; break; case RIG_VFO_TX: if (priv->split) { vfo_letter = 'B'; } // always assume B is the TX VFO else { vfo_letter = 'A'; } break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_MALACHITE && vfo == RIG_VFO_B) { // Malachite does not have VFOB so we'll just return VFOA *freq = 0; RETURNFUNC(RIG_OK); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "F%c", vfo_letter); retval = kenwood_safe_transaction(rig, cmdbuf, freqbuf, 50, 13); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(freqbuf + 2, "%"SCNfreq, freq); RETURNFUNC(RIG_OK); } int kenwood_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } // TODO: Fix for different rigs memcpy(buf, &priv->info[17], 6); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } /* RF * kenwood_get_rit_new (also usable as kenwood_get_xit_new) * Gets the RIT or XIT value using dedicated command * and without using IF. */ int kenwood_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval, tempf; char rfbuf[10]; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_safe_transaction(rig, "RF", rfbuf, sizeof rfbuf, 7); if (retval != RIG_OK) {RETURNFUNC(retval); } tempf = atoi(rfbuf + 3); if (rfbuf[2] == '1') { tempf = -tempf; } *rit = tempf; RETURNFUNC(RIG_OK); } /* * rit can only move up/down by 10 Hz, so we use a loop... */ int kenwood_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[32]; int retval, i; int diff; int rit_enabled; int xit_enabled; shortfreq_t curr_rit; struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called: vfo=%s, rit=%ld\n", __func__, rig_strvfo(vfo), rit); // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC2(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC2(retval); } } // by getting current rit we can determine how to handle change // we just use curr_rit - rit to determine how far we need to move // No need to zero out rit retval = kenwood_get_rit(rig, RIG_VFO_CURR, &curr_rit); if (retval != RIG_OK) { RETURNFUNC2(retval); } #if 0 // no longer needed if diff can be done retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC2(retval); } #endif if (rit == 0 && curr_rit == 0) { RETURNFUNC2(RIG_OK); } if (priv->has_rit2) { diff = rit - curr_rit; rig_debug(RIG_DEBUG_TRACE, "%s: rit=%ld, curr_rit=%ld, diff=%d\n", __func__, rit, curr_rit, diff); SNPRINTF(buf, sizeof(buf), "R%c%05d", (diff > 0) ? 'U' : 'D', abs((int) diff)); retval = kenwood_transaction(rig, buf, NULL, 0); } else { SNPRINTF(buf, sizeof(buf), "R%c", (rit > 0) ? 'U' : 'D'); diff = labs(((curr_rit - rit) + (curr_rit - rit) >= 0 ? 5 : -5) / 10); // round to nearest 10Hz rig_debug(RIG_DEBUG_TRACE, "%s: rit=%ld, curr_rit=%ld, diff=%d\n", __func__, rit, curr_rit, diff); rig_debug(RIG_DEBUG_TRACE, "%s: rit change loop=%d\n", __func__, diff); for (i = 0; i < diff; i++) { retval = kenwood_transaction(rig, buf, NULL, 0); } } RETURNFUNC2(retval); } /* RU/RD * Set the RIT/XIT frequency offset * using dedicated commands (not IF) */ int kenwood_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t rit) { int retval, diff; shortfreq_t oldrit; char rdbuf[10]; ENTERFUNC; if (abs(rit) > 9999) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_rit_new(rig, vfo, &oldrit); if (retval != RIG_OK) { RETURNFUNC(retval); } if (rit == oldrit) // if the new value is the same { RETURNFUNC(RIG_OK); // Nothing to do } diff = rit - oldrit; SNPRINTF(rdbuf, sizeof rdbuf, "R%c%05d;", diff < 0 ? 'D' : 'U', abs(diff)); retval = kenwood_transaction(rig, rdbuf, NULL, 0); RETURNFUNC(retval); } /* * rit and xit are the same */ int kenwood_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { ENTERFUNC; RETURNFUNC(kenwood_get_rit(rig, vfo, rit)); } int kenwood_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { ENTERFUNC; RETURNFUNC(kenwood_set_rit(rig, vfo, rit)); } int kenwood_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { ENTERFUNC; if (RIG_IS_TS990S) { RETURNFUNC(kenwood_transaction(rig, scan == RIG_SCAN_STOP ? "SC00" : "SC01", NULL, 0)); } else { RETURNFUNC(kenwood_transaction(rig, scan == RIG_SCAN_STOP ? "SC0" : "SC1", NULL, 0)); } } /* * 000 No select * 002 FM Wide * 003 FM Narrow * 005 AM * 007 SSB * 009 CW * 010 CW NARROW */ /* XXX revise */ static int kenwood_set_filter(RIG *rig, pbwidth_t width) { char *cmd; ENTERFUNC; if (width <= Hz(250)) { cmd = "FL010009"; } else if (width <= Hz(500)) { cmd = "FL009009"; } else if (width <= kHz(2.7)) { cmd = "FL007007"; } else if (width <= kHz(6)) { cmd = "FL005005"; } else { cmd = "FL002002"; } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } static int kenwood_set_filter_width(RIG *rig, rmode_t mode, pbwidth_t width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); struct kenwood_filter_width *selected_filter_width = NULL; char cmd[20]; int i; rig_debug(RIG_DEBUG_VERBOSE, "%s called, width=%ld\n", __func__, width); if (caps->filter_width == NULL) { RETURNFUNC2(-RIG_ENAVAIL); } for (i = 0; caps->filter_width[i].value >= 0; i++) { if (caps->filter_width[i].modes & mode) { selected_filter_width = &caps->filter_width[i]; if (caps->filter_width[i].width_hz >= width) { break; } } } if (selected_filter_width == NULL) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "FW%04d", selected_filter_width->value); RETURNFUNC2(kenwood_transaction(rig, cmd, NULL, 0)); } /* * kenwood_set_mode */ int kenwood_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char c; char kmode; char buf[6]; char data_mode = '0'; char *data_cmd = "DA"; int err; int datamode = 0; int needdata; struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called, vfo=%s, mode=%s, width=%d, curr_vfo=%s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width, rig_strvfo(STATE(rig)->current_vfo)); // we won't set opposite VFO if the mode is the same as requested // setting VFOB mode requires split modifications which cause VFO flashing // this should generally work unless the user changes mode on VFOB // in which case VFOB won't get mode changed until restart if (priv->split && (priv->tx_vfo & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_A))) { if (priv->modeB == mode) { rig_debug(RIG_DEBUG_TRACE, "%s: VFOB mode already %s so ignoring request\n", __func__, rig_strrmode(mode)); return (RIG_OK); } } if (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS950S || RIG_IS_TS950SDX) { /* supports DATA sub modes */ switch (mode) { case RIG_MODE_PKTUSB: data_mode = '1'; mode = RIG_MODE_USB; break; case RIG_MODE_PKTLSB: data_mode = '1'; mode = RIG_MODE_LSB; break; case RIG_MODE_PKTFM: data_mode = '1'; mode = RIG_MODE_FM; break; default: break; } } if (priv->is_emulation || RIG_IS_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ rig_debug(RIG_DEBUG_VERBOSE, "%s: emulate=%d, HPSDR=%d, changing PKT mode to RTTY\n", __func__, priv->is_emulation, RIG_IS_HPSDR); if (RIG_MODE_PKTLSB == mode) { mode = RIG_MODE_RTTY; } if (RIG_MODE_PKTUSB == mode) { mode = RIG_MODE_RTTYR; } } if (RIG_IS_TS990S) { if (mode == RIG_MODE_PKTUSB) { mode = RIG_MODE_USBD1; } if (mode == RIG_MODE_PKTLSB) { mode = RIG_MODE_LSBD1; } } kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); RETURNFUNC2(-RIG_EINVAL); } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } rig_debug(RIG_DEBUG_VERBOSE, "%s: kmode=%d, cmode=%c, datamode=%c\n", __func__, kmode, c, data_mode); if (RIG_IS_TS890S) { char sf[20]; char sfcmd[] = "SF0;"; // TS890 has SF command -- unique so far if (vfo != RIG_VFO_A) { sfcmd[2] = '1'; } err = kenwood_transaction(rig, sfcmd, sf, sizeof(sf)); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, sfcmd, rigerror(err)); return err; } sf[14] = c; err = kenwood_transaction(rig, sf, NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: %s failed: %s\n", __func__, sf, rigerror(err)); } return err; } else if (RIG_IS_TS990S) { /* The TS990s has targetable read mode but can only set the mode of the current VFO :( So we need to toggle the operating VFO to set the "back" VFO mode. This is done here rather than not setting caps.targetable_vfo to not include RIG_TARGETABLE_MODE since the toggle is not required for reading the mode. */ vfo_t curr_vfo; err = kenwood_get_vfo_main_sub(rig, &curr_vfo); if (err != RIG_OK) { RETURNFUNC2(err); } if (vfo != RIG_VFO_CURR && vfo != curr_vfo) { err = kenwood_set_vfo_main_sub(rig, vfo); if (err != RIG_OK) { RETURNFUNC2(err); } } SNPRINTF(buf, sizeof(buf), "OM0%c", c); /* target vfo is ignored */ err = kenwood_transaction(rig, buf, NULL, 0); if (err == RIG_OK && vfo != RIG_VFO_CURR && vfo != curr_vfo) { int err2; err2 = kenwood_set_vfo_main_sub(rig, curr_vfo); if (err2 != RIG_OK) { RETURNFUNC2(err2); } } return RIG_OK; } else { pbwidth_t twidth; err = rig_get_mode(rig, vfo, &priv->curr_mode, &twidth); } if (err != RIG_OK) { RETURNFUNC2(err); } if (data_mode == '1' && (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS950S || RIG_IS_TS950SDX)) { if (RIG_IS_TS950S || RIG_IS_TS950SDX) { data_cmd = "DT"; } datamode = 1; } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, curr_mode=%s, new_mode=%s, datamode=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(priv->curr_mode), rig_strrmode(mode), datamode); // only change mode if needed if (priv->curr_mode != mode) { SNPRINTF(buf, sizeof(buf), "MD%c", c); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: MD cmd failed: %s\n", __func__, rigerror(err)); RETURNFUNC2(err); } } // determine if we need to set datamode on A or B needdata = 0; if (vfo == RIG_VFO_CURR) { HAMLIB_TRACE; vfo = STATE(rig)->current_vfo; } if ((vfo & (RIG_VFO_A | RIG_VFO_MAIN)) && ((priv->datamodeA == 0 && datamode) || (priv->datamodeA == 1 && !datamode))) { needdata = 1; } if ((vfo & (RIG_VFO_B | RIG_VFO_SUB)) && ((priv->datamodeB == 0 && datamode) || (priv->datamodeB == 1 && !datamode))) { needdata = 1; } if (needdata) { /* supports DATA sub modes - see above */ SNPRINTF(buf, sizeof(buf), "%s%c", data_cmd, data_mode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { RETURNFUNC2(err); } } else if (datamode) { rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): datamode set on %s not needed\n", __func__, __LINE__, rig_strvfo(vfo)); } if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC2(RIG_OK); } if (RIG_IS_TS450S || RIG_IS_TS690S || RIG_IS_TS850 || RIG_IS_TS950S || RIG_IS_TS950SDX) { if (RIG_PASSBAND_NORMAL == width) { width = rig_passband_normal(rig, mode); } kenwood_set_filter(rig, width); /* non fatal */ } else if (RIG_IS_TS480) { err = kenwood_set_filter_width(rig, mode, width); if (err != RIG_OK) { // Ignore errors as non-fatal rig_debug(RIG_DEBUG_ERR, "%s: error setting filter width, error: %d\n", __func__, err); } } RETURNFUNC2(RIG_OK); } static int kenwood_get_filter(RIG *rig, pbwidth_t *width) { int err, f, f1, f2; char buf[10]; ENTERFUNC; if (!width) { RETURNFUNC(-RIG_EINVAL); } err = kenwood_safe_transaction(rig, "FL", buf, sizeof(buf), 8); if (err != RIG_OK) { RETURNFUNC(err); } f2 = atoi(&buf[5]); buf[5] = '\0'; f1 = atoi(&buf[2]); if (f2 > f1) { f = f2; } else { f = f1; } switch (f) { case 2: *width = kHz(12); break; case 3: case 5: *width = kHz(6); break; case 7: *width = kHz(2.7); break; case 9: *width = Hz(500); break; case 10: *width = Hz(250); break; } RETURNFUNC(RIG_OK); } static int kenwood_get_filter_width(RIG *rig, rmode_t mode, pbwidth_t *width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char ackbuf[20]; int i; int retval; int filter_value; ENTERFUNC; if (caps->filter_width == NULL) { RETURNFUNC(-RIG_ENAVAIL); } retval = kenwood_safe_transaction(rig, "FW", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "FW%d", &filter_value); for (i = 0; caps->filter_width[i].value >= 0; i++) { if (caps->filter_width[i].modes & mode) { if (caps->filter_width[i].value == filter_value) { *width = caps->filter_width[i].width_hz; RETURNFUNC(RIG_OK); } } } if (filter_value >= 50) // then it's probably a custom filter width { *width = filter_value; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_EINVAL); } /* * kenwood_get_mode */ int kenwood_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char cmd[5]; char modebuf[20]; int offs; int len = 6; int retval; int kmode; struct kenwood_priv_data *priv = STATE(rig)->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called, curr_vfo=%s\n", __func__, rig_strvfo(STATE(rig)->current_vfo)); if (!mode || !width) { RETURNFUNC2(-RIG_EINVAL); } /* for emulation do not read mode from VFOB as it is copy of VFOA */ /* we avoid the VFO swapping most of the time this way */ /* only need to get it if it has to be initialized */ if (priv->curr_mode > 0 && priv->is_emulation && vfo == RIG_VFO_B) { STATE(rig)->current_vfo = RIG_VFO_A; RETURNFUNC2(RIG_OK); } if (RIG_IS_TS890S) { len = 16; // TS890 has SF command -- unique so far if (vfo == RIG_VFO_A) { strcpy(cmd, "SF0;"); offs = 14; } else { strcpy(cmd, "SF1;"); offs = 14; } } else if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC2(retval); } } switch (vfo) { case RIG_VFO_A: case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_B: case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "OM%c", c); offs = 3; } else { if ((priv->is_k3 || priv->is_k3s || priv->is_k4 || priv->is_k4d || priv->is_k4hd) && vfo == RIG_VFO_B) { SNPRINTF(cmd, sizeof(cmd), "MD$"); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "MD"); offs = 2; } } retval = kenwood_safe_transaction(rig, cmd, modebuf, len, offs + 1); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (modebuf[offs] <= '9') { kmode = modebuf[offs] - '0'; } else { kmode = modebuf[offs] - 'A' + 10; } *mode = kenwood2rmode(kmode, caps->mode_table); if (priv->is_emulation || RIG_IS_HPSDR) { /* emulations like PowerSDR and SmartSDR normally hijack the RTTY modes for SSB-DATA AFSK modes */ rig_debug(RIG_DEBUG_VERBOSE, "%s: emulate=%d, HPSDR=%d, changing RTTY mode to PKT\n", __func__, priv->is_emulation, RIG_IS_HPSDR); if (RIG_MODE_RTTY == *mode) { *mode = RIG_MODE_PKTLSB; } if (RIG_MODE_RTTYR == *mode) { *mode = RIG_MODE_PKTUSB; } } if (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS950S || RIG_IS_TS950SDX) { /* supports DATA sub-modes */ retval = kenwood_safe_transaction(rig, "DA", modebuf, 6, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if ('1' == modebuf[2]) { if (vfo == RIG_VFO_A) { priv->datamodeA = 1; } else { priv->datamodeB = 1; } switch (*mode) { case RIG_MODE_USB: *mode = RIG_MODE_PKTUSB; break; case RIG_MODE_LSB: *mode = RIG_MODE_PKTLSB; break; case RIG_MODE_FM: *mode = RIG_MODE_PKTFM; break; case RIG_MODE_AM: *mode = RIG_MODE_PKTAM; break; default: break; } } else { if (vfo == RIG_VFO_A) { priv->datamodeA = 0; } else { priv->datamodeB = 0; } } } if (RIG_IS_TS480) { retval = kenwood_get_filter_width(rig, *mode, width); if (retval != RIG_OK) { // Ignore errors as non-fatal rig_debug(RIG_DEBUG_ERR, "%s: error getting filter width, error: %d\n", __func__, retval); *width = rig_passband_normal(rig, *mode); } } else { *width = rig_passband_normal(rig, *mode); } if (vfo == RIG_VFO_A) { priv->modeA = *mode; } else { priv->modeB = *mode; } RETURNFUNC2(RIG_OK); } /* This is used when the radio does not support MD; for mode reading */ int kenwood_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int err; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!mode || !width) { RETURNFUNC(-RIG_EINVAL); } err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } *mode = kenwood2rmode(priv->info[29] - '0', caps->mode_table); *width = rig_passband_normal(rig, *mode); if (RIG_IS_TS450S || RIG_IS_TS690S || RIG_IS_TS850 || RIG_IS_TS950S || RIG_IS_TS950SDX) { kenwood_get_filter(rig, width); /* non fatal */ } RETURNFUNC(RIG_OK); } /* kenwood_get_micgain_minmax * Kenwood rigs have different micgain levels * This routine relies on the idea that setting the micgain * to 0 and 255 will result in the minimum and maximum values being set * If a rig doesn't behave this way then customize inside that rig's backend */ static int kenwood_get_micgain_minmax(RIG *rig, int *micgain_now, int *micgain_min, int *micgain_max, int restore) { int expected_length = 18; int retval; char levelbuf[expected_length + 1]; // read micgain_now, set 0, read micgain_min, set 255, read_micgain_max; set 0 // we set back to 0 for safety and if restore is true we restore micgain_min // otherwise we expect calling routine to be setting new micgain level // we batch these commands together for speed char *cmd = "MG;MG000;MG;MG255;MG;MG000;"; int n; struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { RETURNFUNC(retval); } retval = read_string(rp, (unsigned char *) levelbuf, sizeof(levelbuf), NULL, 0, 1, 1); rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval); if (retval != 18) { rig_debug(RIG_DEBUG_ERR, "%s: expected 19, got %d in '%s'\n", __func__, retval, levelbuf); RETURNFUNC(-RIG_EPROTO); } n = sscanf(levelbuf, "MG%d;MG%d;MG%d", micgain_now, micgain_min, micgain_max); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: count not parse 3 values from '%s'\n", __func__, levelbuf); RETURNFUNC(-RIG_EPROTO); } if (restore) { SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d;", *micgain_now); retval = kenwood_transaction(rig, levelbuf, NULL, 0); RETURNFUNC(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: returning now=%d, min=%d, max=%d\n", __func__, *micgain_now, *micgain_min, *micgain_max); RETURNFUNC(RIG_OK); } /* kenwood_get_power_minmax * Kenwood rigs have different power levels by mode and by rig * This routine relies on the idea that setting the power * to 0 and 255 will result in the minimum and maximum values being set * If a rig doesn't behave this way then customize inside that rig's backend */ static int kenwood_get_power_minmax(RIG *rig, int *power_now, int *power_min, int *power_max, int restore) { int max_length = 18; int expected_length; int retval; int simple_PC = 0; // flag to do just a simple PC command char levelbuf[max_length + 1]; // read power_now, set 0, read power_min, set 255, read_power_max; set 0 // we set back to 0 for safety and if restore is true we restore power_min // otherwise we expect calling routine to be setting new power level // we batch these commands together for speed char *cmd; int n; struct rig_state *rs = STATE(rig); struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; if (power_now == NULL || power_min == NULL) { simple_PC = 1; } switch (rig->caps->rig_model) { // TS480 can't handle the long command string // We can treat it like the TS890S case RIG_MODEL_TS480: // TS890S can't take power levels outside 5-100 and 5-25 // So all we'll do is read power_now case RIG_MODEL_TS890S: rs->power_min = 5; rs->power_max = 100; if (power_min) { *power_min = 5; } if (power_max) { *power_max = 100; } if (rs->current_mode == RIG_MODE_AM) { *power_max = 25; } if (rs->current_freq >= 70000000) { rs->power_max = 50; if (rs->current_mode == RIG_MODE_AM) { *power_max = 13; } } cmd = "PC;"; break; default: if (simple_PC) { cmd = "PC;"; } else { cmd = "PC;PC000;PC;PC255;PC;PC000;"; } } // Don't do this if PTT is on...don't want to max out power!! if (CACHE(rig)->ptt == RIG_PTT_ON) { rig_debug(RIG_DEBUG_TRACE, "%s: ptt on so not checking min/max power levels\n", __func__); // return the last values we got *power_now = rs->power_now; if (power_min) { *power_min = rs->power_min; } if (power_max) { *power_max = rs->power_max; } RETURNFUNC(RIG_OK); } retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (retval != RIG_OK) { RETURNFUNC(retval); } if (RIG_IS_TS890S || RIG_IS_TS480 || simple_PC) { expected_length = 6; } else { expected_length = 18; } retval = read_string(rp, (unsigned char *) levelbuf, expected_length + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: retval=%d\n", __func__, retval); if (retval != expected_length) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d, got %d in '%s'\n", __func__, expected_length, retval, levelbuf); RETURNFUNC(-RIG_EPROTO); } if (RIG_IS_TS890S || RIG_IS_TS480 || simple_PC) { n = sscanf(levelbuf, "PC%d;", power_now); if (n != 1) { rig_debug(RIG_DEBUG_ERR, "%s: count not parse 1 value from '%s'\n", __func__, levelbuf); RETURNFUNC(-RIG_EPROTO); } } else { n = sscanf(levelbuf, "PC%d;PC%d;PC%d", power_now, power_min, power_max); if (n != 3) { rig_debug(RIG_DEBUG_ERR, "%s: count not parse 3 values from '%s'\n", __func__, levelbuf); RETURNFUNC(-RIG_EPROTO); } if (restore) // only need to restore if 3-value cmd is done { SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d;", *power_now); retval = kenwood_transaction(rig, levelbuf, NULL, 0); RETURNFUNC(retval); } } rs->power_now = *power_now; if (!simple_PC) { rs->power_min = *power_min; rs->power_max = *power_max; } RETURNFUNC(RIG_OK); } static int kenwood_find_slope_filter_for_frequency(RIG *rig, vfo_t vfo, struct kenwood_slope_filter *filter, int frequency_hz, int *value) { int retval; int i; struct kenwood_slope_filter *last_filter = NULL; freq_t freq; int cache_ms_freq; rmode_t mode; int cache_ms_mode; pbwidth_t width; int cache_ms_width; int data_mode_filter_active; if (filter == NULL) { return -RIG_ENAVAIL; } retval = rig_get_cache(rig, vfo, &freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); if (retval != RIG_OK) { return -RIG_EINVAL; } retval = rig_get_ext_func(rig, vfo, TOK_FUNC_FILTER_WIDTH_DATA, &data_mode_filter_active); if (retval != RIG_OK) { // Ignore errors, e.g. if the command is not supported data_mode_filter_active = 0; } for (i = 0; filter[i].value >= 0; i++) { if (filter[i].modes & mode && filter[i].data_mode_filter == data_mode_filter_active) { if (filter[i].frequency_hz >= frequency_hz) { *value = filter[i].value; return RIG_OK; } last_filter = &filter[i]; } } if (last_filter != NULL) { *value = last_filter->value; return RIG_OK; } return -RIG_EINVAL; } static int kenwood_find_slope_filter_for_value(RIG *rig, vfo_t vfo, struct kenwood_slope_filter *filter, int value, int *frequency_hz) { int retval; int i; freq_t freq; int cache_ms_freq; rmode_t mode; int cache_ms_mode; pbwidth_t width; int cache_ms_width; int data_mode_filter_active; if (filter == NULL) { return -RIG_ENAVAIL; } retval = rig_get_cache(rig, vfo, &freq, &cache_ms_freq, &mode, &cache_ms_mode, &width, &cache_ms_width); if (retval != RIG_OK) { return -RIG_EINVAL; } retval = rig_get_ext_func(rig, vfo, TOK_FUNC_FILTER_WIDTH_DATA, &data_mode_filter_active); if (retval != RIG_OK) { // Ignore errors, e.g. if the command is not supported data_mode_filter_active = 0; } for (i = 0; filter[i].value >= 0; i++) { if (filter[i].modes & mode && filter[i].data_mode_filter == data_mode_filter_active) { if (filter[i].value == value) { *frequency_hz = filter[i].frequency_hz; return RIG_OK; } } } return -RIG_EINVAL; } int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int i, kenwood_val, len, result; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); gran_t *level_info; ENTERFUNC; /* Check input parameter against level_gran limits */ result = check_level_param(rig, level, val, &level_info); if (result != RIG_OK) { RETURNFUNC(result); } if (RIG_LEVEL_IS_FLOAT(level)) { kenwood_val = val.f * 255; } else { kenwood_val = val.i; } switch (level) { int retval; case RIG_LEVEL_RFPOWER: { retval = RIG_OK; pbwidth_t twidth; int err = rig_get_mode(rig, vfo, &priv->curr_mode, &twidth); // https://github.com/Hamlib/Hamlib/issues/1595 if (!err && priv->last_mode_pc != priv->curr_mode) // only need to check when mode changes { priv->last_mode_pc = priv->curr_mode; // Power min/max can vary so we query to find them out every time retval = kenwood_get_power_minmax(rig, &priv->power_now, &priv->power_min, &priv->power_max, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } // https://github.com/Hamlib/Hamlib/issues/465 kenwood_val = val.f * priv->power_max; if (kenwood_val < priv->power_min) { kenwood_val = priv->power_min; } if (kenwood_val > priv->power_max) { kenwood_val = priv->power_max; } SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", kenwood_val); break; } case RIG_LEVEL_AF: { int vfo_num; if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B) ? 1 : 0; } else { vfo_num = (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) ? 0 : 1; } // some rigs only recognize 0 for vfo_set // https://github.com/Hamlib/Hamlib/issues/304 // This is now fixed for all rigs // https://github.com/Hamlib/Hamlib/issues/380 // ag_format is determined in kenwood_get_level switch (priv->ag_format) { case 1: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", kenwood_val); break; case 2: SNPRINTF(levelbuf, sizeof(levelbuf), "AG0%03d", kenwood_val); break; case 3: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%d%03d", vfo_num, kenwood_val); break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown ag_format=%d\n", __func__, priv->ag_format); } } break; case RIG_LEVEL_MICGAIN: { int micgain_now; if (priv->micgain_min == -1) // then we need to know our min/max { retval = kenwood_get_micgain_minmax(rig, &micgain_now, &priv->micgain_min, &priv->micgain_max, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } // is micgain_min ever > 0 ?? kenwood_val = val.f * (priv->micgain_max - priv->micgain_min) + priv->micgain_min; SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d", kenwood_val); break; } case RIG_LEVEL_RF: /* XXX check level range */ // KX2 and KX3 have range -190 to 250 if (val.f > 1.0 || val.f < 0) { RETURNFUNC(-RIG_EINVAL); } kenwood_val = val.f * 255.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_SQL: { int vfo_num; if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { /* Default to RX#0 */ vfo_num = 0; } SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%d%03d", vfo_num, kenwood_val); break; } case RIG_LEVEL_AGC: SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", 84 * kenwood_val); break; case RIG_LEVEL_ATT: len = RIG_IS_TS890S ? 1 : 2; /* set the attenuator if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%0*d", len, 0); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->attenuator[i]; i++) { if (val.i == rs->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%0*d", len, i + 1); foundit = 1; break; } } if (!foundit) { RETURNFUNC(-RIG_EINVAL); } } break; case RIG_LEVEL_PREAMP: /* set the preamp if a correct value is entered */ if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && rs->preamp[i]; i++) { if (val.i == rs->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); foundit = 1; break; } } if (!foundit) { RETURNFUNC(-RIG_EINVAL); } } break; case RIG_LEVEL_SLOPE_HIGH: retval = kenwood_find_slope_filter_for_frequency(rig, vfo, caps->slope_filter_high, val.i, &kenwood_val); if (retval != RIG_OK) { // Fall back to using raw values if (val.i > 20 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } kenwood_val = val.i; } SNPRINTF(levelbuf, sizeof(levelbuf), "SH%02d", kenwood_val); priv->question_mark_response_means_rejected = 1; break; case RIG_LEVEL_SLOPE_LOW: retval = kenwood_find_slope_filter_for_frequency(rig, vfo, caps->slope_filter_low, val.i, &kenwood_val); if (retval != RIG_OK) { // Fall back to using raw values if (val.i > 20 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } kenwood_val = val.i; } SNPRINTF(levelbuf, sizeof(levelbuf), "SL%02d", kenwood_val); priv->question_mark_response_means_rejected = 1; break; case RIG_LEVEL_CWPITCH: { /* Newer rigs have an extra digit of pitch factor */ len = (RIG_IS_TS890S || RIG_IS_TS990S) ? 3 : 2; /* Round input freq to nearest multiple of step */ kenwood_val = (val.i - level_info->min.i + (level_info->step.i / 2)) / level_info->step.i; SNPRINTF(levelbuf, sizeof(levelbuf), "PT%0*d", len, kenwood_val); break; } case RIG_LEVEL_KEYSPD: SNPRINTF(levelbuf, sizeof(levelbuf), "KS%03d", val.i); break; case RIG_LEVEL_COMP: kenwood_val = (int)((val.f / level_info->step.f) + 0.5f); SNPRINTF(levelbuf, sizeof(levelbuf), "PL%03d%03d", kenwood_val, kenwood_val); break; case RIG_LEVEL_VOXDELAY: if (val.i > 30 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } // Raw value is in milliseconds SNPRINTF(levelbuf, sizeof(levelbuf), "VD%04d", val.i * 100); break; case RIG_LEVEL_VOXGAIN: kenwood_val = val.f * 9.0f; SNPRINTF(levelbuf, sizeof(levelbuf), "VG%03d", kenwood_val); break; case RIG_LEVEL_BKIN_DLYMS: if (val.i > 1000 || val.i < 0) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "SD%04d", val.i); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported set_level (0x%08llx) %s", __func__, (unsigned long long)level, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } result = kenwood_transaction(rig, levelbuf, NULL, 0); priv->question_mark_response_means_rejected = 0; RETURNFUNC(result); } int get_kenwood_level(RIG *rig, const char *cmd, float *fval, int *ival) { char lvlbuf[10]; int retval; int lvl; int len = strlen(cmd); ENTERFUNC; if (!fval && !ival) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + 3); if (retval != RIG_OK) { RETURNFUNC(retval); } /* 000..255 */ sscanf(lvlbuf + len, "%d", &lvl); if (ival) { *ival = lvl; } // raw value if (fval) { *fval = lvl / 255.0; } // our default scaling of 0-255 RETURNFUNC(RIG_OK); } /* Helper to get and parse meter values using RM * Note that we turn readings on, but nothing off. * 'pips' is the number of LED bars lit in the digital meter, max=70 */ int get_kenwood_meter_reading(RIG *rig, char meter, int *pips) { char reading[9]; /* 8 char + '\0' */ int retval; char target[] = "RMx1"; /* Turn on reading this meter */ target[2] = meter; retval = kenwood_transaction(rig, target, NULL, 0); if (retval != RIG_OK) { return retval; } /* Read the first value */ retval = kenwood_transaction(rig, "RM", reading, sizeof(reading)); if (retval != RIG_OK) { return retval; } /* Find the one we want */ while (strncmp(reading, target, 3) != 0) { /* That wasn't it, get the next one */ retval = kenwood_transaction(rig, NULL, reading, sizeof(reading)); if (retval != RIG_OK) { return retval; } if (reading[0] != target[0] || reading[1] != target[1]) { /* Somebody else's data, bail */ return -RIG_EPROTO; } } sscanf(reading + 3, "%4d", pips); return RIG_OK; } /* * kenwood_get_level */ int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char cmdbuf[8]; char lvlbuf[KENWOOD_MAX_BUF_LEN]; char *cmd; int retval; int lvl; int i, ret, agclevel, len, value; struct rig_state *rs = STATE(rig); struct kenwood_priv_data *priv = rs->priv; struct kenwood_priv_caps *caps = kenwood_caps(rig); gran_t *level_info; ENTERFUNC; if (!val) { RETURNFUNC(-RIG_EINVAL); } level_info = &rig->caps->level_gran[rig_setting2idx(level)]; switch (level) { case RIG_LEVEL_RAWSTR: if (RIG_IS_TS590S || RIG_IS_TS590SG) { cmd = "SM0"; len = 3; } else if (RIG_IS_TS2000) { len = 3; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { cmd = "SM1"; } else { cmd = "SM0"; } } else { cmd = "SM"; len = 2; } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + len, "%d", &val->i); break; case RIG_LEVEL_STRENGTH: { int multiplier = 1; if (RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS480) { cmd = "SM0"; len = 3; } else if (RIG_IS_TS2000) { len = 3; if (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) { cmd = "SM1"; // TS-2000 sub-transceiver S-meter range is half of the main one multiplier = 2; } else { cmd = "SM0"; } } else { cmd = "SM"; len = 2; } retval = kenwood_safe_transaction(rig, cmd, lvlbuf, 10, len + 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + len, "%d", &val->i); val->i *= multiplier; if (rig->caps->str_cal.size) { val->i = (int) rig_raw2val(val->i, &rig->caps->str_cal); } else { val->i = (val->i * 4) - 54; } break; } case RIG_LEVEL_SQL: { int ack_len; int vfo_num; if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { /* Default to RX#0 */ vfo_num = 0; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "SQ%c", vfo_num); retval = kenwood_transaction(rig, cmdbuf, lvlbuf, sizeof(lvlbuf)); len = 6; if (retval != RIG_OK) { RETURNFUNC(retval); } ack_len = strlen(lvlbuf); if (ack_len != len) { RETURNFUNC(-RIG_EPROTO); } if (sscanf(&lvlbuf[len - 3], "%d", &lvl) != 1) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) lvl / 255.f; RETURNFUNC(RIG_OK); } case RIG_LEVEL_ATT: len = RIG_IS_TS890S ? 3 : 6; retval = kenwood_safe_transaction(rig, "RA", lvlbuf, 50, len); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else { for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (rs->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected att level %d\n", __func__, lvl); RETURNFUNC(-RIG_EPROTO); } } if (i != lvl) { RETURNFUNC(-RIG_EINTERNAL); } val->i = rs->attenuator[i - 1]; } break; case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", lvlbuf, 50, 3); if (retval != RIG_OK) { RETURNFUNC(retval); } if (lvlbuf[2] == '0') { val->i = 0; } else if (isdigit((int)lvlbuf[2])) { lvl = lvlbuf[2] - '0'; for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (rs->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp level %d\n", __func__, lvl); RETURNFUNC(-RIG_EPROTO); } } if (i != lvl) { RETURNFUNC(-RIG_EINTERNAL); } val->i = rs->preamp[i - 1]; } else { rig_debug(RIG_DEBUG_ERR, "%s: " "unexpected preamp char '%c'\n", __func__, lvlbuf[2]); RETURNFUNC(-RIG_EPROTO); } break; case RIG_LEVEL_RFPOWER: { pbwidth_t twidth; int err = rig_get_mode(rig, vfo, &priv->curr_mode, &twidth); // https://github.com/Hamlib/Hamlib/issues/1595 if (!err && priv->last_mode_pc != priv->curr_mode) // only need to check when mode changes { priv->last_mode_pc = priv->curr_mode; // Power min/max can vary so we query to find them out every time retval = kenwood_get_power_minmax(rig, &priv->power_now, &priv->power_min, &priv->power_max, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } else { retval = kenwood_get_power_minmax(rig, &priv->power_now, NULL, NULL, 0); } priv->power_min = 0; // our return scale is 0-max to match the input scale val->f = (priv->power_now - priv->power_min) / (float)(priv->power_max - priv->power_min); RETURNFUNC(RIG_OK); } case RIG_LEVEL_AF: { int vfo_num; // first time through we'll determine the AG format // Can be "AG" "AG0" or "AG0/1" // This could be done by rig but easy enough to make it automagic if (priv->ag_format < 0) { int retry_save = RIGPORT(rig)->retry; RIGPORT(rig)->retry = 0; // speed up this check so no retries rig_debug(RIG_DEBUG_TRACE, "%s: AF format check determination...\n", __func__); // Determine AG format // =-1 == Undetermine // 0 == Unknown // 1 == AG // 2 == AG0 (fixed VFO) // 3 == AG0/1 (with VFO arg) char buffer[KENWOOD_MAX_BUF_LEN]; ret = kenwood_transaction(rig, "AG", buffer, sizeof(buffer)); if (ret == RIG_OK) { priv->ag_format = 1; } else { ret = kenwood_transaction(rig, "AG1", buffer, sizeof(buffer)); if (ret == RIG_OK) { priv->ag_format = 3; } else { ret = kenwood_transaction(rig, "AG0", buffer, sizeof(buffer)); if (ret == RIG_OK) { priv->ag_format = 2; } else { priv->ag_format = 0; // rats....can't figure it out } } } RIGPORT(rig)->retry = retry_save; } rig_debug(RIG_DEBUG_TRACE, "%s: ag_format=%d\n", __func__, priv->ag_format); if (priv->ag_format == 0) { priv->ag_format = -1; // we'll keep trying next time rig_debug(RIG_DEBUG_WARN, "%s: Unable to set AG format?\n", __func__); RETURNFUNC(RIG_OK); // this is non-fatal for no))w } if (RIG_IS_TS2000) { vfo_num = (vfo == RIG_VFO_B || vfo == RIG_VFO_SUB) ? 1 : 0; } else { vfo_num = (vfo == RIG_VFO_A || vfo == RIG_VFO_MAIN) ? 0 : 1; } switch (priv->ag_format) { case 0: priv->ag_format = -1; // reset to try again RETURNFUNC(RIG_OK); break; case 1: retval = get_kenwood_level(rig, "AG", &val->f, NULL); break; case 2: retval = get_kenwood_level(rig, "AG0", &val->f, NULL); break; case 3: SNPRINTF(cmdbuf, sizeof(cmdbuf), "AG%d", vfo_num); retval = get_kenwood_level(rig, cmdbuf, &val->f, NULL); break; default: rig_debug(RIG_DEBUG_WARN, "%s: Invalid ag_format=%d?\n", __func__, priv->ag_format); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(retval); } case RIG_LEVEL_RF: RETURNFUNC(get_kenwood_level(rig, "RG", &val->f, NULL)); case RIG_LEVEL_MICGAIN: { int micgain_now; float vali = 0; if (priv->micgain_min == -1) // then we need to know our min/max { retval = kenwood_get_micgain_minmax(rig, &micgain_now, &priv->micgain_min, &priv->micgain_max, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } rig_debug(RIG_DEBUG_TRACE, "%s: micgain_min=%d, micgain_max=%d\n", __func__, priv->micgain_min, priv->micgain_max); ret = get_kenwood_level(rig, "MG", NULL, &val->i); if (ret != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Error getting MICGAIN\n", __func__); RETURNFUNC(ret); } vali = val->i; val->f = (vali - priv->micgain_min) / (float)(priv->micgain_max - priv->micgain_min); RETURNFUNC(RIG_OK); } case RIG_LEVEL_AGC: ret = get_kenwood_level(rig, "GT", NULL, &val->i); agclevel = val->i; if (agclevel == 0) { val->i = 0; } else if (agclevel < 85) { val->i = 1; } else if (agclevel < 170) { val->i = 2; } else if (agclevel <= 255) { val->i = 3; } RETURNFUNC(ret); case RIG_LEVEL_SLOPE_LOW: priv->question_mark_response_means_rejected = 1; retval = kenwood_transaction(rig, "SL", lvlbuf, sizeof(lvlbuf)); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } value = atoi(&lvlbuf[2]); retval = kenwood_find_slope_filter_for_value(rig, vfo, caps->slope_filter_low, value, &val->i); if (retval != RIG_OK) { if (retval == -RIG_ENAVAIL) { // Fall back to using raw values val->i = value; } else { RETURNFUNC(retval); } } break; case RIG_LEVEL_SLOPE_HIGH: priv->question_mark_response_means_rejected = 1; retval = kenwood_transaction(rig, "SH", lvlbuf, sizeof(lvlbuf)); priv->question_mark_response_means_rejected = 0; if (retval != RIG_OK) { RETURNFUNC(retval); } value = atoi(&lvlbuf[2]); retval = kenwood_find_slope_filter_for_value(rig, vfo, caps->slope_filter_high, value, &val->i); if (retval != RIG_OK) { if (retval == -RIG_ENAVAIL) { // Fall back to using raw values val->i = value; } else { RETURNFUNC(retval); } } break; case RIG_LEVEL_CWPITCH: /* Newer rigs have an extra digit of pitch factor */ len = (RIG_IS_TS890S || RIG_IS_TS990S) ? 3 : 2; retval = kenwood_safe_transaction(rig, "PT", lvlbuf, 50, len + 2); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &val->i); val->i = (val->i * level_info->step.i) + level_info->min.i; break; case RIG_LEVEL_KEYSPD: retval = kenwood_safe_transaction(rig, "KS", lvlbuf, 50, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &val->i); break; case RIG_LEVEL_COMP: { int raw_value; retval = kenwood_safe_transaction(rig, "PL", lvlbuf, 50, 8); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%3d", &raw_value); val->f = (float) raw_value * level_info->step.f; break; } case RIG_LEVEL_VOXDELAY: { int raw_value; retval = kenwood_safe_transaction(rig, "VD", lvlbuf, 50, 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &raw_value); // Value is in milliseconds val->i = raw_value / 100; break; } case RIG_LEVEL_VOXGAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "VG", lvlbuf, 50, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_BKIN_DLYMS: { int raw_value; retval = kenwood_safe_transaction(rig, "SD", lvlbuf, 50, 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(lvlbuf + 2, "%d", &raw_value); val->i = raw_value; break; } case RIG_LEVEL_IF: case RIG_LEVEL_APF: case RIG_LEVEL_NR: case RIG_LEVEL_PBT_IN: case RIG_LEVEL_PBT_OUT: case RIG_LEVEL_NOTCHF: case RIG_LEVEL_BKINDL: case RIG_LEVEL_BALANCE: RETURNFUNC(-RIG_ENIMPL); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported get_level %s", __func__, rig_strlevel(level)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(RIG_OK); } int kenwood_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[10]; /* longest cmd is GTxxx */ ENTERFUNC; switch (func) { case RIG_FUNC_NB: case RIG_FUNC_NB2: /* newer Kenwoods have a second noise blanker */ if (RIG_IS_TS890S) { switch (func) { case RIG_FUNC_NB: SNPRINTF(buf, sizeof(buf), "NB1%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_NB2: SNPRINTF(buf, sizeof(buf), "NB2%c", (status == 0) ? '0' : '1'); break; default: rig_debug(RIG_DEBUG_ERR, "%s: expected 0,1, or 2 and got %d\n", __func__, status); RETURNFUNC(-RIG_EINVAL); } } else { SNPRINTF(buf, sizeof(buf), "NB%c", (status == 0) ? '0' : '1'); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_ABM: SNPRINTF(buf, sizeof(buf), "AM%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_COMP: if (RIG_IS_TS890S) { SNPRINTF(buf, sizeof(buf), "PR0%c", (status == 0) ? '0' : '1'); } else { SNPRINTF(buf, sizeof(buf), "PR%c", (status == 0) ? '0' : '1'); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TONE: SNPRINTF(buf, sizeof(buf), "TO%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TSQL: SNPRINTF(buf, sizeof(buf), "CT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_VOX: SNPRINTF(buf, sizeof(buf), "VX%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_FAGC: SNPRINTF(buf, sizeof(buf), "GT00%c", (status == 0) ? '4' : '2'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_NR: if (RIG_IS_TS890S || RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS480 || RIG_IS_TS2000 || RIG_IS_QRPLABS) { char c = '1'; if (status == 2) { c = '2'; } SNPRINTF(buf, sizeof(buf), "NR%c", (status == 0) ? '0' : c); } else { SNPRINTF(buf, sizeof(buf), "NR%c", (status == 0) ? '0' : '1'); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_BC: SNPRINTF(buf, sizeof(buf), "BC%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_BC2: SNPRINTF(buf, sizeof(buf), "BC%c", (status == 0) ? '0' : '2'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_ANF: SNPRINTF(buf, sizeof(buf), "NT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_AIP: SNPRINTF(buf, sizeof(buf), "MX%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_TUNER: SNPRINTF(buf, sizeof(buf), "AC1%c0", (status == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_FBKIN: SNPRINTF(buf, sizeof(buf), "SD%04d", (status == 1) ? 0 : 50); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %s", rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } /* * works for any 'format 1' command or newer command like the TS890 has * as long as the return is a number 0-9 * answer is always 4 bytes or 5 bytes: two or three byte command id, status and terminator */ int get_kenwood_func(RIG *rig, const char *cmd, int *status) { int retval; char buf[10]; int offset = 2; ENTERFUNC; if (!cmd || !status) { RETURNFUNC(-RIG_EINVAL); } if (strlen(cmd) == 3) { offset = 3; } // some commands are 3 letters retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), offset + 1); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[offset] - '0'; // just return whatever the rig returns RETURNFUNC(RIG_OK); } /* * kenwood_get_func */ int kenwood_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char *cmd; char respbuf[20]; int retval; int raw_value; ENTERFUNC; if (!status) { RETURNFUNC(-RIG_EINVAL); } switch (func) { case RIG_FUNC_FAGC: retval = kenwood_safe_transaction(rig, "GT", respbuf, 20, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = respbuf[4] != '4' ? 1 : 0; RETURNFUNC(RIG_OK); case RIG_FUNC_NB: cmd = "NB"; if (RIG_IS_TS890S) { cmd = "NB1"; } RETURNFUNC(get_kenwood_func(rig, cmd, status)); case RIG_FUNC_NB2: RETURNFUNC(get_kenwood_func(rig, "NB2", status)); case RIG_FUNC_ABM: RETURNFUNC(get_kenwood_func(rig, "AM", status)); case RIG_FUNC_COMP: RETURNFUNC(get_kenwood_func(rig, "PR", status)); case RIG_FUNC_TONE: RETURNFUNC(get_kenwood_func(rig, "TO", status)); case RIG_FUNC_TSQL: RETURNFUNC(get_kenwood_func(rig, "CT", status)); case RIG_FUNC_VOX: RETURNFUNC(get_kenwood_func(rig, "VX", status)); case RIG_FUNC_NR: RETURNFUNC(get_kenwood_func(rig, "NR", status)); /* FIXME on TS2000 */ // Check for BC #1 case RIG_FUNC_BC: // Most will return BC1 or BC0, if BC2 then BC1 is off retval = get_kenwood_func(rig, "BC", &raw_value); if (retval == RIG_OK) { *status = raw_value == 1 ? 1 : 0; } RETURNFUNC(retval); case RIG_FUNC_BC2: // TS-890 check Beat Cancel 2 we return boolean true/false retval = get_kenwood_func(rig, "BC", &raw_value); if (retval == RIG_OK) { *status = raw_value == 2 ? 1 : 0; } RETURNFUNC(retval); case RIG_FUNC_ANF: RETURNFUNC(get_kenwood_func(rig, "NT", status)); case RIG_FUNC_LOCK: RETURNFUNC(get_kenwood_func(rig, "LK", status)); case RIG_FUNC_AIP: RETURNFUNC(get_kenwood_func(rig, "MX", status)); case RIG_FUNC_RIT: RETURNFUNC(get_kenwood_func(rig, "RT", status)); case RIG_FUNC_XIT: RETURNFUNC(get_kenwood_func(rig, "XT", status)); case RIG_FUNC_TUNER: retval = kenwood_safe_transaction(rig, "AC", respbuf, 20, 5); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = respbuf[3] != '0' ? 1 : 0; RETURNFUNC(RIG_OK); case RIG_FUNC_FBKIN: { retval = kenwood_safe_transaction(rig, "SD", respbuf, 20, 6); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(respbuf + 2, "%d", &raw_value); *status = (raw_value == 0) ? 1 : 0; RETURNFUNC(RIG_OK); } default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %s", rig_strfunc(func)); RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(-RIG_EINVAL); } /* * kenwood_set_ctcss_tone * Assumes rig->caps->ctcss_list != NULL * * Warning! This is untested stuff! May work at least on TS-870S * Please owners report to me , thanks. --SF */ int kenwood_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; char tonebuf[16]; int i; ENTERFUNC; caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { RETURNFUNC(-RIG_EINVAL); } /* TODO: replace menu no 57 by a define */ SNPRINTF(tonebuf, sizeof(tonebuf), "EX%03d%04d", 57, i + kenwood_caps(rig)->tone_table_base); RETURNFUNC(kenwood_transaction(rig, tonebuf, NULL, 0)); } int kenwood_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; ENTERFUNC; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(buf, sizeof(buf), "TN%c%02d", c, i + kenwood_caps(rig)->tone_table_base); } else { SNPRINTF(buf, sizeof(buf), "TN%02d", i + kenwood_caps(rig)->tone_table_base); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } /* * kenwood_get_ctcss_tone * Assumes STATE(rig)->priv != NULL */ int kenwood_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { struct kenwood_priv_data *priv = STATE(rig)->priv; struct rig_caps *caps; char tonebuf[3]; int i, retval; unsigned int tone_idx; ENTERFUNC; if (!tone) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (RIG_IS_TS890S) { char buf[5]; retval = kenwood_safe_transaction(rig, "TN", buf, sizeof(buf), 4); memcpy(tonebuf, buf + 2, 2); } else if (RIG_IS_TS990S) { char cmd[4]; char buf[6]; char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(retval); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "TN%c", c); retval = kenwood_safe_transaction(rig, cmd, buf, sizeof(buf), 5); memcpy(tonebuf, &buf[3], 2); } else { retval = kenwood_get_if(rig); memcpy(tonebuf, &priv->info[34], 2); } if (retval != RIG_OK) { RETURNFUNC(retval); } tonebuf[2] = '\0'; tone_idx = atoi(tonebuf); if (tone_idx < kenwood_caps(rig)->tone_table_base) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS tone is zero (%s)\n", __func__, tonebuf); RETURNFUNC(-RIG_EPROTO); } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); RETURNFUNC(-RIG_EPROTO); } } *tone = caps->ctcss_list[tone_idx - kenwood_caps(rig)->tone_table_base]; RETURNFUNC(RIG_OK); } int kenwood_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps = rig->caps; char buf[16]; int i; ENTERFUNC; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (tone == caps->ctcss_list[i]) { break; } } if (tone != caps->ctcss_list[i]) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(buf, sizeof(buf), "CN%c%02d", c, i + kenwood_caps(rig)->tone_table_base); } else { SNPRINTF(buf, sizeof(buf), "CN%02d", i + kenwood_caps(rig)->tone_table_base); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } int kenwood_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { struct rig_caps *caps; char cmd[4]; char tonebuf[6]; int offs; int i, retval; unsigned int tone_idx; ENTERFUNC; if (!tone) { RETURNFUNC(-RIG_EINVAL); } caps = rig->caps; if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(retval); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "CN%c", c); offs = 3; } else { SNPRINTF(cmd, sizeof(cmd), "CN"); offs = 2; } retval = kenwood_safe_transaction(rig, cmd, tonebuf, 6, offs + 2); if (retval != RIG_OK) { RETURNFUNC(retval); } tone_idx = atoi(tonebuf + offs); if (tone_idx < kenwood_caps(rig)->tone_table_base) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS is zero (%s)\n", __func__, tonebuf); RETURNFUNC(-RIG_EPROTO); } /* check this tone exists. That's better than nothing. */ for (i = 0; i < tone_idx; i++) { if (caps->ctcss_list[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: CTCSS NG (%04u)\n", __func__, tone_idx); RETURNFUNC(-RIG_EPROTO); } } *tone = caps->ctcss_list[tone_idx - kenwood_caps(rig)->tone_table_base]; RETURNFUNC(RIG_OK); } /* * set the aerial/antenna to use */ int kenwood_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { char cmd[8]; char a; ENTERFUNC; switch (ant) { case RIG_ANT_1: a = '1'; break; case RIG_ANT_2: a = '2'; break; case RIG_ANT_3: a = '3'; break; case RIG_ANT_4: a = '4'; break; default: RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "AN0%c%c99", c, a); } else if (RIG_IS_TS890S) { SNPRINTF(cmd, sizeof(cmd), "AN%c999", a); } else if (RIG_IS_TS590S || RIG_IS_TS590SG) { SNPRINTF(cmd, sizeof(cmd), "AN%c99", a); } else { SNPRINTF(cmd, sizeof(cmd), "AN%c", a); } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } int kenwood_set_ant_no_ack(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { const char *cmd; ENTERFUNC; switch (ant) { case RIG_ANT_1: cmd = "AN1"; break; case RIG_ANT_2: cmd = "AN2"; break; case RIG_ANT_3: cmd = "AN3"; break; case RIG_ANT_4: cmd = "AN4"; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } /* * get the aerial/antenna in use */ int kenwood_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx) { char ackbuf[8]; int offs; int retval; char antenna; ENTERFUNC; if (!ant_curr) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { retval = kenwood_safe_transaction(rig, "AN0", ackbuf, sizeof(ackbuf), 7); offs = 4; } else if (RIG_IS_TS890S) { retval = kenwood_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 6); offs = 2; } else if (RIG_IS_TS590S || RIG_IS_TS590SG) { retval = kenwood_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 5); offs = 2; } else { retval = kenwood_safe_transaction(rig, "AN", ackbuf, sizeof(ackbuf), 3); offs = 2; } if (retval != RIG_OK) { RETURNFUNC(retval); } antenna = ackbuf[offs]; if (antenna < '0' || antenna > '9') { RETURNFUNC(-RIG_EPROTO); } if (antenna == '0') { // At least TS-2000 return AN0 on VHF/UHF bands *ant_curr = RIG_ANT_1; } else { *ant_curr = RIG_ANT_N(ackbuf[offs] - '1'); } /* XXX check that the returned antenna is valid for the current rig */ RETURNFUNC(RIG_OK); } /* * kenwood_get_ptt */ int kenwood_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { struct kenwood_priv_data *priv = STATE(rig)->priv; int retval; ENTERFUNC; if (!ptt) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } *ptt = priv->info[28] == '0' ? RIG_PTT_OFF : RIG_PTT_ON; RETURNFUNC(RIG_OK); } int kenwood_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); if (RIG_IS_TS2000) { switch (ptt) { case RIG_PTT_ON: case RIG_PTT_ON_MIC: case RIG_PTT_ON_DATA: ptt_cmd = "VX0;TX"; break; case RIG_PTT_OFF: ptt_cmd = "RX"; break; default: RETURNFUNC(-RIG_EINVAL); } } else { switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TX"; break; case RIG_PTT_ON_MIC: ptt_cmd = "TX0"; break; case RIG_PTT_ON_DATA: ptt_cmd = "TX1"; break; case RIG_PTT_OFF: ptt_cmd = "RX"; break; default: RETURNFUNC(-RIG_EINVAL); } } int retval = kenwood_transaction(rig, ptt_cmd, NULL, 0); if (ptt == RIG_PTT_OFF) { hl_usleep(100 * 1000); } // a little time for PTT to turn off RETURNFUNC(retval); } int kenwood_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt) { int err; ptt_t current_ptt; ENTERFUNC; err = kenwood_get_ptt(rig, vfo, ¤t_ptt); if (err != RIG_OK) { RETURNFUNC(err); } if (current_ptt == ptt) { RETURNFUNC(RIG_OK); } RETURNFUNC(kenwood_transaction(rig, (ptt == RIG_PTT_ON) ? "TX" : "RX", NULL, 0)); } /* * kenwood_get_dcd */ int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char busybuf[10]; int retval; int expected; int offs; ENTERFUNC; if (!dcd) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS480 || RIG_IS_TS590S || RIG_IS_TS590SG || RIG_IS_TS990S || RIG_IS_TS2000) { expected = 4; } else { expected = 3; } retval = kenwood_safe_transaction(rig, "BY", busybuf, 10, expected); if (retval != RIG_OK) { RETURNFUNC(retval); } if ((RIG_IS_TS990S && RIG_VFO_SUB == vfo) || (RIG_IS_TS2000 && (RIG_VFO_B == vfo || RIG_VFO_SUB == vfo))) { offs = 3; } else { offs = 2; } *dcd = (busybuf[offs] == '1') ? RIG_DCD_ON : RIG_DCD_OFF; RETURNFUNC(RIG_OK); } /* * kenwood_set_trn */ int kenwood_set_trn(RIG *rig, int trn) { ENTERFUNC; switch (rig->caps->rig_model) { char buf[5]; case RIG_MODEL_POWERSDR: // powersdr doesn't have AI command case RIG_MODEL_THETIS: // powersdr doesn't have AI command case RIG_MODEL_PT8000A: // powersdr doesn't have AI command RETURNFUNC(-RIG_ENAVAIL); case RIG_MODEL_TS990S: RETURNFUNC(kenwood_transaction(rig, (trn == RIG_TRN_RIG) ? "AI2" : "AI0", NULL, 0)); case RIG_MODEL_THD7A: case RIG_MODEL_THD74: RETURNFUNC(kenwood_transaction(rig, (trn == RIG_TRN_RIG) ? "AI 1" : "AI 0", buf, sizeof buf)); default: RETURNFUNC(kenwood_transaction(rig, (trn == RIG_TRN_RIG) ? "AI1" : "AI0", NULL, 0)); } } /* * kenwood_get_trn */ int kenwood_get_trn(RIG *rig, int *trn) { char trnbuf[6]; int retval; ENTERFUNC; if (!trn) { RETURNFUNC(-RIG_EINVAL); } /* these rigs only have AI[0|1] set commands and no AI query */ if (RIG_IS_TS450S || RIG_IS_TS690S || RIG_IS_TS790 || RIG_IS_TS850 || RIG_IS_TS950S || RIG_IS_TS950SDX || RIG_IS_POWERSDR || RIG_IS_THETIS) { RETURNFUNC(-RIG_ENAVAIL); } if (RIG_IS_THD74 || RIG_IS_THD7A || RIG_IS_TMD700) { retval = kenwood_safe_transaction(rig, "AI", trnbuf, 6, 4); } else { retval = kenwood_safe_transaction(rig, "AI", trnbuf, 6, 3); } if (retval != RIG_OK) { RETURNFUNC(retval); } if (RIG_IS_THD74 || RIG_IS_THD7A || RIG_IS_TMD700) { *trn = trnbuf[3] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; } else { *trn = trnbuf[2] != '0' ? RIG_TRN_RIG : RIG_TRN_OFF; } RETURNFUNC(RIG_OK); } /* * kenwood_set_powerstat */ int kenwood_set_powerstat(RIG *rig, powerstat_t status) { int retval; struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; if ((priv->is_k3 || priv->is_k3s) && status == RIG_POWER_ON) { rig_debug(RIG_DEBUG_ERR, "%s: K3/K3S must use aux I/O jack pulled low to power on\n", __func__); return -RIG_EPOWER; } int i = 0; int retry_save = rp->retry; rig_debug(RIG_DEBUG_VERBOSE, "%s called status=%d\n", __func__, status); if (status == RIG_POWER_ON) { // When powering on a Kenwood rig needs dummy bytes to wake it up, // then wait at least 200ms and within 2 seconds issue the power-on command again write_block(rp, (unsigned char *) "PS1;", 4); hl_usleep(500000); } rp->retry = 0; retval = kenwood_transaction(rig, (status == RIG_POWER_ON) ? "PS1;" : "PS0;", NULL, 0); if (status == RIG_POWER_ON) // wait for wakeup only { for (i = 0; i < 8; ++i) // up to ~10 seconds including the timeouts { freq_t freq; sleep(1); retval = rig_get_freq(rig, RIG_VFO_A, &freq); if (retval == RIG_OK) { rp->retry = retry_save; RETURNFUNC2(retval); } rig_debug(RIG_DEBUG_TRACE, "%s: Wait #%d for power up\n", __func__, i + 1); } } rp->retry = retry_save; if (i == 9) { rig_debug(RIG_DEBUG_TRACE, "%s: timeout waiting for powerup, try %d\n", __func__, i + 1); retval = -RIG_ETIMEOUT; } RETURNFUNC2(retval); } /* * kenwood_get_powerstat */ int kenwood_get_powerstat(RIG *rig, powerstat_t *status) { char pwrbuf[6]; int result; struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!priv->has_ps) { *status = RIG_POWER_ON; RETURNFUNC(RIG_OK); // fake the OK return for these rigs } if (!status) { RETURNFUNC(-RIG_EINVAL); } // The first PS command has two purposes: // 1. to detect that the rig is turned on/off when it responds with PS1/PS0 immediately // 2. to act as dummy wake-up data for a rig that is turned off // Timeout needs to be set temporarily to a low value, // so that the second command can be sent in 2 seconds, which is what Kenwood rigs expect. short retry_save; short timeout_retry_save; int timeout_save; retry_save = rp->retry; timeout_retry_save = rp->timeout_retry; timeout_save = rp->timeout; rp->retry = 0; rp->timeout_retry = 0; rp->timeout = 500; result = kenwood_safe_transaction(rig, "PS", pwrbuf, 6, 3); rp->retry = retry_save; rp->timeout_retry = timeout_retry_save; rp->timeout = timeout_save; // Rig may respond here already if (result == RIG_OK) { char ps = pwrbuf[2]; switch (ps) { case '1': *status = RIG_POWER_ON; RETURNFUNC(RIG_OK); case '0': *status = RIG_POWER_OFF; RETURNFUNC(RIG_OK); default: // fall through to retry command break; } } // Kenwood rigs in powered-off state require the PS command to be sent // after waiting for at least 200ms and within 2 seconds after dummy data hl_usleep(500000); // Discard any unsolicited data rig_flush(rp); result = kenwood_safe_transaction(rig, "PS", pwrbuf, 6, 3); if (result != RIG_OK) { RETURNFUNC(result); } *status = pwrbuf[2] == '0' ? RIG_POWER_OFF : RIG_POWER_ON; RETURNFUNC(RIG_OK); } /* * kenwood_reset */ int kenwood_reset(RIG *rig, reset_t reset) { char rstbuf[6]; char rst; ENTERFUNC; if (RIG_IS_TS990S) { switch (reset) { case RIG_RESET_SOFT: rst = '4'; break; case RIG_RESET_VFO: rst = '3'; break; case RIG_RESET_MCALL: rst = '2'; break; case RIG_RESET_MASTER: rst = '5'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); RETURNFUNC(-RIG_EINVAL); } } else { switch (reset) { case RIG_RESET_VFO: rst = '1'; break; case RIG_RESET_MASTER: rst = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported reset %d\n", __func__, reset); RETURNFUNC(-RIG_EINVAL); } } SNPRINTF(rstbuf, sizeof(rstbuf), "SR%c", rst); /* this command has no answer */ RETURNFUNC(kenwood_transaction(rig, rstbuf, NULL, 0)); } /* * kenwood_send_morse */ int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg) { char morsebuf[40], m2[30]; int msg_len, retval; const char *p; struct kenwood_priv_data *priv; ENTERFUNC; if (!msg) { RETURNFUNC(-RIG_EINVAL); } p = msg; msg_len = strlen(msg); while (msg_len > 0) { int buff_len; /* * Check with "KY" if char buffer is available. * if not, sleep. */ for (;;) { retval = kenwood_transaction(rig, "KY;", m2, 4); if (retval != RIG_OK) { RETURNFUNC(retval); } // If answer is "KY0;", there is space in buffer and we can proceed. // If answer is "KY1;", we have to wait a while // If answer is "KY2;", there is space in buffer and we aren't sending so we can proceed. // If answer is something else, return with error to prevent infinite loops if (!strncmp(m2, "KY0", 3)) { break; } if (!strncmp(m2, "KY2", 3)) { break; } if (!strncmp(m2, "KY1", 3)) { hl_usleep(50 * 1000); } else { RETURNFUNC(-RIG_EINVAL); } } buff_len = msg_len > 24 ? 24 : msg_len; strncpy(m2, p, 24); m2[24] = '\0'; /* * Make the total message segments 28 characters * in length because some Kenwoods demand it. * 0x20 fills in the message end. * Some rigs don't need the fill */ switch (rig->caps->rig_model) { case RIG_MODEL_K3: // probably a lot more rigs need to go here case RIG_MODEL_K3S: case RIG_MODEL_KX2: case RIG_MODEL_KX3: case RIG_MODEL_QRPLABS: SNPRINTF(morsebuf, sizeof(morsebuf), "KY %s", m2); break; case RIG_MODEL_TS890S: SNPRINTF(morsebuf, sizeof morsebuf, "KY2%s", m2); break; case RIG_MODEL_TS990S: // Variable message length only on newer firmware priv = STATE(rig)->priv; if (priv->fw_rev_uint >= 110) { SNPRINTF(morsebuf, sizeof morsebuf, "KY2%s", m2); break; } /* FALL THROUGH */ case RIG_MODEL_TS590S: /* the command must consist of 28 bytes right aligned */ SNPRINTF(morsebuf, sizeof(morsebuf), "KY %24s", m2); break; default: /* the command must consist of 28 bytes 0x20 padded */ SNPRINTF(morsebuf, sizeof(morsebuf), "KY %-24s", m2); } retval = kenwood_transaction(rig, morsebuf, NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } msg_len -= buff_len; p += buff_len; } RETURNFUNC(RIG_OK); } /* * kenwood_stop_morse / */ int kenwood_stop_morse(RIG *rig, vfo_t vfo) { ENTERFUNC; RETURNFUNC(kenwood_transaction(rig, "KY0", NULL, 0)); } /* * kenwood_send_voice */ int kenwood_send_voice_mem(RIG *rig, vfo_t vfo, int bank) { char cmd[16]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; #if 0 // don't really need to turn on the list SNPRINTF(cmd, sizeof(cmd), "PB01"); kenwood_transaction(rig, cmd, NULL, 0); #endif if ((bank < 1 || bank > 3) && (rig->caps->rig_model == RIG_MODEL_TS2000 || rig->caps->rig_model == RIG_MODEL_TS480)) { rig_debug(RIG_DEBUG_ERR, "%s: TS2000/TS480 channel is from 1 to 3\n", __func__); RETURNFUNC(-RIG_EINVAL); } // some rigs have 5 channels -- newew ones have 10 channels if ((bank < 1 || bank > 5) && (rig->caps->rig_model == RIG_MODEL_TS590SG || rig->caps->rig_model == RIG_MODEL_TS590S)) { rig_debug(RIG_DEBUG_ERR, "%s: TS590S/SG channel is from 1 to 5\n", __func__); RETURNFUNC(-RIG_EINVAL); } if (rig->caps->rig_model == RIG_MODEL_TS2000 || (rig->caps->rig_model == RIG_MODEL_TS480 || (rig->caps->rig_model == RIG_MODEL_TS590SG || rig->caps->rig_model == RIG_MODEL_TS590S))) { SNPRINTF(cmd, sizeof(cmd), "PB%d", bank); } else { SNPRINTF(cmd, sizeof(cmd), "PB1%d1", bank); } priv->voice_bank = bank; RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } int kenwood_stop_voice_mem(RIG *rig, vfo_t vfo) { char cmd[16]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (rig->caps->rig_model == RIG_MODEL_TS2000 || (rig->caps->rig_model == RIG_MODEL_TS480 || (rig->caps->rig_model == RIG_MODEL_TS590SG || rig->caps->rig_model == RIG_MODEL_TS590S))) { SNPRINTF(cmd, sizeof(cmd), "PB0"); } else { SNPRINTF(cmd, sizeof(cmd), "PB1%d0", priv->voice_bank); } RETURNFUNC(kenwood_transaction(rig, cmd, NULL, 0)); } /* * kenwood_vfo_op */ int kenwood_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { ENTERFUNC; switch (op) { case RIG_OP_UP: RETURNFUNC(kenwood_transaction(rig, "UP", NULL, 0)); case RIG_OP_DOWN: RETURNFUNC(kenwood_transaction(rig, "DN", NULL, 0)); case RIG_OP_BAND_UP: RETURNFUNC(kenwood_transaction(rig, "BU", NULL, 0)); case RIG_OP_BAND_DOWN: RETURNFUNC(kenwood_transaction(rig, "BD", NULL, 0)); case RIG_OP_TUNE: RETURNFUNC(kenwood_transaction(rig, "AC111", NULL, 0)); case RIG_OP_CPY: RETURNFUNC(kenwood_transaction(rig, "VV", NULL, 0)); default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); RETURNFUNC(-RIG_EINVAL); } } /* * kenwood_set_mem */ int kenwood_set_mem(RIG *rig, vfo_t vfo, int ch) { char buf[7]; ENTERFUNC; if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { int err; if (RIG_OK != (err = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(err); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(buf, sizeof(buf), "MN%c%03d", c, ch); } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(buf, sizeof(buf), "MC %02d", ch); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } /* * kenwood_get_mem */ int kenwood_get_mem(RIG *rig, vfo_t vfo, int *ch) { char cmd[4]; char membuf[10]; int offs; int retval; ENTERFUNC; if (!ch) { RETURNFUNC(-RIG_EINVAL); } if (RIG_IS_TS990S) { char c; if (RIG_VFO_CURR == vfo || RIG_VFO_VFO == vfo) { if (RIG_OK != (retval = kenwood_get_vfo_main_sub(rig, &vfo))) { RETURNFUNC(retval); } } switch (vfo) { case RIG_VFO_MAIN: c = '0'; break; case RIG_VFO_SUB: c = '1'; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n", __func__, rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmd, sizeof(cmd), "MN%c", c); offs = 3; } else { /* * "MCbmm;" * where b is the bank number, mm the memory number. * b can be a space */ SNPRINTF(cmd, sizeof(cmd), "MC"); offs = 2; } retval = kenwood_safe_transaction(rig, cmd, membuf, sizeof(membuf), 3 + offs); if (retval != RIG_OK) { RETURNFUNC(retval); } *ch = atoi(membuf + offs); RETURNFUNC(RIG_OK); } int kenwood_get_mem_if(RIG *rig, vfo_t vfo, int *ch) { int err; char buf[4]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!ch) { RETURNFUNC(-RIG_EINVAL); } err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } memcpy(buf, &priv->info[26], 2); buf[2] = '\0'; *ch = atoi(buf); RETURNFUNC(RIG_OK); } int kenwood_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; char buf[26]; char cmd[8]; char bank = ' '; struct kenwood_priv_caps *caps = kenwood_caps(rig); ENTERFUNC; if (!chan) { RETURNFUNC(-RIG_EINVAL); } /* put channel num in the command string */ if (RIG_IS_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(cmd, sizeof(cmd), "MR0%c%02d", bank, chan->channel_num); err = kenwood_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { RETURNFUNC(err); } memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_VFO; /* MR0 1700005890000510 ; * MRsbccfffffffffffMLTtt ; */ /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ if (buf[19] == '0' || buf[19] == ' ') { chan->ctcss_tone = 0; } else { buf[22] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[atoi(&buf[20])]; } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { RETURNFUNC(-RIG_ENAVAIL); } buf[6] = '\0'; chan->channel_num = atoi(&buf[4]); if (buf[3] >= '0' && buf[3] <= '9') { chan->bank_num = buf[3] - '0'; } /* split freq */ cmd[2] = '1'; err = kenwood_safe_transaction(rig, cmd, buf, 26, 23); if (err != RIG_OK) { RETURNFUNC(err); } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); RETURNFUNC(-RIG_ENIMPL); } RETURNFUNC(RIG_OK); } int kenwood_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char buf[128]; char mode, tx_mode = 0; char bank = ' '; int err; int tone = 0; struct kenwood_priv_caps *caps = kenwood_caps(rig); ENTERFUNC; if (!chan) { RETURNFUNC(-RIG_EINVAL); } mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); RETURNFUNC(-RIG_EINVAL); } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); RETURNFUNC(-RIG_EINVAL); } } /* find tone */ if (chan->ctcss_tone) { for (tone = 0; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = 0; } } if (RIG_IS_TS940) { bank = '0' + chan->bank_num; } SNPRINTF(buf, sizeof(buf), "MW0%c%02d%011"PRIll"%c%c%c%02d ", /* note the space at the end */ bank, chan->channel_num, (int64_t)chan->freq, '0' + mode, (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { RETURNFUNC(err); } SNPRINTF(buf, sizeof(buf), "MW1%c%02d%011"PRIll"%c%c%c%02d ", bank, chan->channel_num, (int64_t)(chan->split == RIG_SPLIT_ON ? chan->tx_freq : 0), (chan->split == RIG_SPLIT_ON) ? ('0' + tx_mode) : '0', (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', chan->ctcss_tone ? '1' : '0', chan->ctcss_tone ? (tone + 1) : 0); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } int kenwood_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val) { struct kenwood_priv_data *priv = STATE(rig)->priv; char buf[4]; ENTERFUNC; switch (token) { case TOK_VOICE: RETURNFUNC(kenwood_transaction(rig, "VR", NULL, 0)); case TOK_FINE: SNPRINTF(buf, sizeof(buf), "FS%c", (val.i == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case TOK_XIT: SNPRINTF(buf, sizeof(buf), "XT%c", (val.i == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case TOK_RIT: SNPRINTF(buf, sizeof(buf), "RT%c", (val.i == 0) ? '0' : '1'); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); case TOK_NO_ID: priv->no_id = val.i; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_EINVAL); } /* * kenwood_set_clock */ int kenwood_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { char cmd[20]; int retval, kenwood_val; /* Do the offset first. Then if the clock is synced to NTP, * the set failure still should allow correct display * * utc_offset = hours * 100 + minutes * Kenwood value = 15 minute intervals normalized to 56 ( = UTC+00) */ // Convert utc_offset to minutes kenwood_val = ((utc_offset / 100) * 60) + (utc_offset % 100); // Now convert to 15 minute intervals, centered on 56 kenwood_val = kenwood_val / 15 + 56; SNPRINTF(cmd, sizeof(cmd), "CK2%03d", kenwood_val); retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) {return retval;} // Offset is set, now check if clock is settable retval = kenwood_transaction(rig, "CK6", cmd, sizeof(cmd)); if (retval != RIG_OK) {return retval;} if (cmd[3] == '1') { // OK, autoset by NTP is on so we can't set it // What should we tell the user? // Until I hear otherwise, pretend everything worked, and // the local clock should display the correct time in whatever // zone the app thought it was trying to set. return RIG_OK; } // Local clock should be settable; build the command SNPRINTF(cmd, sizeof(cmd), "CK0%02d%02d%02d%02d%02d%02d", year % 100, month, day, hour, min, sec); if (RIG_IS_TS990S) { // TS-990S does not have seconds cmd[13] = '\0'; } retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } /* * kenwood_get_clock */ int kenwood_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { int retval; int fields, diff; char ans[20]; // Make sure the clock has been set at least once retval = kenwood_transaction(rig, "CK1", ans, sizeof(ans)); if (retval != RIG_OK) {return retval;} if (ans[3] != '1') { return -RIG_ENAVAIL; } // Get the local clock retval = kenwood_transaction(rig, "CK0", ans, sizeof(ans)); if (retval != RIG_OK) {return retval;} fields = sscanf(ans, "CK0%2d%2d%2d%2d%2d%2d", year, month, day, hour, min, sec); // TS-890S doesn't define what P6 is, but it sure looks like seconds to me. // TS-990S doesn't have a P6, so set it to 0 if (fields < 6) { *sec = 0; } // Add the century if (*year <= 20) //TODO: Update this every decade or so { *year += 100; } *year += 2000; //TODO: Update this every century or so // Now figure out the time zone retval = kenwood_transaction(rig, "CK2", ans, sizeof(ans)); if (retval != RIG_OK) {return retval;} diff = (atoi(&ans[3]) - 56) * 15; // UTC offset in minutes // Pack as hours * 100 + minutes *utc_offset = (diff / 60) * 100 + diff % 60; // No msec available *msec = 0; return RIG_OK; } int kenwood_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val) { int err; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!val) { RETURNFUNC(-RIG_EINVAL); } switch (token) { case TOK_FINE: RETURNFUNC(get_kenwood_func(rig, "FS", &val->i)); case TOK_XIT: err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } val->i = (priv->info[24] == '1') ? 1 : 0; RETURNFUNC(RIG_OK); case TOK_RIT: err = kenwood_get_if(rig); if (err != RIG_OK) { RETURNFUNC(err); } val->i = (priv->info[23] == '1') ? 1 : 0; RETURNFUNC(RIG_OK); } RETURNFUNC(-RIG_ENIMPL); } /* * kenwood_get_info * supposed to work only for TS2000... */ const char *kenwood_get_info(RIG *rig) { char firmbuf[10]; int retval; ENTERFUNC2; if (!rig) { return ("*rig == NULL"); } retval = kenwood_safe_transaction(rig, "TY", firmbuf, 10, 5); if (retval != RIG_OK) { return (NULL); } switch (firmbuf[4]) { case '0': return ("Firmware: Overseas type"); case '1': return ("Firmware: Japanese 100W type"); case '2': return ("Firmware: Japanese 20W type"); default: return ("Firmware: unknown"); } } #define IDBUFSZ 16 /* * proberigs_kenwood * * Notes: * There's only one rig possible per port. * * rig_model_t probeallrigs_kenwood(port_t *port, rig_probe_func_t cfunc, rig_ptr_t data) */ DECLARE_PROBERIG_BACKEND(kenwood) { char idbuf[IDBUFSZ] = ""; int id_len = -1, i, k_id; int retval = -1; int rates[] = { 115200, 57600, 38400, 19200, 9600, 4800, 1200, 0 }; /* possible baud rates */ int rates_idx; int write_delay = port->write_delay; short retry = port->retry; if (port->type.rig != RIG_PORT_SERIAL) { return (RIG_MODEL_NONE); } port->write_delay = port->post_write_delay = 0; port->parm.serial.stop_bits = 2; port->retry = 0; /* * try for all different baud rates */ for (rates_idx = 0; rates[rates_idx]; rates_idx++) { port->parm.serial.rate = rates[rates_idx]; port->timeout = 2 * 1000 / rates[rates_idx] + 50; retval = serial_open(port); if (retval != RIG_OK) { port->write_delay = write_delay; port->retry = retry; return (RIG_MODEL_NONE); } retval = write_block(port, (unsigned char *) "ID;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK || id_len < 0) { continue; } } if (retval != RIG_OK || id_len < 0 || !strcmp(idbuf, "ID;")) { port->write_delay = write_delay; port->retry = retry; return (RIG_MODEL_NONE); } /* * reply should be something like 'IDxxx;' */ if (id_len != 5 && id_len != 6) { idbuf[7] = '\0'; rig_debug(RIG_DEBUG_VERBOSE, "probe_kenwood: protocol error, " " expected %d, received %d: %s\n", 6, id_len, idbuf); port->write_delay = write_delay; port->retry = retry; return (RIG_MODEL_NONE); } /* first, try ID string */ for (i = 0; kenwood_id_string_list[i].model != RIG_MODEL_NONE; i++) { if (!strncmp(kenwood_id_string_list[i].id, idbuf + 2, 16)) { rig_debug(RIG_DEBUG_VERBOSE, "probe_kenwood: " "found %s\n", idbuf + 2); if (cfunc) { (*cfunc)(port, kenwood_id_string_list[i].model, data); } port->write_delay = write_delay; port->retry = retry; return (kenwood_id_string_list[i].model); } } /* then, try ID numbers */ k_id = atoi(idbuf + 2); /* * Elecraft K2 returns same ID as TS570 */ if (k_id == 17) { retval = serial_open(port); if (retval != RIG_OK) { return (RIG_MODEL_NONE); } retval = write_block(port, (unsigned char *) "K2;", 3); id_len = read_string(port, (unsigned char *) idbuf, IDBUFSZ, ";\r", 2, 0, 1); close(port->fd); if (retval != RIG_OK) { return (RIG_MODEL_NONE); } /* * reply should be something like 'K2n;' */ if (id_len == 4 || !strcmp(idbuf, "K2")) { rig_debug(RIG_DEBUG_VERBOSE, "%s: found K2\n", __func__); if (cfunc) { (*cfunc)(port, RIG_MODEL_K2, data); } return (RIG_MODEL_K2); } } for (i = 0; kenwood_id_list[i].model != RIG_MODEL_NONE; i++) { if (kenwood_id_list[i].id == k_id) { rig_debug(RIG_DEBUG_VERBOSE, "probe_kenwood: " "found %03d\n", k_id); if (cfunc) { (*cfunc)(port, kenwood_id_list[i].model, data); } return (kenwood_id_list[i].model); } } /* * not found in known table.... * update kenwood_id_list[]! */ rig_debug(RIG_DEBUG_WARN, "probe_kenwood: found unknown device " "with ID %03d, please report to Hamlib " "developers.\n", k_id); rig_debug(RIG_DEBUG_TRACE, "%s: post_write_delay=%d\n", __func__, port->post_write_delay); return (RIG_MODEL_NONE); } /* * initrigs_kenwood is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(kenwood) { rig_register(&ts950s_caps); rig_register(&ts950sdx_caps); rig_register(&ts50s_caps); rig_register(&ts140_caps); rig_register(&ts450s_caps); rig_register(&ts570d_caps); rig_register(&ts570s_caps); rig_register(&ts680s_caps); rig_register(&ts690s_caps); rig_register(&ts790_caps); rig_register(&ts850_caps); rig_register(&ts870s_caps); rig_register(&ts930_caps); rig_register(&ts2000_caps); rig_register(&trc80_caps); rig_register(&k2_caps); rig_register(&k3_caps); rig_register(&k3s_caps); rig_register(&kx2_caps); rig_register(&kx3_caps); rig_register(&k4_caps); rig_register(&xg3_caps); rig_register(&sdrconsole_caps); rig_register(&ts440_caps); rig_register(&ts940_caps); rig_register(&ts711_caps); rig_register(&ts811_caps); rig_register(&r5000_caps); rig_register(&tmd700_caps); rig_register(&thd7a_caps); rig_register(&thd72a_caps); rig_register(&thd74_caps); rig_register(&thf7e_caps); rig_register(&thg71_caps); rig_register(&tmv7_caps); rig_register(&tmv71_caps); rig_register(&tmd710_caps); rig_register(&ts590_caps); rig_register(&ts990s_caps); rig_register(&ts590sg_caps); rig_register(&ts480_caps); rig_register(&thf6a_caps); rig_register(&transfox_caps); rig_register(&f6k_caps); rig_register(&powersdr_caps); rig_register(&pihpsdr_caps); rig_register(&ts890s_caps); rig_register(&pt8000a_caps); rig_register(&malachite_caps); rig_register(&tx500_caps); rig_register(&sdruno_caps); rig_register(&qrplabs_caps); rig_register(&qrplabs_qmx_caps); rig_register(&fx4_caps); rig_register(&thetis_caps); rig_register(&trudx_caps); return (RIG_OK); } hamlib-4.6.2/rigs/kenwood/flex.h0000644000175000017500000000246114752216205013430 00000000000000/* * Hamlib Elecraft backend--support extensions to Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2013 by Steve Conklin AI4QR, steve@conklinhouse.com * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _FLEXRADIO_H #define _FLEXRADIO_H 1 #include #define EXT_LEVEL_NONE -1 #define FLEXRADIO_MAX_BUF_LEN 50 struct flexradio_priv_data { char info[FLEXRADIO_MAX_BUF_LEN]; split_t split; /* current split state */ }; /* Flexradio extension function declarations */ int flexradio_open(RIG *rig); #endif /* _FLEXRADIO_H */ hamlib-4.6.2/rigs/kenwood/kenwood.h0000644000175000017500000003443714752216205014150 00000000000000/* * Hamlib Kenwood backend - main header * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (C) 2009,2010 Alessandro Zummo * Copyright (C) 2009,2010,2011,2012,2013 by Nate Bargmann, n0nb@n0nb.us * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _KENWOOD_H #define _KENWOOD_H 1 #include #include "token.h" #include "idx_builtin.h" #define BACKEND_VER "20250107" #define EOM_KEN ';' #define EOM_TH '\r' #define KENWOOD_MODE_TABLE_MAX 24 #define KENWOOD_MAX_BUF_LEN 128 /* max answer len, arbitrary */ /* Tokens for Parameters common to multiple rigs. * Use token # >= 1 or <= 100. Defined here so they will be * available in Kenwood name space. */ #define TOK_VOICE TOKEN_BACKEND(1) #define TOK_FINE TOKEN_BACKEND(2) #define TOK_XIT TOKEN_BACKEND(3) #define TOK_RIT TOKEN_BACKEND(4) #define TOK_NO_ID TOKEN_BACKEND(5) #define TOK_FUNC_FILTER_WIDTH_DATA TOKEN_BACKEND(6) // Data communications mode that affects SL/SH/FW commands /* Token structure assigned to .cfgparams in rig_caps */ extern struct confparams kenwood_cfg_params[]; /* * modes in use by the "MD" command */ #define MD_NONE '0' #define MD_LSB '1' #define MD_USB '2' #define MD_CW '3' #define MD_FM '4' #define MD_AM '5' #define MD_FSK '6' #define MD_CWR '7' // MD_DIG used by SDRPlay #define MD_DIG '8' #define MD_FSKR '9' /* S-meter calibration tables */ /* This one for the TS590 no doubt applies elsewhere */ #define TS590_SM_CAL { 10, \ { \ { 0, -54 }, \ { 3, -48 }, \ { 6, -36 }, \ { 9, -24 }, \ { 12, -12 }, \ { 15, 0 }, \ { 20, 20 }, \ { 25, 40 }, \ { 30, 60 }, \ } } #define RIG_IS_HPSDR (rig->caps->rig_model == RIG_MODEL_HPSDR) #define RIG_IS_K2 (rig->caps->rig_model == RIG_MODEL_K2) #define RIG_IS_K3 (rig->caps->rig_model == RIG_MODEL_K3) #define RIG_IS_K3S (rig->caps->rig_model == RIG_MODEL_K3S) #define RIG_IS_KX2 (rig->caps->rig_model == RIG_MODEL_KX2) #define RIG_IS_KX3 (rig->caps->rig_model == RIG_MODEL_KX3) #define RIG_IS_K4 (rig->caps->rig_model == RIG_MODEL_K4) #define RIG_IS_THD7A (rig->caps->rig_model == RIG_MODEL_THD7A) #define RIG_IS_THD74 (rig->caps->rig_model == RIG_MODEL_THD74) #define RIG_IS_TMD700 (rig->caps->rig_model == RIG_MODEL_TMD700) #define RIG_IS_TS2000 (rig->caps->rig_model == RIG_MODEL_TS2000) #define RIG_IS_TS50 (rig->caps->rig_model == RIG_MODEL_TS50) #define RIG_IS_TS450S (rig->caps->rig_model == RIG_MODEL_TS450S) #define RIG_IS_TS480 (rig->caps->rig_model == RIG_MODEL_TS480) #define RIG_IS_TS590S (rig->caps->rig_model == RIG_MODEL_TS590S) #define RIG_IS_TS590SG (rig->caps->rig_model == RIG_MODEL_TS590SG) #define RIG_IS_TS690S (rig->caps->rig_model == RIG_MODEL_TS690S) #define RIG_IS_TS790 (rig->caps->rig_model == RIG_MODEL_TS790) #define RIG_IS_TS850 (rig->caps->rig_model == RIG_MODEL_TS850) #define RIG_IS_TS890S (rig->caps->rig_model == RIG_MODEL_TS890S) #define RIG_IS_TS940 (rig->caps->rig_model == RIG_MODEL_TS940) #define RIG_IS_TS950SDX (rig->caps->rig_model == RIG_MODEL_TS950SDX) #define RIG_IS_TS950S (rig->caps->rig_model == RIG_MODEL_TS950S) #define RIG_IS_TS990S (rig->caps->rig_model == RIG_MODEL_TS990S) #define RIG_IS_XG3 (rig->caps->rig_model == RIG_MODEL_XG3) #define RIG_IS_PT8000A (rig->caps->rig_model == RIG_MODEL_PT8000A) #define RIG_IS_POWERSDR (rig->caps->rig_model == RIG_MODEL_POWERSDR) #define RIG_IS_THETIS (rig->caps->rig_model == RIG_MODEL_THETIS) #define RIG_IS_MALACHITE (rig->caps->rig_model == RIG_MODEL_MALACHITE) #define RIG_IS_QRPLABS (rig->caps->rig_model == RIG_MODEL_QRPLABS) struct kenwood_filter_width { rmode_t modes; int value; pbwidth_t width_hz; }; struct kenwood_slope_filter { rmode_t modes; int data_mode_filter; int value; pbwidth_t frequency_hz; }; struct kenwood_priv_caps { char cmdtrm; /* Command termination chars (ken=';' or th='\r') */ int if_len; /* length of IF; answer excluding ';' terminator */ rmode_t *mode_table; struct kenwood_filter_width *filter_width; /* Last entry should have value == -1 and width_hz == -1 */ struct kenwood_slope_filter *slope_filter_high; /* Last entry should have value == -1 and frequency_hz == -1 */ struct kenwood_slope_filter *slope_filter_low; /* Last entry should have value == -1 and frequency_hz == -1 */ double swr; int tone_table_base; /* Offset of first value in rigs tone tables, default=0 */ }; struct kenwood_priv_data { char info[KENWOOD_MAX_BUF_LEN]; split_t split; /* current split state */ vfo_t tx_vfo; /* split tx vfo */ int k2_ext_lvl; /* Initial K2 extension level */ int k3_ext_lvl; /* Initial K3 extension level */ int k2_md_rtty; /* K2 RTTY mode available flag, 1 = RTTY, 0 = N/A */ int has_kpa3; /* Elecraft K3 has k3pa for PC command */ int has_kpa100; /* Elecraft KX3/KX2 has kpa100 for PC command */ char *fw_rev; /* firmware revision level */ int trn_state; /* AI state discovered at startup */ unsigned fw_rev_uint; /* firmware revision as a number 1.07 -> 107 */ char verify_cmd[4]; /* command used to verify set commands */ int is_emulation; /* flag for TS-2000 emulations */ void *data; /* model specific data */ rmode_t curr_mode; /* used for is_emulation to avoid get_mode on VFOB */ struct timespec cache_start; char last_if_response[KENWOOD_MAX_BUF_LEN]; int poweron; /* to avoid powering on more than once */ int has_ps; /* rig has PS cmd */ int ag_format; /* which AG command is being used...see LEVEL_AF in kenwood.c*/ int has_rit2; /* rig has set 2 rit command -- can set rit 0-99999 directly */ int micgain_min, micgain_max; /* varies by rig so we figure it out automagically */ int is_k2; int is_k3; int is_k3s; int is_kx3; int is_kx2; int is_k4; int is_k4d; int is_k4hd; int no_id; // if true will not send ID; with every set command int opened; // true once rig_open is called to avoid setting VFOA every open call rmode_t modeA; rmode_t modeB; int datamodeA; // datamode status from get_mode or set_mode int datamodeB; // datamode status from get_mode or set_mode int question_mark_response_means_rejected; /* the question mark response has multiple meanings */ int save_k2_ext_lvl; // so we can restore to original int save_k3_ext_lvl; // so we can restore to original -- for future use if needed int voice_bank; /* last voice bank send for use by stop_voice_mem */ rmode_t last_mode_pc; // last mode memory for PC command int power_now,power_min,power_max; }; #define kenwood_caps(rig) ((struct kenwood_priv_caps *)(rig)->caps->priv) extern rmode_t kenwood_mode_table[KENWOOD_MODE_TABLE_MAX]; extern tone_t kenwood38_ctcss_list[]; extern tone_t kenwood42_ctcss_list[]; extern tone_t kenwood51_ctcss_list[]; int kenwood_transaction(RIG *rig, const char *cmdstr, char *data, size_t datasize); int kenwood_safe_transaction(RIG *rig, const char *cmd, char *buf, size_t buf_size, size_t expected); rmode_t kenwood2rmode(unsigned char mode, const rmode_t mode_table[]); char rmode2kenwood(rmode_t mode, const rmode_t mode_table[]); int kenwood_init(RIG *rig); int kenwood_cleanup(RIG *rig); int kenwood_open(RIG *rig); int kenwood_close(RIG *rig); int kenwood_set_vfo(RIG *rig, vfo_t vfo); int kenwood_set_vfo_main_sub(RIG *rig, vfo_t vfo); int kenwood_get_vfo_if(RIG *rig, vfo_t *vfo); int kenwood_get_vfo_main_sub(RIG *rig, vfo_t *vfo); int kenwood_set_split(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); int kenwood_get_vfo_frft(RIG *rig, vfo_t *vfo); int kenwood_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); int kenwood_get_split_vfo_if(RIG *rig, vfo_t rxvfo, split_t *split, vfo_t *txvfo); int kenwood_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int kenwood_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int kenwood_get_freq_if(RIG *rig, vfo_t vfo, freq_t *freq); int kenwood_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); int kenwood_set_rit_new(RIG *rig, vfo_t vfo, shortfreq_t rit); // Also use this for xit int kenwood_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); int kenwood_get_rit_new(RIG *rig, vfo_t vfo, shortfreq_t *rit); // Also use this for xit int kenwood_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit); int kenwood_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit); int kenwood_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int kenwood_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int kenwood_get_mode_if(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int kenwood_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int kenwood_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int kenwood_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int kenwood_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int kenwood_set_ext_parm(RIG *rig, hamlib_token_t token, value_t val); int kenwood_get_ext_parm(RIG *rig, hamlib_token_t token, value_t *val); int kenwood_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int kenwood_set_ctcss_tone_tn(RIG *rig, vfo_t vfo, tone_t tone); int kenwood_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); int kenwood_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); int kenwood_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); int kenwood_set_powerstat(RIG *rig, powerstat_t status); int kenwood_get_powerstat(RIG *rig, powerstat_t *status); int kenwood_reset(RIG *rig, reset_t reset); int kenwood_send_morse(RIG *rig, vfo_t vfo, const char *msg); int kenwood_stop_morse(RIG *rig, vfo_t vfo); int kenwood_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int kenwood_set_ant_no_ack(RIG *rig, vfo_t vfo, ant_t ant, value_t option); int kenwood_get_ant(RIG *rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t *ant_curr, ant_t *ant_tx, ant_t *ant_rx); int kenwood_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int kenwood_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int kenwood_set_ptt_safe(RIG *rig, vfo_t vfo, ptt_t ptt); int kenwood_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int kenwood_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int kenwood_set_mem(RIG *rig, vfo_t vfo, int ch); int kenwood_get_mem(RIG *rig, vfo_t vfo, int *ch); int kenwood_get_mem_if(RIG *rig, vfo_t vfo, int *ch); int kenwood_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); int kenwood_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); int kenwood_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); const char *kenwood_get_info(RIG *rig); int kenwood_get_id(RIG *rig, char *buf); int kenwood_get_if(RIG *rig); int kenwood_send_voice_mem(RIG *rig, vfo_t vfo, int bank); int kenwood_stop_voice_mem(RIG *rig, vfo_t vfo); int kenwood_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset); int kenwood_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset); int kenwood_set_trn(RIG *rig, int trn); int kenwood_get_trn(RIG *rig, int *trn); /* only use if returned string has length 6, e.g. 'SQ011;' */ int get_kenwood_level(RIG *rig, const char *cmd, float *fval, int *ival); int get_kenwood_func(RIG *rig, const char *cmd, int *status); int get_kenwood_meter_reading(RIG *rig, char meter, int *pips); extern struct rig_caps ts950s_caps; extern struct rig_caps ts950sdx_caps; extern struct rig_caps ts50s_caps; extern struct rig_caps ts140_caps; extern struct rig_caps ts450s_caps; extern struct rig_caps ts570d_caps; extern struct rig_caps ts570s_caps; extern struct rig_caps ts680s_caps; extern struct rig_caps ts690s_caps; extern struct rig_caps ts790_caps; extern struct rig_caps ts850_caps; extern struct rig_caps ts870s_caps; extern struct rig_caps ts930_caps; extern struct rig_caps ts2000_caps; extern struct rig_caps k2_caps; extern struct rig_caps k3_caps; extern struct rig_caps k3s_caps; extern struct rig_caps kx2_caps; extern struct rig_caps kx3_caps; extern struct rig_caps k4_caps; extern struct rig_caps xg3_caps; extern struct rig_caps trc80_caps; extern struct rig_caps sdrconsole_caps; extern struct rig_caps thd7a_caps; extern struct rig_caps thd72a_caps; extern struct rig_caps thd74_caps; extern struct rig_caps tmd700_caps; extern struct rig_caps thf7a_caps; extern struct rig_caps thf7e_caps; extern struct rig_caps thg71_caps; extern struct rig_caps tmv7_caps; extern struct rig_caps tmv71_caps; extern struct rig_caps tmd710_caps; extern struct rig_caps ts440_caps; extern struct rig_caps ts940_caps; extern struct rig_caps ts711_caps; extern struct rig_caps ts811_caps; extern struct rig_caps r5000_caps; extern struct rig_caps ts480_caps; extern struct rig_caps ts590_caps; extern struct rig_caps ts590sg_caps; extern struct rig_caps thf6a_caps; extern struct rig_caps transfox_caps; extern struct rig_caps f6k_caps; extern struct rig_caps powersdr_caps; extern struct rig_caps pihpsdr_caps; extern struct rig_caps ts890s_caps; extern struct rig_caps pt8000a_caps; extern struct rig_caps malachite_caps; extern struct rig_caps tx500_caps; extern struct rig_caps sdruno_caps; extern struct rig_caps qrplabs_caps; extern struct rig_caps qrplabs_qmx_caps; extern struct rig_caps fx4_caps; extern struct rig_caps thetis_caps; extern struct rig_caps trudx_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, size_t expected) { struct kenwood_priv_data *priv = STATE(rig)->priv; return kenwood_safe_transaction(rig, cmd, priv->info, KENWOOD_MAX_BUF_LEN, expected); } #endif /* _KENWOOD_H */ hamlib-4.6.2/rigs/kenwood/README.k30000644000175000017500000001262514752216205013520 00000000000000Elecraft K3 notes and Hamlib errata by Nate Bargmann, N0NB. While the K3 uses a large set of commands compatible with the standard Kenwood commands, a number are extended and others have side effects that are peculiar to the K3. As such, a separate set of elecraft.[c|h] files have been written to support the K2 and K3 in the best possible way using shared code when possible. K3 specific code can be found in k3.c As always, comments and bug reports should be submitted to hamlib-developer@lists.sourceforge.net elecraft_open() =============== The kenwood_open() function fails for the Elecraft radios as the function checks the backend to be certain the ID from the radio matches the backend that called the function. As the ID command of the Elecraft radios returns "017" which corresponds to the TS-570, the backend test fails. Rather than muck up a working function, I chose to implement an independent elecraft_open which not only checks for the existence of a connected radio that returns an ID of "017", it also checks for K2 or K3 extensions and sets a pair of private variables that may be used later for advanced functions. This way the backend should be able to reliably test for either a K2 or K3 (needs more testing with the K2). k3_set_vfo() ============ The K3's use of VFO A and VFO B differs from other rigs in that VFO A is *always* the main or upper display and VFO B is *always* the sub or lower display. The A/B panel button simply swaps the contents of the two displays. The K3 manual states that VFO A is always the receive frequency and VFO B is the transmit frequency in split mode. This is complicated somewhat when the second receiver is installed and VFO B serves as its display frequency *and* the transmit frequency in split mode. Got that? Good! As a result of the above, I found that using the kenwood_set_vfo function had the side effect of clearing the rig out of split mode when the VFO was set to RIG_VFO_B. The Kenwood command 'FT1;' is used to make VFO B the transmitting VFO while this command will cause the K3 to enter split mode. Likewise, the Kenwood command 'FR1;' is used to set VFO B as the receiving VFO while the K3 exits split mode when it receives *any* set value for 'FR'. My solution is to simply issue the 'SWT11;' command which emulates tapping the A/B button on the K3's front panel to swap the displays when the k3_set_vfo function is called with RIG_VFO_B. Any other vfo value leaves the display alone. Feedback on improving this function is welcome. k3_get_mode() k3_get_mode() =========================== As an extension to the common Kenwood mode definitions, the K3 implements the custom 'DT' command which can query and set its data sub-modes. These are as follows: DT0 DATA A DT1 AFSK A DT2 FSK D DT3 PSK D The main difference is that DT0 and DT1 are for soundcard audio modes from a computer such as PSK31, MFSK, Olivia, etc. with DT1 being "optimized for RTTY". Conversely, DT2 and DT3 utilize "direct FSK in" on the accessory jack as well as enable the K3's internal encoding/decoding of RTTY and PSK31 modes (outside the realm of Hamlib). As implemented the k3_get_mode function will query the data sub-mode when the kenwood_get_mode function returns RIG_MODE_RTTY or RIG_MODE_RTTYR. As of k3 backend version 20101027 the following will be returned: MD6 MD9 DT0 RIG_MODE_PKTUSB RIG_MODE_PKTLSB DT1 RIG_MODE_RTTY RIG_MODE_RTTYR DT2 N/A N/A DT3 N/A N/A Perhaps it would be preferable to return the RTTY modes when DT2 is detected. Feedback is requested. Mode setting is little different as the MD and DT values will be set as above for the Hamlib RIG_MODE values. Feedback is requested on whether RTTY/RTTYR should map to AFSK A (DT1) or FSK D (DT2). The K3 can set any bandwidth in any mode using its custom 'BW' command. Band- width values are sent to the K3 in 10 Hz increments and the K3 will round down to the nearest 100 Hz values from 10 to 40 Hz. It will round down to the nearest 50 Hz values from 50 to 90 Hz. As an example, sending 'BW0236' (2360 in rigctl) will set the bandwidth to 2350 Hz (rounded down by the K3). The k3_get_mode function will query and return the actual bandwidth in use in Hertz. k3_set_ext_level() ================== This function is used to set the K3 for some extra level functions (rigctl command examples shown). To clear the RIT and XIT offset, use the 'L' command with the token name 'ritclr' for 'Level' to set in rigctl[d]. The prompted value is not used and can be safely set to 0. Use this level to clear the RIT and XIT offsets when it is not desired to turn RIT|XIT off. k3_get_ext_level() ================== This function is used to query the K3 for some extra information (rigctl command examples shown). To query the IF center frequency, use the 'l' command with the token name 'ifctr' for 'Level' to read in rigctl[d]. Value returned is 8210000.0 + queried value from rig (see K3 Programmers Reference, FI command). Returned type is a floating point value. To query the TX status, use the 'l' command with the token name 'txst' for 'Level' to read in rigctl[d]. Value returned is 1 for K3 in transmit mode and 0 for receive mode. Returned type is an integer. kenwood_get/set_ext_parms() =========================== These functions are used to get and set RIT/XIT on and off. The special token names of 'rit' and 'xit' are used with the P/p commands of rigctl[d] for the 'parm'. Set/returned value is 0 or 1 for off or on. hamlib-4.6.2/rigs/kenwood/trc80.c0000644000175000017500000001261614752216205013430 00000000000000/* * Hamlib Kenwood backend - TRC-80 description * Copyright (c) 2000-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include "hamlib/rig.h" #include "kenwood.h" #define TRC80_ALL_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_AM|RIG_MODE_RTTY) #define TRC80_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_RTTY) #define TRC80_AM_TX_MODES RIG_MODE_AM /* TODO: make sure they are implemented by kenwood generic backend, and compatible */ #define TRC80_FUNC_ALL (RIG_FUNC_TUNER|RIG_FUNC_AIP|\ RIG_FUNC_TONE|RIG_FUNC_AIP|RIG_FUNC_NB|RIG_FUNC_VOX) #define TRC80_LEVEL_ALL (RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_MICGAIN|\ RIG_LEVEL_RFPOWER|RIG_LEVEL_CWPITCH|RIG_LEVEL_BKIN_DLYMS|\ RIG_LEVEL_SQL|RIG_LEVEL_VOXDELAY) #define TRC80_PARMS (RIG_PARM_NONE) #define TRC80_VFO_OPS (RIG_OP_NONE) #define TRC80_SCAN_OPS (RIG_SCAN_VFO) #define TRC80_VFO (RIG_VFO_MEM) #define TRC80_ANTS (0) #define TRC80_CHANNEL_CAPS { \ .freq=1,\ .mode=1,\ .tx_freq=1,\ .tx_mode=1,\ .split=1,\ .flags=RIG_CHFLAG_SKIP \ } static struct kenwood_priv_caps trc80_priv_caps = { .cmdtrm = EOM_KEN, }; /* * TRC-80/TK-80 rig capabilities. */ struct rig_caps trc80_caps = { RIG_MODEL(RIG_MODEL_TRC80), .model_name = "TRC-80", .mfg_name = "Kenwood", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 100, .timeout = 1000, .retry = 3, .has_get_func = TRC80_FUNC_ALL, .has_set_func = TRC80_FUNC_ALL, .has_get_level = TRC80_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TRC80_LEVEL_ALL), .has_get_parm = TRC80_PARMS, .has_set_parm = RIG_LEVEL_SET(TRC80_PARMS), /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = kHz(1.1), .max_xit = 0, .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .vfo_ops = TRC80_VFO_OPS, .scan_ops = TRC80_SCAN_OPS, .chan_list = { { 1, 80, RIG_MTYPE_MEM, TRC80_CHANNEL_CAPS }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TRC80_ALL_MODES, -1, -1, TRC80_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {MHz(1.8), MHz(30), TRC80_OTHER_TX_MODES, W(15), W(100), TRC80_VFO, TRC80_ANTS}, {MHz(1.8), MHz(30), TRC80_AM_TX_MODES, W(5), W(25), TRC80_VFO, TRC80_ANTS}, /* AM class */ RIG_FRNG_END, }, .rx_range_list2 = { {kHz(500), MHz(30), TRC80_ALL_MODES, -1, -1, TRC80_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {MHz(1.8), MHz(30), TRC80_OTHER_TX_MODES, W(15), W(100), TRC80_VFO, TRC80_ANTS}, {MHz(1.8), MHz(30), TRC80_AM_TX_MODES, W(5), W(25), TRC80_VFO, TRC80_ANTS}, /* AM class */ RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: TBC */ {TRC80_ALL_MODES, 1}, {TRC80_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.2)}, {RIG_MODE_AM, kHz(5)}, RIG_FLT_END, }, .priv = (void *)& trc80_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, #ifdef XXREMOVEDXX .set_freq = kenwood_set_freq, #endif .get_freq = kenwood_get_freq_if, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = kenwood_get_channel, .scan = kenwood_scan, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/thf7.c0000644000175000017500000002412314752216205013334 00000000000000/* * Hamlib Kenwood backend - TH-F7 description * Copyright (c) 2001-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "tones.h" #include "kenwood.h" #include "th.h" #define THF7_MODES_TX (RIG_MODE_FM) #define THF7_HIGH_MODES (RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_WFM) #define THF7_ALL_MODES (THF7_HIGH_MODES|RIG_MODE_SSB|RIG_MODE_CW) #define THF7_FUNC_ALL (RIG_FUNC_ARO|RIG_FUNC_LOCK|RIG_FUNC_BC) /* * How incredible, there's no RIG_LEVEL_STRENGTH! */ #define THF7_LEVEL_ALL (RIG_LEVEL_SQL|RIG_LEVEL_RFPOWER|RIG_LEVEL_ATT|\ RIG_LEVEL_BALANCE|RIG_LEVEL_VOXGAIN|RIG_LEVEL_VOXDELAY) #define THF7_PARMS (RIG_PARM_APO|RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define THF7_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define THF7_ANTS (RIG_ANT_1|RIG_ANT_2) /* * TODO: * scan_group can only be get. scan_group=channel_num%50; */ #define THF7_CHANNEL_CAPS \ TH_CHANNEL_CAPS,\ .flags=1, \ .dcs_code=1, \ .dcs_sql=1, #define THF7_CHANNEL_CAPS_WO_LO \ TH_CHANNEL_CAPS,\ .dcs_code=1, \ .dcs_sql=1, /* CTCSS 01..42 */ static tone_t thf7_ctcss_list[] = { 670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541, 0 }; static rmode_t thf7_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_FM, [1] = RIG_MODE_WFM, [2] = RIG_MODE_AM, [3] = RIG_MODE_LSB, [4] = RIG_MODE_USB, [5] = RIG_MODE_CW }; /* * Band A & B */ #define THF7_VFO (RIG_VFO_A|RIG_VFO_B) static struct kenwood_priv_caps thf7_priv_caps = { .cmdtrm = EOM_TH, /* Command termination character */ .mode_table = thf7_mode_table, }; static int thf7e_init(RIG *rig); static int thf7e_open(RIG *rig); static int thf7e_get_vfo(RIG *rig, vfo_t *vfo); static int thf7e_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* * TH-F7E rig capabilities. * * Manual, thanks to K6MAY: http://www.k6may.com/KenwoodTHF6Tip1.shtml * * TODO: * - set/get_ctcss_tone/sql through set/get_channel() and VR/VW * - emulate RIG_FUNC_TONE|RIG_FUNC_TSQL by setting ctcss_tone/sql to 0/non zero? */ struct rig_caps thf7e_caps = { RIG_MODEL(RIG_MODEL_THF7E), .model_name = "TH-F7E", .mfg_name = "Kenwood", .version = TH_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_HANDHELD, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .has_get_func = THF7_FUNC_ALL, .has_set_func = THF7_FUNC_ALL | RIG_FUNC_TBURST, .has_get_level = THF7_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(THF7_LEVEL_ALL), .has_get_parm = THF7_PARMS, .has_set_parm = THF7_PARMS, .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = thf7_ctcss_list, .dcs_list = common_dcs_list, .preamp = { RIG_DBLST_END, }, .attenuator = { 20, RIG_DBLST_END, }, .max_rit = Hz(0), .max_xit = Hz(0), .max_ifshift = Hz(0), .vfo_ops = THF7_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, /* TBC */ .bank_qty = 0, .chan_desc_sz = 8, .chan_list = { { 0, 399, RIG_MTYPE_MEM, {THF7_CHANNEL_CAPS}}, /* normal MEM */ { 400, 409, RIG_MTYPE_EDGE, {THF7_CHANNEL_CAPS}}, /* L0-L9 lower scan limit */ { 410, 419, RIG_MTYPE_EDGE, {THF7_CHANNEL_CAPS}}, /* U0-U9 upper scan limit */ { 420, 429, RIG_MTYPE_MEM, {THF7_CHANNEL_CAPS}}, /* I0-I9 info */ { 430, 431, RIG_MTYPE_PRIO, {THF7_CHANNEL_CAPS}}, /* PR0,PR1 priority */ { 432, 434, RIG_MTYPE_CALL, {THF7_CHANNEL_CAPS_WO_LO}}, /* Call (for each ham band) */ { 435, 449, RIG_MTYPE_BAND, {THF7_CHANNEL_CAPS_WO_LO}}, /* VFO */ /* 3 A-band VFO */ /* 11 B-band VFO */ /* TODO: 10 DTMF */ RIG_CHAN_END, }, .rx_range_list1 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(146), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF7_ALL_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF7_HIGH_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list1 = { /* power actually depends on DC power supply */ {MHz(144), MHz(146), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(440), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, /* region 2 is model TH-F6A in fact */ .rx_range_list2 = { /* RIG_ANT_2 is internal bar antenna */ {MHz(144), MHz(148), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF7_MODES_TX, -1, -1, RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {kHz(100), MHz(470), THF7_ALL_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1 | RIG_ANT_2}, {MHz(470), GHz(1.3), THF7_HIGH_MODES, -1, -1, RIG_VFO_MEM | RIG_VFO_B, RIG_ANT_1}, RIG_FRNG_END }, .tx_range_list2 = { /* power actually depends on DC power supply */ {MHz(144), MHz(148), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(222), MHz(225), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, {MHz(430), MHz(450), THF7_MODES_TX, W(0.05), W(5), RIG_VFO_MEM | RIG_VFO_A, RIG_ANT_1}, RIG_FRNG_END }, .tuning_steps = { /* This table is ordered according to protocol, from '0' to 'b' */ /* The steps are not available on every band/frequency limit 470MHz */ {THF7_ALL_MODES, kHz(5)}, {THF7_ALL_MODES, kHz(6.25)}, {THF7_ALL_MODES, kHz(8.33)}, {THF7_ALL_MODES, kHz(9)}, {THF7_ALL_MODES, kHz(10)}, {THF7_ALL_MODES, kHz(12.5)}, {THF7_ALL_MODES, kHz(15)}, {THF7_ALL_MODES, kHz(20)}, {THF7_ALL_MODES, kHz(25)}, {THF7_ALL_MODES, kHz(30)}, {THF7_ALL_MODES, kHz(50)}, {THF7_ALL_MODES, kHz(100)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { /* real width to be checked (missing specs) */ {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, /* narrow FM */ {RIG_MODE_AM, kHz(9)}, {RIG_MODE_WFM, kHz(150)}, /* or 230? */ {RIG_MODE_SSB | RIG_MODE_CW, kHz(3)}, RIG_FLT_END, }, .priv = (void *)& thf7_priv_caps, .rig_init = thf7e_init, .rig_cleanup = kenwood_cleanup, .rig_open = thf7e_open, .rig_close = kenwood_close, .set_freq = th_set_freq, .get_freq = th_get_freq, .set_mode = th_set_mode, .get_mode = th_get_mode, .set_vfo = th_set_vfo, .get_vfo = thf7e_get_vfo, .set_ptt = th_set_ptt, .get_dcd = th_get_dcd, .vfo_op = thf7e_vfo_op, .set_mem = th_set_mem, .get_mem = th_get_mem, .set_func = th_set_func, .get_func = th_get_func, .set_level = th_set_level, .get_level = th_get_level, .get_parm = th_get_parm, .set_parm = th_set_parm, .get_info = th_get_info, .set_channel = th_set_channel, .get_channel = th_get_channel, .set_ant = th_set_ant, .get_ant = th_get_ant, .reset = th_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; int thf7e_init(RIG *rig) { return kenwood_init(rig); } int thf7e_open(RIG *rig) { return kenwood_open(rig); } /* * th_get_vfo * Assumes rig!=NULL */ int thf7e_get_vfo(RIG *rig, vfo_t *vfo) { char vfoch; int retval; rig_debug(RIG_DEBUG_TRACE, "%s: called\n", __func__); retval = th_get_vfo_char(rig, vfo, &vfoch); if (retval != RIG_OK) { return retval; } switch (vfoch) { case '0' : case '3' : /* Fine Step Enable */ break; case '1' : /* MR */ case '2' : /* CALL */ case '4' : /* INFO */ *vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unexpected VFO value '%c'\n", __func__, vfoch); return -RIG_EVFO; } return RIG_OK; } /* * thf7e_vfo_op */ int thf7e_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!rig) { return -RIG_EINVAL; } switch (op) { case RIG_OP_UP: return kenwood_transaction(rig, "UP", NULL, 0); case RIG_OP_DOWN: return kenwood_transaction(rig, "DW", NULL, 0); /* Not implemented! case RIG_OP_BAND_UP: return kenwood_transaction(rig, "BU", NULL, 0); case RIG_OP_BAND_DOWN: return kenwood_transaction(rig, "BD", NULL, 0); */ default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported op %#x\n", __func__, op); return -RIG_EINVAL; } } hamlib-4.6.2/rigs/kenwood/ts480.c0000644000175000017500000024115414752216205013353 00000000000000/* * Hamlib Kenwood backend - TS-480 description * Copyright (c) 2000-2004 by Stephane Fillod and Juergen Rinas * Copyright (c) 2021 by Mikael Nousiainen * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include #include "cal.h" #include "idx_builtin.h" #include "iofunc.h" #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) #define PS8000A_ALL_MODES (RIG_MODE_AM|RIG_MODE_AMS|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define QMX_ALL_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_PKTUSB|RIG_MODE_PKTLSB) #define TS480_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS480_AM_TX_MODES RIG_MODE_AM #define TS480_VFO (RIG_VFO_A|RIG_VFO_B) #define TS480_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| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define PT8000A_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_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define TS480_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define PT8000A_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define TS480_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT| \ RIG_FUNC_TUNER|RIG_FUNC_MON|RIG_FUNC_FBKIN|RIG_FUNC_LOCK) #define TS480_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) // TS-480 S-meter calibration table based on LCD display bars #define TS480_STR_CAL { 9, \ { \ { 0, -60 }, \ { 3, -48 }, \ { 5, -36 }, \ { 7, -24 }, \ { 9, -12 }, \ { 11, 0 }, \ { 14, 20 }, \ { 17, 40 }, \ { 20, 60 } \ } } // TS-480 SWR calibration table based approximately on LCD display bars #define TS480_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 4, 1.5f }, \ { 8, 2.0f }, \ { 12, 3.0f }, \ { 20, 10.0f } \ } } #define TOK_FUNC_NOISE_REDUCTION_2 TOKEN_BACKEND(102) #define TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT TOKEN_BACKEND(103) #define TOK_LEVEL_DSP_RX_EQUALIZER TOKEN_BACKEND(104) #define TOK_LEVEL_DSP_TX_EQUALIZER TOKEN_BACKEND(105) #define TOK_LEVEL_DSP_TX_BANDWIDTH TOKEN_BACKEND(106) #define TOK_LEVEL_BEEP_VOLUME TOKEN_BACKEND(107) #define TOK_LEVEL_TX_SIDETONE_VOLUME TOKEN_BACKEND(108) #define TOK_LEVEL_AF_INPUT_LEVEL TOKEN_BACKEND(109) #define TOK_LEVEL_AF_OUTPUT_LEVEL TOKEN_BACKEND(110) #define TOK_LEVEL_DIGITAL_NOISE_LIMITER TOKEN_BACKEND(111) #define TOK_FUNC_CW_IF_FOR_SSB_RX TOKEN_BACKEND(112) int ts480_ext_tokens[] = { TOK_FUNC_NOISE_REDUCTION_2, TOK_FUNC_FILTER_WIDTH_DATA, TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT, TOK_LEVEL_DSP_RX_EQUALIZER, TOK_LEVEL_DSP_TX_EQUALIZER, TOK_LEVEL_DSP_TX_BANDWIDTH, TOK_LEVEL_BEEP_VOLUME, TOK_LEVEL_TX_SIDETONE_VOLUME, TOK_LEVEL_AF_INPUT_LEVEL, TOK_LEVEL_AF_OUTPUT_LEVEL, TOK_LEVEL_DIGITAL_NOISE_LIMITER, TOK_FUNC_CW_IF_FOR_SSB_RX, TOK_BACKEND_NONE, }; const struct confparams ts480_ext_funcs[] = { { TOK_FUNC_NOISE_REDUCTION_2, "NR2", "Noise reduction 2", "Noise reduction 2", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_FUNC_CW_IF_FOR_SSB_RX, "CW_IF_FOR_SSB_RX", "CW IF filter for SSB", "Use CW IF filter for SSB reception", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_FUNC_FILTER_WIDTH_DATA, "FILTER_WIDTH_DATA", "Filter bandwidth for data", "Filter bandwidth for data communications", NULL, RIG_CONF_CHECKBUTTON, }, { TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT, "TX_AUDIO_FROM_DATA_INPUT", "TX audio from data input", "Transmit with audio input from the data terminal", NULL, RIG_CONF_CHECKBUTTON, }, { RIG_CONF_END, NULL, } }; const struct confparams ts480_ext_levels[] = { { TOK_LEVEL_DIGITAL_NOISE_LIMITER, "DIGITAL_NOISE_LIMITER", "Digital Noise Limiter", "Digital Noise Limiter", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "DNL Level 1", "DNL Level 2", "DNL Level 3", NULL } } } }, { TOK_LEVEL_DSP_RX_EQUALIZER, "DSP_RX_EQUALIZER", "DSP RX equalizer", "DSP RX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "c", "U", NULL } } } }, { TOK_LEVEL_DSP_TX_EQUALIZER, "DSP_TX_EQUALIZER", "DSP TX equalizer", "DSP TX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "Hb1", "Hb2", "FP", "bb1", "bb2", "c", "U", NULL } } } }, { TOK_LEVEL_DSP_TX_BANDWIDTH, "DSP_TX_BANDWIDTH", "DSP TX bandwidth", "DSP TX bandwidth for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2.0 kHz", "2.4 kHz", NULL } } } }, { TOK_LEVEL_BEEP_VOLUME, "BEEP_VOLUME", "Beep volume", "Beep volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_TX_SIDETONE_VOLUME, "TX_SIDETONE_VOLUME", "TX sidetone volume", "TX sidetone volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_AF_INPUT_LEVEL, "AF_INPUT_LEVEL", "AF input level", "AF input level for data communications", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_AF_OUTPUT_LEVEL, "AF_OUTPUT_LEVEL", "AF output level", "AF output level for data communications", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { RIG_CONF_END, NULL, } }; /* * kenwood_ts480_get_info * Assumes rig!=NULL */ const char * kenwood_ts480_get_info(RIG *rig) { char firmbuf[50]; int retval; size_t firm_len; retval = kenwood_transaction(rig, "TY", firmbuf, sizeof(firmbuf)); if (retval != RIG_OK) { return NULL; } firm_len = strlen(firmbuf); if (firm_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)firm_len); return NULL; } switch (firmbuf[4]) { case '0': return "TS-480HX (200W)"; case '1': return "TS-480SAT (100W + AT)"; case '2': return "Japanese 50W type"; case '3': return "Japanese 20W type"; default: return "Firmware: unknown"; } } static int ts480_set_ex_menu(RIG *rig, int number, int value_len, int value) { char buf[20]; ENTERFUNC; SNPRINTF(buf, sizeof(buf), "EX%03d0000%0*d", number, value_len, value); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } static int ts480_get_ex_menu(RIG *rig, int number, int value_len, int *value) { int retval; char buf[20]; char ackbuf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(buf, sizeof(buf), "EX%03d0000", number); retval = kenwood_safe_transaction(rig, buf, ackbuf, sizeof(ackbuf), 9 + value_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(ackbuf + 9, "%d", value); RETURNFUNC2(RIG_OK); } static int ts480_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (func) { case RIG_FUNC_MON: SNPRINTF(buf, sizeof(buf), "ML00%c", (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c%c", (status == 0) ? '0' : '1', (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); default: return kenwood_set_func(rig, vfo, func, status); } } static int ts480_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[20]; int retval; ENTERFUNC; switch (func) { case RIG_FUNC_MON: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(buf, "ML%d", &raw_value); *status = (raw_value > 0); break; } case RIG_FUNC_LOCK: retval = kenwood_safe_transaction(rig, "LK", buf, sizeof(buf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[2] != '0' || buf[3] != '0'; break; default: RETURNFUNC(kenwood_get_func(rig, vfo, func, status)); } RETURNFUNC(RIG_OK); } /* * WARNING: The commands differ slightly from the general versions in kenwood.c * e.g.: "SQ"=>"SQ0" , "AG"=>"AG0" */ int kenwood_ts480_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RF: kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_AF: return kenwood_set_level(rig, vfo, level, val); case RIG_LEVEL_SQL: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "SQ0%03d", kenwood_val); break; case RIG_LEVEL_AGC: /* hamlib argument is int, possible values rig.h:enum agc_level_e */ /* possible values for TS480 000(=off), 001(=fast), 002(=slow) */ rig_debug(RIG_DEBUG_VERBOSE, "%s TS480 RIG_LEVEL_AGC\n", __func__); switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_FAST: kenwood_val = 1; break; case RIG_AGC_SLOW: kenwood_val = 2; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value", __func__); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_MONITOR_GAIN: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", kenwood_val); break; case RIG_LEVEL_NB: kenwood_val = val.f * 10.0; SNPRINTF(levelbuf, sizeof(levelbuf), "NL%03d", kenwood_val); break; case RIG_LEVEL_NR: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RL%02d", kenwood_val); break; case RIG_LEVEL_PREAMP: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "PA%c", (val.i == 12) ? '1' : '0'); break; case RIG_LEVEL_ATT: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", (val.i == 12) ? 1 : 0); break; case RIG_LEVEL_METER: switch (val.i) { case RIG_METER_SWR: kenwood_val = 1; break; case RIG_METER_COMP: kenwood_val = 2; break; case RIG_METER_ALC: kenwood_val = 3; break; default: RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RM%d", kenwood_val); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { RETURNFUNC2(-RIG_EINVAL); } RETURNFUNC2(ts480_set_ex_menu(rig, 34, 2, (val.i - 400) / 50)); default: return kenwood_set_level(rig, vfo, level, val); } return kenwood_transaction(rig, levelbuf, NULL, 0); } static int ts480_read_meters(RIG *rig, int *swr, int *comp, int *alc) { int retval; char *cmd = "RM;"; struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 24; ENTERFUNC; retval = write_block(rp, (unsigned char *) cmd, strlen(cmd)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); if (retval != RIG_OK) { RETURNFUNC(retval); } // TS-480 returns values for all meters at the same time, for example: RM10000;RM20000;RM30000; retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to read rig response\n", __func__); RETURNFUNC(retval); } if (retval != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d bytes, got %d in '%s'\n", __func__, expected_len, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } retval = sscanf(ackbuf, "RM1%d;RM2%d;RM3%d;", swr, comp, alc); if (retval != 3) { rig_debug(RIG_DEBUG_ERR, "%s: expected 3 meter values to parse, got %d in '%s'\n", __func__, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); } /* * kenwood_ts480_get_level * Assumes rig!=NULL, val!=NULL */ int kenwood_ts480_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len, ack_len_expected; int levelint; int retval; ENTERFUNC; switch (level) { case RIG_LEVEL_AF: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (5 != ack_len) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = levelint / (float) 100; RETURNFUNC(RIG_OK); case RIG_LEVEL_SQL: retval = kenwood_transaction(rig, "SQ0", ackbuf, sizeof(ackbuf)); ack_len_expected = 6; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) levelint / 255.; RETURNFUNC(RIG_OK); case RIG_LEVEL_AGC: retval = kenwood_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); ack_len_expected = 5; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } switch (ackbuf[ack_len_expected - 1]) { case '0': val->i = RIG_AGC_OFF; break; case '1': val->i = RIG_AGC_FAST; break; case '2': val->i = RIG_AGC_SLOW; break; default: RETURNFUNC(-RIG_EPROTO); } RETURNFUNC(RIG_OK); case RIG_LEVEL_STRENGTH: if (CACHE(rig)->ptt != RIG_PTT_OFF) { val->i = -9 * 6; break; } RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_MONITOR_GAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "ML%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_NB: { int raw_value; retval = kenwood_safe_transaction(rig, "NL", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NL%d", &raw_value); val->f = (float) raw_value / 10.0f; break; } case RIG_LEVEL_NR: { int raw_value; retval = kenwood_safe_transaction(rig, "RL", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RL%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[2] == '1' ? 12 : 0; break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[3] == '1' ? 12 : 0; break; case RIG_LEVEL_SWR: case RIG_LEVEL_COMP_METER: case RIG_LEVEL_ALC: { int swr; int comp; int alc; retval = ts480_read_meters(rig, &swr, &comp, &alc); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(swr, &rig->caps->swr_cal); } else { val->f = (float) swr / 2.0f; } break; case RIG_LEVEL_COMP_METER: val->f = (float) comp; // Maximum value is 20dB break; case RIG_LEVEL_ALC: // Maximum value is 20, so have the max at 5 just to be on the range where other rigs report ALC val->f = (float) alc / 4.0f; break; default: RETURNFUNC(-RIG_ENAVAIL); } break; } case RIG_LEVEL_RFPOWER_METER: { int raw_value; if (CACHE(rig)->ptt == RIG_PTT_OFF) { val->f = 0; break; } retval = kenwood_safe_transaction(rig, "SM0", ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "SM0%d", &raw_value); val->f = (float) raw_value / 20.0f; break; } case RIG_LEVEL_CWPITCH: { int raw_value; retval = ts480_get_ex_menu(rig, 34, 2, &raw_value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = 400 + raw_value * 50; break; } default: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); } RETURNFUNC(RIG_OK); } static int ts480_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[20]; int retval; int rit_enabled; int xit_enabled; ENTERFUNC; if (rit < -9999 || rit > 9999) { RETURNFUNC(-RIG_EINVAL); } // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (rit == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(buf, sizeof(buf), "R%c%05d", (rit > 0) ? 'U' : 'D', abs((int) rit)); retval = kenwood_transaction(rig, buf, NULL, 0); RETURNFUNC(retval); } static int ts480_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(buf, &priv->info[18], 5); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } static int ts480_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { char cmdbuf[20]; int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "NR%d", status ? 2 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; case TOK_FUNC_CW_IF_FOR_SSB_RX: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 17, 1, status); break; case TOK_FUNC_FILTER_WIDTH_DATA: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 45, 1, status); break; case TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 60, 1, status); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts480_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: { int value; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "NR", ackbuf, sizeof(ackbuf), 3); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NR%d", &value); *status = (value == 2) ? 1 : 0; break; } case TOK_FUNC_CW_IF_FOR_SSB_RX: retval = ts480_get_ex_menu(rig, 17, 1, status); break; case TOK_FUNC_FILTER_WIDTH_DATA: retval = ts480_get_ex_menu(rig, 45, 1, status); break; case TOK_FUNC_TX_AUDIO_FROM_DATA_INPUT: retval = ts480_get_ex_menu(rig, 60, 1, status); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts480_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; char cmdbuf[20]; ENTERFUNC; switch (token) { case TOK_LEVEL_DIGITAL_NOISE_LIMITER: if (val.i < 0 || val.i > 3) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "DL%d%02d", val.i != 0 ? 1 : 0, val.i > 0 ? val.i - 1 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; case TOK_LEVEL_DSP_RX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 18, 1, val.i); break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (val.i < 0 || val.i > 7) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 19, 1, val.i); break; case TOK_LEVEL_DSP_TX_BANDWIDTH: if (val.i < 0 || val.i > 1) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 20, 1, val.i); break; case TOK_LEVEL_BEEP_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 12, 1, (int) val.f); break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 13, 1, (int) val.f); break; case TOK_LEVEL_AF_INPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 46, 1, (int) val.f); break; case TOK_LEVEL_AF_OUTPUT_LEVEL: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts480_set_ex_menu(rig, 47, 1, (int) val.f); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts480_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; int value; ENTERFUNC; switch (token) { case TOK_LEVEL_DIGITAL_NOISE_LIMITER: { int enabled; int level; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "DL", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "DL%1d%2d", &enabled, &level); val->i = enabled ? level + 1 : 0; break; } case TOK_LEVEL_DSP_RX_EQUALIZER: retval = ts480_get_ex_menu(rig, 18, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_EQUALIZER: retval = ts480_get_ex_menu(rig, 19, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_BANDWIDTH: retval = ts480_get_ex_menu(rig, 20, 1, &value); val->i = value; break; case TOK_LEVEL_BEEP_VOLUME: retval = ts480_get_ex_menu(rig, 12, 1, &value); val->f = value; break; case TOK_LEVEL_TX_SIDETONE_VOLUME: retval = ts480_get_ex_menu(rig, 13, 1, &value); val->f = value; break; case TOK_LEVEL_AF_INPUT_LEVEL: retval = ts480_get_ex_menu(rig, 46, 1, &value); val->f = value; break; case TOK_LEVEL_AF_OUTPUT_LEVEL: retval = ts480_get_ex_menu(rig, 47, 1, &value); val->f = value; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static struct kenwood_filter_width ts480_filter_width[] = { { RIG_MODE_CW | RIG_MODE_CWR, 50, 50 }, { RIG_MODE_CW | RIG_MODE_CWR, 80, 80 }, { RIG_MODE_CW | RIG_MODE_CWR, 100, 100 }, { RIG_MODE_CW | RIG_MODE_CWR, 150, 150 }, { RIG_MODE_CW | RIG_MODE_CWR, 200, 200 }, { RIG_MODE_CW | RIG_MODE_CWR, 300, 300 }, { RIG_MODE_CW | RIG_MODE_CWR, 400, 400 }, { RIG_MODE_CW | RIG_MODE_CWR, 500, 500 }, { RIG_MODE_CW | RIG_MODE_CWR, 600, 600 }, { RIG_MODE_CW | RIG_MODE_CWR, 1000, 1000 }, { RIG_MODE_CW | RIG_MODE_CWR, 2000, 2000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 250, 250 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 500, 500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1000, 1000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1500, 1500 }, { RIG_MODE_SSB, 0, 2400 }, { RIG_MODE_SSB, 1, 500 }, // NAR1 optional filter { RIG_MODE_SSB, 2, 270 }, // NAR2 optional filter { RIG_MODE_FM, 0, 12000 }, { RIG_MODE_AM, 0, 6000 }, { RIG_MODE_AM, 1, 2400 }, // NAR1 optional filter (?) { RIG_MODE_NONE, -1, -1 }, }; static struct kenwood_slope_filter ts480_slope_filter_high[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 1000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 1200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 1400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 1600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 1800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 2000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 2200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 2400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 2600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 2800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 3000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 3400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 12, 4000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 13, 5000 }, { RIG_MODE_AM, 0, 0, 2500 }, { RIG_MODE_AM, 0, 1, 3000 }, { RIG_MODE_AM, 0, 2, 4000 }, { RIG_MODE_AM, 0, 3, 5000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 1000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 2, 2210 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_slope_filter ts480_slope_filter_low[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 0 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 50 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 100 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 300 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 500 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 700 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 900 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 1000 }, { RIG_MODE_AM, 0, 0, 0 }, { RIG_MODE_AM, 0, 1, 100 }, { RIG_MODE_AM, 0, 2, 200 }, { RIG_MODE_AM, 0, 3, 500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 50 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 100 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 2, 250 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 3, 500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 4, 1000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 5, 1500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 6, 2400 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_priv_caps ts480_priv_caps = { .cmdtrm = EOM_KEN, .filter_width = ts480_filter_width, .slope_filter_high = ts480_slope_filter_high, .slope_filter_low = ts480_slope_filter_low, }; int ts480_init(RIG *rig) { struct kenwood_priv_data *priv; int retval; ENTERFUNC; retval = kenwood_init(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } priv = (struct kenwood_priv_data *) STATE(rig)->priv; priv->ag_format = 2; priv->micgain_min = 0; priv->micgain_max = 100; RETURNFUNC(RIG_OK); } int qrplabs_open(RIG *rig) { int retval; char buf[64]; struct kenwood_priv_data *priv = (struct kenwood_priv_data *) STATE(rig)->priv; ENTERFUNC; retval = kenwood_open(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } retval = kenwood_transaction(rig, "VN", buf, sizeof(buf)); if (retval == RIG_OK) { strtok(buf, ";"); rig_debug(RIG_DEBUG_VERBOSE, "%s: firmware version %s\n", __func__, &buf[2]); } priv->is_emulation = 1; RETURNFUNC(retval); } int qdx_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { const char *ptt_cmd; struct hamlib_port *rp = RIGPORT(rig); ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s: ptt=%d\n", __func__, ptt); switch (ptt) { case RIG_PTT_ON: ptt_cmd = "TQ1"; break; case RIG_PTT_OFF: ptt_cmd = "TQ0"; break; default: RETURNFUNC(-RIG_EINVAL); } int retval = kenwood_transaction(rig, ptt_cmd, NULL, 0); hl_usleep(100 * 1000); // a little time for PTT to return whatever it returns which we ignore rig_flush(rp); RETURNFUNC(retval); } int qrplabs_get_clock(RIG *rig, int *year, int *month, int *day, int *hour, int *min, int *sec, double *msec, int *utc_offset) { char tm_cmd[32]; char tm_buf[32]; *year = *month = *day = *hour = *min = *sec = *msec = *utc_offset = 0; *month = 0; *day = 0; sprintf(tm_cmd, "TM;"); int retval = kenwood_transaction(rig, tm_cmd, tm_buf, sizeof(tm_buf)); if (retval == RIG_OK && strlen(tm_buf) >= 8) { sscanf(tm_buf, "TM%02d%02d%02d", hour, min, sec); } return retval; } int qrplabs_set_clock(RIG *rig, int year, int month, int day, int hour, int min, int sec, double msec, int utc_offset) { char tm_cmd[32]; sprintf(tm_cmd, "TM%02d%02d%02d;", hour, min, sec); int retval = kenwood_transaction(rig, tm_cmd, NULL, 0); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting time: %s\n", __func__, rigerror(retval)); } return retval; } /* * TS-480 rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps ts480_caps = { RIG_MODEL(RIG_MODEL_TS480), .model_name = "TS-480", .mfg_name = "Kenwood", .version = BACKEND_VER ".3", .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 = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .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, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), kHz(3800), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7200), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7200), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), MHz(4) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7300), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7300), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .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 = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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 = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .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 = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * truSDC rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps trudx_caps = { RIG_MODEL(RIG_MODEL_TRUSDX), .model_name = "(tr)uSDX", .mfg_name = "DL2MAN", .version = BACKEND_VER ".1", .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 = 38400, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .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, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), kHz(3800), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7200), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7200), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), MHz(4) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7300), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7300), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .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 = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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 = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .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 = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * QRPLabs TS-480 emulation rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps qrplabs_caps = { RIG_MODEL(RIG_MODEL_QRPLABS), .model_name = "QCX/QDX", .mfg_name = "QRPLabs", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .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, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_FAST, RIG_AGC_SLOW }, .rx_range_list1 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {kHz(1810), kHz(1850), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1810), kHz(1850), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), kHz(3800), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), kHz(3800), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7200), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7200), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(3500), MHz(4) - 1, TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(5250), kHz(5450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(7), kHz(7300), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(7), kHz(7300), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(10100), kHz(10150), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(14), kHz(14350), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(14), kHz(14350), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(18068), kHz(18168), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(21), kHz(21450), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(21), kHz(21450), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {kHz(24890), kHz(24990), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(28), kHz(29700), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(28), kHz(29700), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, {MHz(50), kHz(52000), TS480_OTHER_TX_MODES, 5000, 100000, TS480_VFO}, {MHz(50), kHz(52000), TS480_AM_TX_MODES, 5000, 25000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .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 = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = qrplabs_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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, .get_info = kenwood_ts480_get_info, .reset = kenwood_reset, .has_set_level = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .get_clock = qrplabs_get_clock, .set_clock = qrplabs_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps qrplabs_qmx_caps = { RIG_MODEL(RIG_MODEL_QRPLABS_QMX), .model_name = "QMX", .mfg_name = "QRPLabs", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_BETA, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 256000, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 3, .preamp = {12, RIG_DBLST_END,}, .attenuator = {12, RIG_DBLST_END,}, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .rx_range_list1 = { {MHz(4), MHz(14), QMX_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {MHz(4), MHz(14), QMX_ALL_MODES, 5000, 100000, TS480_VFO}, RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(3.2)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, RIG_FLT_END, }, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = qrplabs_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = kenwood_set_mode, .get_mode = kenwood_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_info = kenwood_ts480_get_info, .get_clock = qrplabs_get_clock, .set_clock = qrplabs_set_clock, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Hilberling PT8000A TS480 emulation * Notice that some rigs share the same functions. */ struct rig_caps pt8000a_caps = { RIG_MODEL(RIG_MODEL_PT8000A), .model_name = "PT-8000A", .mfg_name = "Hilberling", .version = BACKEND_VER ".2", .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 = 9600, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 500, .retry = 10, .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, .transceive = RIG_TRN_RIG, .rx_range_list1 = { // not region specific {kHz(9), MHz(30), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_2 | RIG_ANT_3, "Generic"}, {MHz(50), MHz(54), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, {MHz(69.9), MHz(70.5), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, {MHz(110), MHz(143.99), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, {MHz(144), MHz(148), PS8000A_ALL_MODES, -1, -1, TS480_VFO, RIG_ANT_1, "Generic"}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { {MHz(1.8), MHz(30), TS480_OTHER_TX_MODES, 1000, 200000, TS480_VFO, RIG_ANT_2 | RIG_ANT_3, "Generic"}, /* 200W class */ {MHz(1.8), MHz(30), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 50000, TS480_VFO, RIG_ANT_2 | RIG_ANT_3, "Generic"}, /* 50W class */ {MHz(50), MHz(54), TS480_OTHER_TX_MODES, 1000, 100000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 100W class */ {MHz(50), MHz(54), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 25000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 25W class */ {MHz(69.9), MHz(70.5), TS480_OTHER_TX_MODES, 1000, 100000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 100W class */ {MHz(69.9), MHz(70.5), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 25000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 25W class */ {MHz(144), MHz(148), TS480_OTHER_TX_MODES, 1000, 100000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 100W class */ {MHz(144), MHz(148), TS480_AM_TX_MODES | RIG_MODE_AMS, 5000, 25000, TS480_VFO, RIG_ANT_1, "Generic"}, /* 25W class */ RIG_FRNG_END, }, .tuning_steps = { {PS8000A_ALL_MODES, Hz(1)}, {PS8000A_ALL_MODES, Hz(10)}, {PS8000A_ALL_MODES, Hz(100)}, {PS8000A_ALL_MODES, Hz(1000)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(6.0)}, {RIG_MODE_SSB, kHz(1.0)}, {RIG_MODE_SSB, kHz(1.2)}, {RIG_MODE_SSB, kHz(1.4)}, {RIG_MODE_SSB, kHz(1.6)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(1.9)}, {RIG_MODE_SSB, kHz(2.0)}, {RIG_MODE_SSB, kHz(2.1)}, {RIG_MODE_SSB, kHz(2.2)}, {RIG_MODE_SSB, kHz(2.3)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(2.5)}, {RIG_MODE_SSB, kHz(2.6)}, {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(2.9)}, {RIG_MODE_SSB, kHz(3.0)}, {RIG_MODE_SSB, kHz(3.1)}, {RIG_MODE_SSB, kHz(3.2)}, {RIG_MODE_SSB, kHz(3.3)}, {RIG_MODE_SSB, kHz(3.4)}, {RIG_MODE_SSB, kHz(3.5)}, {RIG_MODE_SSB, kHz(4.6)}, {RIG_MODE_CW, Hz(50)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_CW, Hz(400)}, {RIG_MODE_CW, Hz(500)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_AM, kHz(2.5)}, {RIG_MODE_AM, kHz(2.6)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, kHz(2.8)}, {RIG_MODE_AM, kHz(2.9)}, {RIG_MODE_AM, kHz(3.0)}, {RIG_MODE_AM, kHz(3.1)}, {RIG_MODE_AM, kHz(3.2)}, {RIG_MODE_AM, kHz(3.3)}, {RIG_MODE_AM, kHz(3.4)}, {RIG_MODE_AM, kHz(3.5)}, {RIG_MODE_AM, kHz(3.5)}, {RIG_MODE_AM, kHz(4.6)}, {RIG_MODE_AM, kHz(6.0)}, {RIG_MODE_FM, kHz(2.4)}, {RIG_MODE_FM, kHz(2.5)}, {RIG_MODE_FM, kHz(2.6)}, {RIG_MODE_FM, kHz(2.7)}, {RIG_MODE_FM, kHz(2.8)}, {RIG_MODE_FM, kHz(2.9)}, {RIG_MODE_FM, kHz(3.0)}, {RIG_MODE_FM, kHz(3.1)}, {RIG_MODE_FM, kHz(3.2)}, {RIG_MODE_FM, kHz(3.3)}, {RIG_MODE_FM, kHz(3.4)}, {RIG_MODE_FM, kHz(3.5)}, {RIG_MODE_FM, kHz(3.5)}, {RIG_MODE_FM, kHz(4.6)}, {RIG_MODE_FM, kHz(6.0)}, RIG_FLT_END, }, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .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}}, }, .priv = (void *)& ts480_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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 = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .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 = PT8000A_LEVEL_SET, .has_get_level = PT8000A_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * SDRPlay SDRUno rig capabilities * Notice that some rigs share the same functions. */ struct rig_caps sdruno_caps = { RIG_MODEL(RIG_MODEL_SDRUNO), .model_name = "SDRUno", .mfg_name = "SDRPlay", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .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, .transceive = RIG_TRN_RIG, .rx_range_list1 = { {kHz(100), Hz(59999999), SDRUNO_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 1 */ .tx_range_list1 = { RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 1 */ .rx_range_list2 = { {kHz(100), Hz(59999999), TS480_ALL_MODES, -1, -1, TS480_VFO}, RIG_FRNG_END, }, /*!< Receive frequency range list for ITU region 2 */ .tx_range_list2 = { RIG_FRNG_END, }, /*!< Transmit frequency range list for ITU region 2 */ .tuning_steps = { {TS480_ALL_MODES, kHz(1)}, {TS480_ALL_MODES, Hz(2500)}, {TS480_ALL_MODES, kHz(5)}, {TS480_ALL_MODES, Hz(6250)}, {TS480_ALL_MODES, kHz(10)}, {TS480_ALL_MODES, Hz(12500)}, {TS480_ALL_MODES, kHz(15)}, {TS480_ALL_MODES, kHz(20)}, {TS480_ALL_MODES, kHz(25)}, {TS480_ALL_MODES, kHz(30)}, {TS480_ALL_MODES, kHz(100)}, {TS480_ALL_MODES, kHz(500)}, {TS480_ALL_MODES, MHz(1)}, {TS480_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, Hz(270)}, {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_PKTUSB, kHz(4)}, RIG_FLT_END, }, .vfo_ops = TS480_VFO_OPS, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .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 = TS480_STR_CAL, .swr_cal = TS480_SWR_CAL, .ext_tokens = ts480_ext_tokens, .extfuncs = ts480_ext_funcs, .extlevels = ts480_ext_levels, .priv = (void *)& ts480_priv_caps, .rig_init = ts480_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts480_set_rit, .get_rit = ts480_get_rit, .set_xit = ts480_set_rit, .get_xit = ts480_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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 = kenwood_ts480_get_info, .reset = kenwood_reset, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .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 = TS480_LEVEL_SET, .has_get_level = TS480_LEVEL_GET, .set_level = kenwood_ts480_set_level, .get_level = kenwood_ts480_get_level, .set_ext_level = ts480_set_ext_level, .get_ext_level = ts480_get_ext_level, .has_get_func = TS480_FUNC_ALL, .has_set_func = TS480_FUNC_ALL, .set_func = ts480_set_func, .get_func = ts480_get_func, .set_ext_func = ts480_set_ext_func, .get_ext_func = ts480_get_ext_func, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; const struct confparams malachite_cfg_parms[] = { { // the Malachite SDR cannot handle sending ID; after FA; commands TOK_NO_ID, "no_id", "No ID", "If true do not send ID; with set commands", NULL, RIG_CONF_CHECKBUTTON, { } }, { RIG_CONF_END, NULL, } }; int malachite_init(RIG *rig) { struct kenwood_priv_data *priv; int retval; ENTERFUNC; retval = kenwood_init(rig); priv = STATE(rig)->priv; priv->no_id = 1; // the Malchite doesn't like the ID; verify cmd if (retval != RIG_OK) { RETURNFUNC(retval); } RETURNFUNC(RIG_OK); } int malachite_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int post_write_delay_save = STATE(rig)->post_write_delay; STATE(rig)->post_write_delay = 0; int retval = kenwood_get_mode(rig, vfo, mode, width); STATE(rig)->post_write_delay = post_write_delay_save; return retval; } int malachite_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int post_write_delay_save = STATE(rig)->post_write_delay; ENTERFUNC; STATE(rig)->post_write_delay = 0; int retval = kenwood_get_freq(rig, vfo, freq); STATE(rig)->post_write_delay = post_write_delay_save; RETURNFUNC(retval); } int malachite_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; struct rig_cache *cachep = CACHE(rig); ENTERFUNC; rig_debug(RIG_DEBUG_TRACE, "%s: freqMainA=%g, freq=%g\n", __func__, cachep->freqMainA, freq); if ((cachep->freqMainA < 400000000 && freq >= 400000000) || (cachep->freqMainA >= 400000000 && freq < 400000000) || cachep->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); STATE(rig)->post_write_delay = 250; // need a bit more time on band change if (retval != RIG_OK) { RETURNFUNC(retval); } } else { STATE(rig)->post_write_delay = 125; } retval = kenwood_set_freq(rig, vfo, freq); RETURNFUNC(retval); } /* * Malachite SDR rig capabilities. * Notice that some rigs share the same functions. */ struct rig_caps malachite_caps = { RIG_MODEL(RIG_MODEL_MALACHITE), .model_name = "DSP", .mfg_name = "Malachite", .version = BACKEND_VER ".4", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_RECEIVER, .ptt_type = RIG_PTT_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, // 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, .transceive = RIG_TRN_POLL, .rx_range_list1 = { {kHz(50), MHz(250), TS480_ALL_MODES, -1, -1, RIG_VFO_A, RIG_ANT_CURR, "Generic" }, {MHz(400), GHz(2), TS480_ALL_MODES, -1, -1, RIG_VFO_A, RIG_ANT_CURR, "Generic" }, RIG_FRNG_END, }, .tuning_steps = { {RIG_MODE_ALL, Hz(1)}, RIG_TS_END }, .filters = { {RIG_MODE_ALL, RIG_FLT_ANY}, RIG_FLT_END }, .priv = (void *)& ts480_priv_caps, .rig_init = malachite_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = malachite_set_freq, .get_freq = malachite_get_freq, .set_mode = kenwood_set_mode, .get_mode = malachite_get_mode, .set_vfo = kenwood_set_vfo, // Malachite only supports VFOA .get_vfo = kenwood_get_vfo_if, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/elecraft.c0000644000175000017500000004364614752216205014264 00000000000000/* * Hamlib Elecraft backend--support Elecraft extensions to Kenwood commands * Copyright (C) 2010,2011 by Nate Bargmann, n0nb@n0nb.us * Copyright (C) 2011 by Alexander Sack, Alexander Sack, pisymbol@gmail.com * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include "serial.h" #include "elecraft.h" #include "kenwood.h" #include "misc.h" static const struct elec_ext_id_str elec_ext_id_str_lst[] = { { K20, "K20" }, { K21, "K21" }, { K22, "K22" }, { K23, "K23" }, { K30, "K30" }, { K31, "K31" }, { EXT_LEVEL_NONE, NULL }, /* end marker */ }; /* K3 firmware revision level, will be assigned to the fw_rev pointer in * kenwood_priv_data structure at runtime in electraft_open(). The array is * declared here so that the sizeof operator can be used in the call to * elecraft_get_firmware_revision_level() to calculate the exact size of the * array for the call to strncpy(). */ static char k3_fw_rev[KENWOOD_MAX_BUF_LEN]; /* Private Elecraft extra levels definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams elecraft_ext_levels[] = { { TOK_IF_FREQ, "ifctr", "IF freq", "IF center frequency", NULL, RIG_CONF_NUMERIC, { .n = { 0, 9990, 10 } } }, { TOK_TX_STAT, "txst", "TX status", "TX status", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", NULL, RIG_CONF_BUTTON, { { } }, }, { RIG_CONF_END, NULL, } }; /* Private function declarations */ int verify_kenwood_id(RIG *rig, char *id); int elecraft_get_extension_level(RIG *rig, const char *cmd, int *ext_level); int elecraft_get_firmware_revision_level(RIG *rig, const char *cmd, char *fw_rev, size_t fw_rev_sz); /* Shared backend function definitions */ /* elecraft_open() * * First checks for ID of '017' then tests for an Elecraft radio/backend using * the K2; command. Here we also test for a K3 and if that fails, assume a K2. * Finally, save the value for later reading. * */ int elecraft_open(RIG *rig) { int err; char buf[KENWOOD_MAX_BUF_LEN]; char *model = "Unknown"; struct rig_state *rs = STATE(rig); struct hamlib_port *rp = RIGPORT(rig); struct kenwood_priv_data *priv = rs->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called, rig version=%s\n", __func__, rig->caps->version); if (rs->auto_power_on && priv->poweron == 0) { rig_set_powerstat(rig, 1); priv->poweron = 1; } /* Actual read extension levels from radio. * * The value stored in the k?_ext_lvl variables map to * elec_ext_id_str_lst.level and is only written to by the * elecraft_get_extension_level() private function during elecraft_open() * and thereafter shall be treated as READ ONLY! */ /* As k3_fw_rev is declared static, it is persistent so the structure * can point to it. This way was chosen to allow the compiler to * calculate the size of the array to resolve a bug found by gcc 4.8.x */ priv->fw_rev = k3_fw_rev; /* Use check for "ID017;" to verify rig is reachable */ rig_debug(RIG_DEBUG_TRACE, "%s: rig_model=%u,%d\n", __func__, rig->caps->rig_model, RIG_MODEL_XG3); if (rig->caps->rig_model == RIG_MODEL_XG3) // XG3 doesn't have ID { char *cmd = "V;"; char data[32]; strcpy(data, "EMPTY"); // Not going to get carried away with retries and such err = write_block(rp, (unsigned char *) cmd, strlen(cmd)); if (err != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: XG3 cannot request identification\n", __func__); return err; } err = read_string(rp, (unsigned char *) buf, sizeof(buf), ";", 1, 0, 1); if (err < 0) { rig_debug(RIG_DEBUG_TRACE, "%s: XG3 cannot get identification\n", __func__); return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: id=%s\n", __func__, buf); #if 0 if (err != RIG_OK) { rig_debug(RIG_DEBUG_TRACE, "%s: cannot get identification\n", __func__); return err; } #endif } else // Standard Kenwood { err = verify_kenwood_id(rig, buf); if (err != RIG_OK) { return err; } } priv->save_k2_ext_lvl = -1; // so we don't restore if not neeede if (rig->caps->rig_model != RIG_MODEL_XG3) // XG3 doesn't have extended { err = elecraft_get_extension_level(rig, "K2", &priv->save_k2_ext_lvl); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error getting K2 ext_lvl: %s\n", __func__, rigerror(err)); return err; } // turn on k2 extended to get PC values in more resolution err = kenwood_transaction(rig, "K22;", NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error setting K22='%s'...continuing\n", __func__, rigerror(err)); } } switch (rig->caps->rig_model) { case RIG_MODEL_K2: err = elecraft_get_extension_level(rig, "K2", &priv->k2_ext_lvl); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: K2 level is %d, %s\n", __func__, priv->k2_ext_lvl, elec_ext_id_str_lst[priv->k2_ext_lvl].id); priv->is_k2 = 1; break; case RIG_MODEL_K3: case RIG_MODEL_K3S: case RIG_MODEL_KX2: case RIG_MODEL_KX3: case RIG_MODEL_K4: // we need to know what's hooked up for PC command max levels err = kenwood_safe_transaction(rig, "OM", buf, KENWOOD_MAX_BUF_LEN, 15); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_TRACE, "%s: OM=%s\n", __func__, buf); priv->has_kpa3 = 0; if (strstr(buf, "P")) { priv->has_kpa3 = 1; } // could also use K4; command priv->is_k3 = 1; // default to K3 if (rig->caps->rig_model == RIG_MODEL_K4) { priv->is_k3 = 0; priv->is_k4 = 1; } else if (strstr(buf, "R")) { priv->is_k3 = 0; priv->is_k3s = 1; } // combination of OM flags determines model if (strstr(buf, "S") && strstr(buf, "4") && strstr(buf, "H")) { // new firmware should recognize k4hd now priv->is_k4 = priv->is_k3 = 0; priv->is_k4hd = 1; } else if (strstr(buf, "S") && strstr(buf, "4")) { priv->is_k4 = priv->is_k3 = 0; priv->is_k4d = 1; } if (buf[13] == '0') // then we have a KX3 or KX2 { char modelnum; modelnum = buf[14]; switch (modelnum) { case '1': priv->is_k2 = 0; model = "KX2"; priv->is_kx2 = 1; break; case '2': model = "KX3"; priv->is_k3 = 0; priv->is_kx3 = 1; break; default: rig_debug(RIG_DEBUG_ERR, "%s: Unknown Elecraft modelnum=%c, expected 1 or 2\n", __func__, modelnum); break; } if (strstr(buf, "P")) { priv->has_kpa100 = 1; } } else { model = "K3"; if (strstr(buf, "R")) { model = "K3S"; } } rig_debug(RIG_DEBUG_TRACE, "%s: model=%s, is_k2=%d, is_k3=%d, is_k3s=%d, is_kx3=%d, is_kx2=%d, is_k4=%d, is_k4d=%d, is_k4hd=%d, kpa3=%d\n", __func__, model, priv->is_k2, priv->is_k3, priv->is_k3s, priv->is_kx3, priv->is_kx2, priv->is_k4, priv->is_k4d, priv->is_k4hd, priv->has_kpa3); err = elecraft_get_extension_level(rig, "K2", &priv->k2_ext_lvl); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: K2 level is %d, %s\n", __func__, priv->k2_ext_lvl, elec_ext_id_str_lst[priv->k2_ext_lvl].id); err = elecraft_get_extension_level(rig, "K3", &priv->k3_ext_lvl); if (err != RIG_OK) { return err; } rig_debug(RIG_DEBUG_VERBOSE, "%s: K3 level is %d, %s\n", __func__, priv->k3_ext_lvl, elec_ext_id_str_lst[priv->k3_ext_lvl].id); err = elecraft_get_firmware_revision_level(rig, "RVM", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVM failed\n", __func__); return err; } err = elecraft_get_firmware_revision_level(rig, "RVD", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVD failed\n", __func__); } if (priv->is_k3) { err = elecraft_get_firmware_revision_level(rig, "RVA", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVA failed\n", __func__); } err = elecraft_get_firmware_revision_level(rig, "RVR", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVR failed\n", __func__); } err = elecraft_get_firmware_revision_level(rig, "RVF", priv->fw_rev, (sizeof(k3_fw_rev) / sizeof(k3_fw_rev[0]))); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: Firmware RVF failed\n", __func__); } } break; case RIG_MODEL_XG3: rig_debug(RIG_DEBUG_VERBOSE, "%s: XG3 level is %d, %s\n", __func__, priv->k3_ext_lvl, elec_ext_id_str_lst[priv->k3_ext_lvl].id); break; default: rig_debug(RIG_DEBUG_WARN, "%s: unrecognized rig model %u\n", __func__, rig->caps->rig_model); return -RIG_EINVAL; } if (RIG_MODEL_XG3 != rig->caps->rig_model) { /* get current AI state so it can be restored */ priv->trn_state = -1; kenwood_get_trn(rig, &priv->trn_state); /* ignore errors */ /* Currently we cannot cope with AI mode so turn it off in case last client left it on */ kenwood_set_trn(rig, RIG_TRN_OFF); /* ignore status in case it's not supported */ } // For rigs like K3X vfo emulation need to set VFO_A to start vfo_t vfo; rig_get_vfo(rig, &vfo); if (vfo != RIG_VFO_A && vfo != RIG_VFO_B) { rig_set_vfo(rig, RIG_VFO_A); } return RIG_OK; } int elecraft_close(RIG *rig) { const struct kenwood_priv_data *priv = STATE(rig)->priv; if (priv->save_k2_ext_lvl >= 0) { int err; char cmd[32]; sprintf(cmd, "K2%d;", priv->save_k2_ext_lvl); err = kenwood_transaction(rig, cmd, NULL, 0); if (err != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: error restoring %s='%s'...continuing\n", __func__, cmd, rigerror(err)); } } return kenwood_close(rig); } /* Private helper functions */ /* Tests for Kenwood ID string of "017" */ int verify_kenwood_id(RIG *rig, char *id) { int err; char *idptr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!id) { return -RIG_EINVAL; } /* Check for an Elecraft K2|K3 which returns "017" */ err = kenwood_get_id(rig, id); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: cannot get identification\n", __func__); return err; } /* ID is 'ID017;' */ if (strlen(id) < 5) { rig_debug(RIG_DEBUG_VERBOSE, "%s: unknown ID type (%s)\n", __func__, id); return -RIG_EPROTO; } /* check for any white space and skip it */ idptr = &id[2]; if (*idptr == ' ') { idptr++; } if (strcmp("017", idptr) != 0) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig (%.4095s) is not a K2 or K3\n", __func__, id); // return -RIG_EPROTO; } else { rig_debug(RIG_DEBUG_VERBOSE, "%s: Rig ID is %.4095s\n", __func__, id); } return RIG_OK; } /* Determines K2 and K3 extension level */ int elecraft_get_extension_level(RIG *rig, const char *cmd, int *ext_level) { int err, i; char buf[KENWOOD_MAX_BUF_LEN]; char *bufptr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ext_level) { return -RIG_EINVAL; } err = kenwood_safe_transaction(rig, cmd, buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot get K2|K3 ID\n", __func__); return err; } /* Get extension level string */ bufptr = &buf[0]; for (i = 0; elec_ext_id_str_lst[i].level != EXT_LEVEL_NONE; i++) { if (strcmp(elec_ext_id_str_lst[i].id, bufptr) == 0) { *ext_level = elec_ext_id_str_lst[i].level; rig_debug(RIG_DEBUG_VERBOSE, "%s: %s extension level is %d, %s\n", __func__, cmd, *ext_level, elec_ext_id_str_lst[i].id); } } return RIG_OK; } /* Determine firmware revision level */ int elecraft_get_firmware_revision_level(RIG *rig, const char *cmd, char *fw_rev, size_t fw_rev_sz) { int err; char *bufptr; char buf[KENWOOD_MAX_BUF_LEN]; char rvp = cmd[2]; char *rv = "UNK"; if (rig->caps->rig_model == RIG_MODEL_K4) { switch (rvp) { case 'F': case 'M': rv = "FPF"; break; case 'A': case 'D': rv = "DSP"; break; case 'R': rv = "DAP"; break; } } else { switch (rvp) { case 'M': rv = "MCU"; break; case 'D': rv = "DSP"; break; case 'A': rv = "AUX"; break; case 'R': rv = "DVR"; break; case 'F': rv = "FPF"; break; } } rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!fw_rev) { return -RIG_EINVAL; } /* Get the actual firmware revision number. */ err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot get firmware revision level\n", __func__); return err; } /* Now buf[] contains the string from the K3 which includes the command * and the firmware revision number as: "RVM04.67". */ bufptr = &buf[0]; /* Skip the command string */ bufptr += strlen(cmd); /* Skip leading zero(s) as the revision number has the format of: "04.67" */ while (*bufptr == '0') { bufptr++; } /* Copy out */ strncpy(fw_rev, bufptr, fw_rev_sz - 1); rig_debug(RIG_DEBUG_VERBOSE, "%s: Elecraft %s firmware revision is %s\n", __func__, rv, fw_rev); return RIG_OK; } // FR;FT;TQ; is faster than IF; // Works on K4 int elecraft_get_vfo_tq(RIG *rig, vfo_t *vfo) { int retval; int fr, ft, tq; char cmdbuf[10]; char splitbuf[12]; ENTERFUNC2; memset(splitbuf, 0, sizeof(splitbuf)); SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR;"); retval = kenwood_safe_transaction(rig, cmdbuf, splitbuf, 12, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (sscanf(splitbuf, "FR%1d", &fr) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse FR '%s'\n", __func__, splitbuf); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT;"); retval = kenwood_safe_transaction(rig, cmdbuf, splitbuf, 12, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (sscanf(splitbuf, "FT%1d", &ft) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse FT '%s'\n", __func__, splitbuf); } // We can use the TQX; command but we have to check that we have R32 firmware or higher // Not sure it's much better than TQ; since it still seems to take 350ms // So we have to sleep for a while after sending it to avoid TCP timeouts which still needs to be fixed // See #if 0 if (rig->caps->rig_model == RIG_MODEL_K4) { SNPRINTF(cmdbuf, sizeof(cmdbuf), "TQX;"); } else #endif { SNPRINTF(cmdbuf, sizeof(cmdbuf), "TQ;"); } retval = kenwood_safe_transaction(rig, cmdbuf, splitbuf, 12, 3); if (retval != RIG_OK) { RETURNFUNC2(retval); } if (sscanf(splitbuf, "TQ%1d", &tq) != 1) { rig_debug(RIG_DEBUG_ERR, "%s: unable to parse TQ or TQX response of '%s'\n", __func__, splitbuf); } *vfo = STATE(rig)->tx_vfo = RIG_VFO_A; if (tq && ft == 1) { *vfo = STATE(rig)->tx_vfo = RIG_VFO_B; } else if (tq && ft == 0) { *vfo = STATE(rig)->tx_vfo = RIG_VFO_A; } if (!tq && fr == 1) { *vfo = STATE(rig)->rx_vfo = STATE(rig)->tx_vfo = RIG_VFO_B; } RETURNFUNC2(RIG_OK); } hamlib-4.6.2/rigs/kenwood/ts2000.c0000644000175000017500000020463214752216205013421 00000000000000/* * Hamlib Kenwood backend - TS2000 description * Copyright (c) 2000-2011 by Stephane Fillod * Copyright (c) 2023 by Mikael Nousiainen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include "kenwood.h" #include "token.h" #include "misc.h" #include "iofunc.h" #include "cal.h" #define TS2000_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY|RIG_MODE_RTTYR) #define TS2000_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS2000_AM_TX_MODES RIG_MODE_AM #define TS2000_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| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SWR|RIG_LEVEL_COMP_METER|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define TS2000_LEVEL_SET (RIG_LEVEL_RFPOWER|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_SQL|RIG_LEVEL_AGC|RIG_LEVEL_MICGAIN|RIG_LEVEL_KEYSPD|RIG_LEVEL_CWPITCH| \ RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_NB|RIG_LEVEL_NR|RIG_LEVEL_PREAMP|RIG_LEVEL_COMP|RIG_LEVEL_ATT|RIG_LEVEL_VOXDELAY|RIG_LEVEL_VOXGAIN|RIG_LEVEL_BKIN_DLYMS| \ RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define SDRCONSOLE_LEVEL_GET (|RIG_LEVEL_AGC|RIG_LEVEL_STRENGTH|RIG_LEVEL_METER|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_SLOPE_LOW) #define SDRCONSOLE_LEVEL_SET (RIG_LEVEL_NONE) #define TS2000_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_NR|RIG_FUNC_BC|RIG_FUNC_BC2|RIG_FUNC_RIT|RIG_FUNC_XIT| \ RIG_FUNC_TUNER|RIG_FUNC_MON|RIG_FUNC_FBKIN|RIG_FUNC_LOCK|RIG_FUNC_TONE|RIG_FUNC_TSQL|RIG_FUNC_ANF) #define TS2000_MAINVFO (RIG_VFO_A|RIG_VFO_B) #define TS2000_SUBVFO (RIG_VFO_C) #define TS2000_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_BAND_UP|RIG_OP_BAND_DOWN|RIG_OP_CPY|RIG_OP_TUNE) #define TS2000_SCAN_OP (RIG_SCAN_VFO) #define TS2000_ANTS (RIG_ANT_1|RIG_ANT_2) #define TS2000_STR_CAL {9, {\ {0x00, -54},\ {0x03, -48},\ {0x06, -36},\ {0x09, -24},\ {0x0C, -12},\ {0x0F, 0},\ {0x14, 20},\ {0x19, 40},\ {0x1E, 60}}\ } #define TS2000_SWR_CAL { 5, \ { \ { 0, 1.0f }, \ { 4, 1.5f }, \ { 8, 2.0f }, \ { 12, 3.0f }, \ { 20, 10.0f } \ } } #define TOK_FUNC_NOISE_REDUCTION_2 TOKEN_BACKEND(102) #define TOK_LEVEL_DSP_RX_EQUALIZER TOKEN_BACKEND(104) #define TOK_LEVEL_DSP_TX_EQUALIZER TOKEN_BACKEND(105) #define TOK_LEVEL_DSP_TX_BANDWIDTH TOKEN_BACKEND(106) #define TOK_LEVEL_BEEP_VOLUME TOKEN_BACKEND(107) #define TOK_LEVEL_TX_SIDETONE_VOLUME TOKEN_BACKEND(108) /* * 38 CTCSS sub-audible tones + 1750 tone */ tone_t ts2000_ctcss_list[] = { 670, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1035, 1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567, 1622, 1679, 1738, 1799, 1862, 1928, 2035, 2107, 2181, 2257, 2336, 2418, 2503, 17500, 0, }; /* * 103 available DCS codes */ tone_t ts2000_dcs_list[] = { 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, 0, }; int ts2000_ext_tokens[] = { TOK_FUNC_NOISE_REDUCTION_2, TOK_FUNC_FILTER_WIDTH_DATA, TOK_LEVEL_DSP_RX_EQUALIZER, TOK_LEVEL_DSP_TX_EQUALIZER, TOK_LEVEL_DSP_TX_BANDWIDTH, TOK_LEVEL_BEEP_VOLUME, TOK_LEVEL_TX_SIDETONE_VOLUME, TOK_BACKEND_NONE, }; const struct confparams ts2000_ext_funcs[] = { { TOK_FUNC_NOISE_REDUCTION_2, "NR2", "Noise reduction 2", "Noise reduction 2", NULL, RIG_CONF_CHECKBUTTON, }, { RIG_CONF_END, NULL, } }; const struct confparams ts2000_ext_levels[] = { { TOK_LEVEL_DSP_RX_EQUALIZER, "DSP_RX_EQUALIZER", "DSP RX equalizer", "DSP RX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "H BOOST", "F PASS", "B BOOST", "CONV-EN", "USER", NULL } } } }, { TOK_LEVEL_DSP_TX_EQUALIZER, "DSP_TX_EQUALIZER", "DSP TX equalizer", "DSP TX equalizer type", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "OFF", "H BOOST", "F PASS", "B BOOST", "CONV-EN", "USER", NULL } } } }, { TOK_LEVEL_DSP_TX_BANDWIDTH, "DSP_TX_BANDWIDTH", "DSP TX bandwidth", "DSP TX bandwidth for SSB and AM", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "2.0 kHz", "2.2 kHz", "2.4 kHz", "2.6 kHz", "2.8 kHz", "3.0 kHz", NULL } } } }, { TOK_LEVEL_BEEP_VOLUME, "BEEP_VOLUME", "Beep volume", "Beep volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { TOK_LEVEL_TX_SIDETONE_VOLUME, "TX_SIDETONE_VOLUME", "TX sidetone volume", "TX sidetone volume", NULL, RIG_CONF_NUMERIC, { .n = { .min = 0, .max = 9, .step = 1 } } }, { RIG_CONF_END, NULL, } }; static struct kenwood_filter_width ts2000_filter_width[] = { { RIG_MODE_CW | RIG_MODE_CWR, 50, 50 }, { RIG_MODE_CW | RIG_MODE_CWR, 80, 80 }, { RIG_MODE_CW | RIG_MODE_CWR, 100, 100 }, { RIG_MODE_CW | RIG_MODE_CWR, 150, 150 }, { RIG_MODE_CW | RIG_MODE_CWR, 200, 200 }, { RIG_MODE_CW | RIG_MODE_CWR, 300, 300 }, { RIG_MODE_CW | RIG_MODE_CWR, 400, 400 }, { RIG_MODE_CW | RIG_MODE_CWR, 500, 500 }, { RIG_MODE_CW | RIG_MODE_CWR, 600, 600 }, { RIG_MODE_CW | RIG_MODE_CWR, 1000, 1000 }, { RIG_MODE_CW | RIG_MODE_CWR, 2000, 2000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 250, 250 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 500, 500 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1000, 1000 }, { RIG_MODE_RTTY | RIG_MODE_RTTYR, 1500, 1500 }, { RIG_MODE_SSB, 0, 2400 }, { RIG_MODE_SSB, 1, 500 }, // NAR1 optional filter { RIG_MODE_SSB, 2, 270 }, // NAR2 optional filter { RIG_MODE_FM, 0, 6000 }, { RIG_MODE_FM, 1, 12000 }, { RIG_MODE_AM, 0, 2400 }, { RIG_MODE_AM, 1, 6000 }, // NAR1 optional filter (?) { RIG_MODE_NONE, -1, -1 }, }; static struct kenwood_slope_filter ts2000_slope_filter_high[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 1400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 1600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 1800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 2000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 2200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 2400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 2600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 2800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 3000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 3400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 4000 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 11, 5000 }, { RIG_MODE_AM, 0, 0, 2500 }, { RIG_MODE_AM, 0, 1, 3000 }, { RIG_MODE_AM, 0, 2, 4000 }, { RIG_MODE_AM, 0, 3, 5000 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 170 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1930 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 2, 2160 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_slope_filter ts2000_slope_filter_low[] = { { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 0, 0 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 1, 50 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 2, 100 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 3, 200 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 4, 300 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 5, 400 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 6, 500 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 7, 600 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 8, 700 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 9, 800 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 0, 10, 900 }, { RIG_MODE_SSB | RIG_MODE_FM | RIG_MODE_RTTY | RIG_MODE_RTTYR, 10, 1, 1000 }, { RIG_MODE_AM, 0, 0, 0 }, { RIG_MODE_AM, 0, 1, 100 }, { RIG_MODE_AM, 0, 2, 200 }, { RIG_MODE_AM, 0, 3, 500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 0, 2500 }, { RIG_MODE_SSB | RIG_MODE_RTTY | RIG_MODE_RTTYR | RIG_MODE_FM | RIG_MODE_AM, 1, 1, 1000 }, { RIG_MODE_NONE, 0, -1, -1 }, }; static struct kenwood_priv_caps ts2000_priv_caps = { .cmdtrm = EOM_KEN, .filter_width = ts2000_filter_width, .slope_filter_high = ts2000_slope_filter_high, .slope_filter_low = ts2000_slope_filter_low, .tone_table_base = 1, }; /* memory capabilities */ #define TS2000_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .rptr_shift=1, \ .rptr_offs=1, \ .funcs=RIG_FUNC_REV|RIG_FUNC_TONE|RIG_FUNC_TSQL,\ .tuning_step=1, \ .ctcss_tone=1, \ .ctcss_sql=1, \ .dcs_code=1, \ .dcs_sql=1, \ .scan_group=1, \ .flags=1, \ .channel_desc=1 \ } /* * Function definitions below */ int ts2000_init(RIG *rig) { struct kenwood_priv_data *priv; int retval; ENTERFUNC; retval = kenwood_init(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } priv = (struct kenwood_priv_data *) STATE(rig)->priv; priv->ag_format = 3; priv->micgain_min = 0; priv->micgain_max = 100; RETURNFUNC(RIG_OK); } static int ts2000_set_ex_menu(RIG *rig, int number, int value_len, int value) { char buf[20]; ENTERFUNC; SNPRINTF(buf, sizeof(buf), "EX%03d0000%0*d", number, value_len, value); RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } static int ts2000_get_ex_menu(RIG *rig, int number, int value_len, int *value) { int retval; char buf[20]; char ackbuf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); SNPRINTF(buf, sizeof(buf), "EX%03d0000", number); retval = kenwood_safe_transaction(rig, buf, ackbuf, sizeof(ackbuf), 9 + value_len); if (retval != RIG_OK) { RETURNFUNC2(retval); } sscanf(ackbuf + 9, "%d", value); RETURNFUNC2(RIG_OK); } static int ts2000_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[20]; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (func) { case RIG_FUNC_MON: SNPRINTF(buf, sizeof(buf), "ML00%c", (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); case RIG_FUNC_LOCK: SNPRINTF(buf, sizeof(buf), "LK%c%c", (status == 0) ? '0' : '1', (status == 0) ? '0' : '1'); RETURNFUNC2(kenwood_transaction(rig, buf, NULL, 0)); default: return kenwood_set_func(rig, vfo, func, status); } } static int ts2000_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char buf[20]; int retval; ENTERFUNC; switch (func) { case RIG_FUNC_MON: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", buf, sizeof(buf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(buf, "ML%d", &raw_value); *status = (raw_value > 0); break; } case RIG_FUNC_LOCK: retval = kenwood_safe_transaction(rig, "LK", buf, sizeof(buf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } *status = buf[2] != '0' || buf[3] != '0'; break; default: RETURNFUNC(kenwood_get_func(rig, vfo, func, status)); } RETURNFUNC(RIG_OK); } /* * WARNING: The commands differ slightly from the general versions in kenwood.c * e.g.: "SQ"=>"SQ0" , "AG"=>"AG0" */ static int ts2000_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; char vfo_num = (vfo == RIG_VFO_C) ? '1' : '0'; rig_debug(RIG_DEBUG_TRACE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_RF: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", kenwood_val); break; case RIG_LEVEL_AF: return kenwood_set_level(rig, vfo, level, val); case RIG_LEVEL_SQL: kenwood_val = val.f * 255; SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%c%03d", vfo_num, kenwood_val); break; case RIG_LEVEL_AGC: /* Possible values for TS-2000 are 0(=off)-020(=slow) */ switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_SUPERFAST: kenwood_val = 1; break; case RIG_AGC_FAST: kenwood_val = 5; break; case RIG_AGC_MEDIUM: kenwood_val = 10; break; case RIG_AGC_SLOW: kenwood_val = 20; break; default: rig_debug(RIG_DEBUG_ERR, "%s: unsupported agc value", __func__); return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_MONITOR_GAIN: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", kenwood_val); break; case RIG_LEVEL_NB: kenwood_val = val.f * 10.0; SNPRINTF(levelbuf, sizeof(levelbuf), "NL%03d", kenwood_val); break; case RIG_LEVEL_NR: kenwood_val = val.f * 9.0; SNPRINTF(levelbuf, sizeof(levelbuf), "RL%02d", kenwood_val); break; case RIG_LEVEL_PREAMP: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "PA%c", (val.i == 12) ? '1' : '0'); break; case RIG_LEVEL_ATT: if (val.i != 12 && val.i != 0) { RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", (val.i == 12) ? 1 : 0); break; case RIG_LEVEL_METER: switch (val.i) { case RIG_METER_SWR: kenwood_val = 1; break; case RIG_METER_COMP: kenwood_val = 2; break; case RIG_METER_ALC: kenwood_val = 3; break; default: RETURNFUNC2(-RIG_EINVAL); } SNPRINTF(levelbuf, sizeof(levelbuf), "RM%d", kenwood_val); break; case RIG_LEVEL_CWPITCH: if (val.i > 1000 || val.i < 400) { RETURNFUNC2(-RIG_EINVAL); } RETURNFUNC2(ts2000_set_ex_menu(rig, 31, 2, (val.i - 400) / 50)); default: return kenwood_set_level(rig, vfo, level, val); } return kenwood_transaction(rig, levelbuf, NULL, 0); } // TS-2000 can only read one meter at a time and the user must select // the meter using RIG_LEVEL_METER. This function returns the meter value if // the selected meter matches the expected meter. static int ts2000_read_meter(RIG *rig, int expected_meter, int *value) { int retval; char cmdbuf[8]; struct hamlib_port *rp = RIGPORT(rig); char ackbuf[32]; int expected_len = 8; int read_meter; int read_value; ENTERFUNC; SNPRINTF(cmdbuf, sizeof(cmdbuf), "RM;"); retval = write_block(rp, (unsigned char *) cmdbuf, strlen(cmdbuf)); rig_debug(RIG_DEBUG_TRACE, "%s: write_block retval=%d\n", __func__, retval); if (retval != RIG_OK) { RETURNFUNC(retval); } // TS-2000 returns values for a single meter at the same time, for example: RM10000; retval = read_string(rp, (unsigned char *) ackbuf, expected_len + 1, NULL, 0, 0, 1); rig_debug(RIG_DEBUG_TRACE, "%s: read_string retval=%d\n", __func__, retval); if (retval < 0) { rig_debug(RIG_DEBUG_ERR, "%s: failed to read rig response\n", __func__); RETURNFUNC(retval); } if (retval != expected_len) { rig_debug(RIG_DEBUG_ERR, "%s: expected %d bytes, got %d in '%s'\n", __func__, expected_len, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } retval = sscanf(ackbuf, "RM%1d%d;", &read_meter, &read_value); if (retval != 2) { rig_debug(RIG_DEBUG_ERR, "%s: expected 2 values to parse for meters, got %d in '%s'\n", __func__, retval, ackbuf); RETURNFUNC(-RIG_EPROTO); } if (read_meter == expected_meter) { *value = read_value; } else { *value = 0; } RETURNFUNC(RIG_OK); } static int ts2000_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char cmdbuf[8]; char ackbuf[50]; size_t ack_len, ack_len_expected; int levelint; int retval; char vfo_num = (vfo == RIG_VFO_C) ? '1' : '0'; ENTERFUNC; switch (level) { case RIG_LEVEL_AF: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_RF: retval = kenwood_transaction(rig, "RG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (5 != ack_len) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } val->f = levelint / (float) 255; RETURNFUNC(RIG_OK); case RIG_LEVEL_SQL: SNPRINTF(cmdbuf, sizeof(cmdbuf), "SQ%c", vfo_num); retval = kenwood_transaction(rig, cmdbuf, ackbuf, sizeof(ackbuf)); ack_len_expected = 6; if (retval != RIG_OK) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint) != 1) { RETURNFUNC(-RIG_EPROTO); } val->f = (float) levelint / 255.f; RETURNFUNC(RIG_OK); case RIG_LEVEL_AGC: retval = kenwood_transaction(rig, "GT", ackbuf, sizeof(ackbuf)); ack_len_expected = 5; if (RIG_OK != retval) { RETURNFUNC(retval); } ack_len = strlen(ackbuf); if (ack_len != ack_len_expected) { RETURNFUNC(-RIG_EPROTO); } if (1 != sscanf(&ackbuf[ack_len_expected - 3], "%d", &levelint)) { RETURNFUNC(-RIG_EPROTO); } if (levelint == 0) { val->i = RIG_AGC_OFF; } else if (levelint <= 1) { val->i = RIG_AGC_SUPERFAST; } else if (levelint <= 5) { val->i = RIG_AGC_FAST; } else if (levelint <= 10) { val->i = RIG_AGC_MEDIUM; } else { val->i = RIG_AGC_SLOW; } RETURNFUNC(RIG_OK); case RIG_LEVEL_STRENGTH: if (CACHE(rig)->ptt != RIG_PTT_OFF) { val->i = -9 * 6; break; } RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); case RIG_LEVEL_MONITOR_GAIN: { int raw_value; retval = kenwood_safe_transaction(rig, "ML", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "ML%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_NB: { int raw_value; retval = kenwood_safe_transaction(rig, "NL", ackbuf, sizeof(ackbuf), 5); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NL%d", &raw_value); val->f = (float) raw_value / 10.0f; break; } case RIG_LEVEL_NR: { int raw_value; retval = kenwood_safe_transaction(rig, "RL", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RL%d", &raw_value); val->f = (float) raw_value / 9.0f; break; } case RIG_LEVEL_PREAMP: retval = kenwood_safe_transaction(rig, "PA", ackbuf, sizeof(ackbuf), 4); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[2] == '1' ? 12 : 0; break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", ackbuf, sizeof(ackbuf), 6); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = ackbuf[3] == '1' ? 12 : 0; break; case RIG_LEVEL_METER: { int raw_value; // TODO: Read all meters at the same time: RM10000;RM20000;RM30000; retval = kenwood_safe_transaction(rig, "RM", ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "RM%1d", &raw_value); switch (raw_value) { case 1: val->i = RIG_METER_SWR; break; case 2: val->i = RIG_METER_COMP; break; case 3: val->i = RIG_METER_ALC; break; default: val->i = RIG_METER_NONE; } break; } case RIG_LEVEL_SWR: case RIG_LEVEL_COMP_METER: case RIG_LEVEL_ALC: { int meter; int swr; int comp; int *value; int alc; switch (level) { case RIG_LEVEL_SWR: meter = 1; value = &swr; break; case RIG_LEVEL_COMP_METER: meter = 2; value = ∁ break; case RIG_LEVEL_ALC: meter = 3; value = &alc; break; default: RETURNFUNC(-RIG_EINVAL); } retval = ts2000_read_meter(rig, meter, value); if (retval != RIG_OK) { RETURNFUNC(retval); } switch (level) { case RIG_LEVEL_SWR: if (rig->caps->swr_cal.size) { val->f = rig_raw2val_float(swr, &rig->caps->swr_cal); } else { val->f = (float) swr / 2.0f; } break; case RIG_LEVEL_COMP_METER: val->f = (float) comp; // Maximum value is 20dB break; case RIG_LEVEL_ALC: // Maximum value is 20, so have the max at 5 just to be on the range where other rigs report ALC val->f = (float) alc / 4.0f; break; default: RETURNFUNC(-RIG_ENAVAIL); } break; } case RIG_LEVEL_RFPOWER_METER: { int raw_value; char read_vfo_num; if (CACHE(rig)->ptt == RIG_PTT_OFF) { val->f = 0; break; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "SM%c", vfo_num); retval = kenwood_safe_transaction(rig, cmdbuf, ackbuf, sizeof(ackbuf), 7); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "SM%c%d", &read_vfo_num, &raw_value); if (vfo_num == '1') { val->f = (float) raw_value / 15.0f; } else { val->f = (float) raw_value / 30.0f; } break; } case RIG_LEVEL_CWPITCH: { int raw_value; retval = ts2000_get_ex_menu(rig, 31, 2, &raw_value); if (retval != RIG_OK) { RETURNFUNC(retval); } val->i = 400 + raw_value * 50; break; } default: RETURNFUNC(kenwood_get_level(rig, vfo, level, val)); } RETURNFUNC(RIG_OK); } static int ts2000_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[20]; int retval; int rit_enabled; int xit_enabled; ENTERFUNC; if (rit < -19999 || rit > 19999) { RETURNFUNC(-RIG_EINVAL); } // RC clear command cannot be executed if RIT/XIT is not enabled retval = kenwood_get_func(rig, vfo, RIG_FUNC_RIT, &rit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled) { retval = kenwood_get_func(rig, vfo, RIG_FUNC_XIT, &xit_enabled); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 1); if (retval != RIG_OK) { RETURNFUNC(retval); } } retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } if (!rit_enabled && !xit_enabled) { retval = kenwood_set_func(rig, vfo, RIG_FUNC_RIT, 0); if (retval != RIG_OK) { RETURNFUNC(retval); } } if (rit == 0) { RETURNFUNC(RIG_OK); } SNPRINTF(buf, sizeof(buf), "R%c%05d", (rit > 0) ? 'U' : 'D', abs((int) rit)); retval = kenwood_transaction(rig, buf, NULL, 0); RETURNFUNC(retval); } static int ts2000_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int retval; char buf[7]; struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; if (!rit) { RETURNFUNC(-RIG_EINVAL); } retval = kenwood_get_if(rig); if (retval != RIG_OK) { RETURNFUNC(retval); } memcpy(buf, &priv->info[18], 5); buf[6] = '\0'; *rit = atoi(buf); RETURNFUNC(RIG_OK); } static int ts2000_set_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int status) { char cmdbuf[20]; int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: if (status < 0 || status > 1) { RETURNFUNC(-RIG_EINVAL); } SNPRINTF(cmdbuf, sizeof(cmdbuf), "NR%d", status ? 2 : 0); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts2000_get_ext_func(RIG *rig, vfo_t vfo, hamlib_token_t token, int *status) { int retval; ENTERFUNC; switch (token) { case TOK_FUNC_NOISE_REDUCTION_2: { int value; char ackbuf[20]; retval = kenwood_safe_transaction(rig, "NR", ackbuf, sizeof(ackbuf), 3); if (retval != RIG_OK) { RETURNFUNC(retval); } sscanf(ackbuf, "NR%d", &value); *status = (value == 2) ? 1 : 0; break; } default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts2000_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { int retval; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 20, 1, val.i); break; case TOK_LEVEL_DSP_TX_EQUALIZER: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 21, 1, val.i); break; case TOK_LEVEL_DSP_TX_BANDWIDTH: if (val.i < 0 || val.i > 5) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 22, 1, val.i); break; case TOK_LEVEL_BEEP_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 12, 1, (int) val.f); break; case TOK_LEVEL_TX_SIDETONE_VOLUME: if (val.f < 0 || val.f > 9) { RETURNFUNC(-RIG_EINVAL); } retval = ts2000_set_ex_menu(rig, 13, 1, (int) val.f); break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } static int ts2000_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { int retval; int value; ENTERFUNC; switch (token) { case TOK_LEVEL_DSP_RX_EQUALIZER: retval = ts2000_get_ex_menu(rig, 20, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_EQUALIZER: retval = ts2000_get_ex_menu(rig, 21, 1, &value); val->i = value; break; case TOK_LEVEL_DSP_TX_BANDWIDTH: retval = ts2000_get_ex_menu(rig, 22, 1, &value); val->i = value; break; case TOK_LEVEL_BEEP_VOLUME: retval = ts2000_get_ex_menu(rig, 12, 1, &value); val->f = value; break; case TOK_LEVEL_TX_SIDETONE_VOLUME: retval = ts2000_get_ex_menu(rig, 13, 1, &value); val->f = value; break; default: RETURNFUNC(-RIG_EINVAL); } RETURNFUNC(retval); } /* * ts2000_get_channel * Read command format: M|R|P1|P2|P3|P3|;| * P1: 0 - RX frequency, 1 - TX frequency Memory channel 290 ~ 299: P1=0 (start frequency), P1=1 (end frequency) P2 - bank number allowed values: , 0, 1 or 2 P3 - channel number 00-99 Returned value: M | R |P1 |P2 |P3 |P3 |P4 |P4 |P4 |P4 | P4 |P4 |P4 |P4 |P4 |P4 |P4 |P5 |P6 |P7 | P8 |P8 |P9 |P9 |P10|P10|P10|P11|P12|P13| P13|P13|P13|P13|P13|P13|P13|P13|P14|P14| P15|P16|P16|P16|P16|P16|P16|P16|P16| ; | P1 - P3 described above P4: Frequency in Hz (11-digit). P5: Mode. 1: LSB, 2: USB, 3: CW, 4: FM, 5: AM, 6: FSK, 7: CR-R, 8: Reserved, 9: FSK-R P6: Lockout status. 0: Lockout OFF, 1: Lockout ON. P7: 0: OFF, 1: TONE, 2: CTCSS, 3: DCS. P8: Tone Number. Allowed values 01 (67Hz) - 38 (250.3Hz) P9: CTCSS tone number. Allowed values 01 (67Hz) - 38 (250.3Hz) P10: DCS code. Allowed values 000 (023 DCS code) to 103 (754 DCS code). P11: REVERSE status. P12: SHIFT status. 0: Simplex, 1: +, 2: –, 3: = (All E-types) P13: Offset frequency in Hz (9-digit). Allowed values 000000000 - 059950000 in steps of 50000. Unused digits must be 0. P14: Step size. Allowed values: for SSB, CW, FSK mode: 00 - 03 00: 1 kHz, 01: 2.5 kHz, 02: 5 kHz, 03: 10 kHz for AM, FM mode: 00 - 09 00: 5 kHz, 01: 6.25 kHz, 02: 10 kHz, 03: 12.5 kHz, 04: 15 kHz, 05: 20 kHz, 06: 25 kHz, 07: 30 kHz, 08: 50 kHz, 09: 100 kHz P15: Memory Group number (0 ~ 9). P16: Memory name. A maximum of 8 characters. */ int ts2000_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only) { int err; int tmp; size_t length; char buf[52]; char cmd[8]; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan || chan->vfo != RIG_VFO_MEM) { return -RIG_EINVAL; } /* put channel num in the command string */ SNPRINTF(cmd, sizeof(cmd), "MR0%03d;", chan->channel_num); err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } length = strlen(buf); memset(chan, 0x00, sizeof(channel_t)); chan->vfo = RIG_VFO_MEM; /* parse from right to left */ /* XXX based on the available documentation, there is no command * to read out the filters of a given memory channel. The rig, however, * stores this information. */ /* First check if a name is assigned. Name is returned at positions 41-48 (counting from 0) */ if (length > 41) { // rig_debug(RIG_DEBUG_VERBOSE, "Copying channel description: %s\n", &buf[ 41 ] ); strcpy(chan->channel_desc, &buf[ 41 ]); } /* Memory group no */ chan->scan_group = buf[ 40 ] - '0'; /* Fields 38-39 contain tuning step as a number 00 - 09. Tuning step depends on this number and the mode, just save it for now */ buf[ 40 ] = '\0'; tmp = atoi(&buf[ 38]); /* Offset frequency */ buf[ 38 ] = '\0'; chan->rptr_offs = atoi(&buf[ 29 ]); /* Shift type WARNING: '=' shift type not programmed */ if (buf[ 28 ] == '1') { chan->rptr_shift = RIG_RPT_SHIFT_PLUS; } else { if (buf[ 28 ] == '2') { chan->rptr_shift = RIG_RPT_SHIFT_MINUS; } else { chan->rptr_shift = RIG_RPT_SHIFT_NONE; } } /* Reverse status */ if (buf[27] == '1') { chan->funcs |= RIG_FUNC_REV; } /* Check for tone, CTCSS and DCS */ /* DCS code first */ if (buf[ 19 ] == '3') { if (rig->caps->dcs_list) { buf[ 27 ] = '\0'; chan->dcs_code = rig->caps->dcs_list[ atoi(&buf[ 24 ]) ]; chan->dcs_sql = chan->dcs_code; chan->ctcss_tone = 0; chan->ctcss_sql = 0; } } else { chan->dcs_code = 0; chan->dcs_sql = 0; /* CTCSS code Caution, CTCSS codes, unlike DCS codes, are numbered from 1! */ buf[ 24 ] = '\0'; if (buf[ 19 ] == '2') { chan->funcs |= RIG_FUNC_TSQL; if (rig->caps->ctcss_list) { chan->ctcss_sql = rig->caps->ctcss_list[ atoi(&buf[22]) - 1 ]; chan->ctcss_tone = 0; } } else { chan->ctcss_sql = 0; /* CTCSS tone */ if (buf[ 19 ] == '1') { chan->funcs |= RIG_FUNC_TONE; buf[ 22 ] = '\0'; if (rig->caps->ctcss_list) { chan->ctcss_tone = rig->caps->ctcss_list[ atoi(&buf[20]) - 1 ]; } } else { chan->ctcss_tone = 0; } } } /* memory lockout */ if (buf[18] == '1') { chan->flags |= RIG_CHFLAG_SKIP; } /* mode */ chan->mode = kenwood2rmode(buf[17] - '0', caps->mode_table); /* Now we have the mode, let's finish the tuning step */ if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (tmp) { case 0: chan->tuning_step = kHz(5); break; case 1: chan->tuning_step = kHz(6.25); break; case 2: chan->tuning_step = kHz(10); break; case 3: chan->tuning_step = kHz(12.5); break; case 4: chan->tuning_step = kHz(15); break; case 5: chan->tuning_step = kHz(20); break; case 6: chan->tuning_step = kHz(25); break; case 7: chan->tuning_step = kHz(30); break; case 8: chan->tuning_step = kHz(50); break; case 9: chan->tuning_step = kHz(100); break; default: chan->tuning_step = 0; } } else { switch (tmp) { case 0: chan->tuning_step = kHz(1); break; case 1: chan->tuning_step = kHz(2.5); break; case 2: chan->tuning_step = kHz(5); break; case 3: chan->tuning_step = kHz(10); break; default: chan->tuning_step = 0; } } /* Frequency */ buf[17] = '\0'; chan->freq = atoi(&buf[6]); if (chan->freq == RIG_FREQ_NONE) { return -RIG_ENAVAIL; } buf[6] = '\0'; chan->channel_num = atoi(&buf[3]); /* Check split freq */ cmd[2] = '1'; err = kenwood_transaction(rig, cmd, buf, sizeof(buf)); if (err != RIG_OK) { return err; } chan->tx_mode = kenwood2rmode(buf[17] - '0', caps->mode_table); buf[17] = '\0'; chan->tx_freq = atoi(&buf[6]); if (chan->freq == chan->tx_freq) { chan->tx_freq = RIG_FREQ_NONE; chan->tx_mode = RIG_MODE_NONE; chan->split = RIG_SPLIT_OFF; } else { chan->split = RIG_SPLIT_ON; } if (!read_only) { // Set rig to channel values rig_debug(RIG_DEBUG_ERR, "%s: please contact hamlib mailing list to implement this\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: need to know if rig updates when channel read or not\n", __func__); return -RIG_ENIMPL; } return RIG_OK; } int ts2000_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char sqltype = '0'; char buf[128]; char mode, tx_mode = 0; char shift = '0'; short dcscode = 0; short code = 0; int tstep = 0; int err; int tone = 0; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!chan) { return -RIG_EINVAL; } mode = rmode2kenwood(chan->mode, caps->mode_table); if (mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->mode)); return -RIG_EINVAL; } if (chan->split == RIG_SPLIT_ON) { tx_mode = rmode2kenwood(chan->tx_mode, caps->mode_table); if (tx_mode < 0) { rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(chan->tx_mode)); return -RIG_EINVAL; } } /* find tone */ if (chan->ctcss_tone) { for (; rig->caps->ctcss_list[tone] != 0; tone++) { if (chan->ctcss_tone == rig->caps->ctcss_list[tone]) { break; } } if (chan->ctcss_tone != rig->caps->ctcss_list[tone]) { tone = -1; } else { sqltype = '1'; } } else { tone = -1; /* -1 because we will add 1 when outputting; this is necessary as CTCSS codes are numbered from 1 */ } /* find CTCSS code */ if (chan->ctcss_sql) { for (; rig->caps->ctcss_list[code] != 0; code++) { if (chan->ctcss_sql == rig->caps->ctcss_list[code]) { break; } } if (chan->ctcss_sql != rig->caps->ctcss_list[code]) { code = -1; } else { sqltype = '2'; } } else { code = -1; } /* find DCS code */ if (chan->dcs_code) { for (; rig->caps->dcs_list[dcscode] != 0; dcscode++) { if (chan->dcs_code == rig->caps->dcs_list[dcscode]) { break; } } if (chan->dcs_code != rig->caps->dcs_list[dcscode]) { dcscode = 0; } else { sqltype = '3'; } } else { dcscode = 0; } if (chan->rptr_shift == RIG_RPT_SHIFT_PLUS) { shift = '1'; } if (chan->rptr_shift == RIG_RPT_SHIFT_MINUS) { shift = '2'; } if ((chan->mode == RIG_MODE_AM) || (chan->mode == RIG_MODE_FM)) { switch (chan->tuning_step) { case s_kHz(6.25): tstep = 1; break; case s_kHz(10): tstep = 2; break; case s_kHz(12.5): tstep = 3; break; case s_kHz(15): tstep = 4; break; case s_kHz(20): tstep = 5; break; case s_kHz(25): tstep = 6; break; case s_kHz(30): tstep = 7; break; case s_kHz(50): tstep = 8; break; case s_kHz(100): tstep = 9; break; default: tstep = 0; } } else { switch (chan->tuning_step) { case s_kHz(2.5): tstep = 1; break; case s_kHz(5): tstep = 2; break; case s_kHz(10): tstep = 3; break; default: tstep = 0; } } /* P-number 2-3 4 5 6 7 8 9 101112 13 141516 */ SNPRINTF(buf, sizeof(buf), "MW0%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;", chan->channel_num, (unsigned) chan->freq, /* 4 - frequency */ '0' + mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* 15 - Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "The command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (chan->split == RIG_SPLIT_ON) { SNPRINTF(buf, sizeof(buf), "MW1%03d%011u%c%c%c%02d%02d%03d%c%c%09d0%c%c%s;\n", chan->channel_num, (unsigned) chan->tx_freq, /* 4 - frequency */ '0' + tx_mode, /* 5 - mode */ (chan->flags & RIG_CHFLAG_SKIP) ? '1' : '0', /* 6 - lockout status */ sqltype, /* 7 - squelch and tone type */ tone + 1, /* 8 - tone code */ code + 1, /* 9 - CTCSS code */ dcscode + 1, /* 10 - DCS code */ (chan->funcs & RIG_FUNC_REV) ? '1' : '0', /* 11 - Reverse status */ shift, /* 12 - shift type */ (int) chan->rptr_offs, /* 13 - offset frequency */ tstep + '0', /* 14 - Step size */ chan->scan_group + '0', /* Memory group no */ chan->channel_desc /* 16 - description */ ); rig_debug(RIG_DEBUG_VERBOSE, "Split, the command will be: %s\n", buf); err = kenwood_transaction(rig, buf, NULL, 0); } return err; } /* * TS-2000 rig capabilities */ struct rig_caps ts2000_caps = { RIG_MODEL(RIG_MODEL_TS2000), .model_name = "TS-2000", .mfg_name = "Kenwood", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .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, /* ms */ .timeout = 200, .retry = 3, .has_get_func = TS2000_FUNC_ALL, .has_set_func = TS2000_FUNC_ALL, .has_get_level = TS2000_LEVEL_GET, .has_set_level = TS2000_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .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 = 1000}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .parm_gran = {}, .vfo_ops = TS2000_VFO_OPS, .scan_ops = TS2000_SCAN_OP, .ctcss_list = ts2000_ctcss_list, .dcs_list = ts2000_dcs_list, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 12, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST }, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TS2000_MEM_CAP }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1830), kHz(1850), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(142), MHz(152), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(420), MHz(450), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(118), MHz(174), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(220), MHz(512), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1800), MHz(2), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(148), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(148), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {TS2000_ALL_MODES, 10}, {TS2000_ALL_MODES, 100}, {TS2000_ALL_MODES, kHz(1)}, {TS2000_ALL_MODES, kHz(2.5)}, {TS2000_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {TS2000_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {TS2000_ALL_MODES, MHz(1)}, {TS2000_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(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = TS2000_STR_CAL, .swr_cal = TS2000_SWR_CAL, .ext_tokens = ts2000_ext_tokens, .extfuncs = ts2000_ext_funcs, .extlevels = ts2000_ext_levels, .priv = (void *)& ts2000_priv_caps, .rig_init = ts2000_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts2000_set_rit, .get_rit = ts2000_get_rit, .set_xit = ts2000_set_rit, .get_xit = ts2000_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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, .set_ctcss_tone = kenwood_set_ctcss_tone_tn, .get_ctcss_tone = kenwood_get_ctcss_tone, .set_ctcss_sql = kenwood_set_ctcss_sql, .get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = ts2000_set_func, .get_func = ts2000_get_func, .set_level = ts2000_set_level, .get_level = ts2000_get_level, .set_ext_func = ts2000_set_ext_func, .get_ext_func = ts2000_get_ext_func, .set_ext_level = ts2000_set_ext_level, .get_ext_level = ts2000_get_ext_level, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .send_voice_mem = kenwood_send_voice_mem, .stop_voice_mem = kenwood_stop_voice_mem, .vfo_op = kenwood_vfo_op, .scan = kenwood_scan, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = ts2000_get_channel, .set_channel = ts2000_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * SDRConsole TS-2000 rig capabilities * SDRConsole does not use hardware flow control for example */ struct rig_caps sdrconsole_caps = { RIG_MODEL(RIG_MODEL_SDRCONSOLE), .model_name = "SDRConsole", .mfg_name = "SDR Radio", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, /* ms */ .timeout = 200, .retry = 3, .has_get_func = TS2000_FUNC_ALL, .has_set_func = TS2000_FUNC_ALL, .has_get_level = TS2000_LEVEL_GET, .has_set_level = TS2000_LEVEL_SET, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { #define NO_LVL_VOXDELAY #define NO_LVL_KEYSPD #define NO_LVL_CWPITCH #define NO_LVL_BKIN_DLYMS #define NO_LVL_SLOPE_LOW #define NO_LVL_SLOPE_HIGH #include "level_gran_kenwood.h" #undef NO_LVL_VOXDELAY #undef NO_LVL_KEYSPD #undef NO_LVL_CWPITCH #undef NO_LVL_BKIN_DLYMS #undef NO_LVL_SLOPE_LOW #undef NO_LVL_SLOPE_HIGH [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 30 }, .step = { .i = 1 } }, [LVL_KEYSPD] = {.min = {.i = 10}, .max = {.i = 60}, .step = {.i = 1}}, [LVL_CWPITCH] = {.min = {.i = 400}, .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 = 1000}, .step = {.i = 10}}, [LVL_SLOPE_HIGH] = {.min = {.i = 0}, .max = {.i = 5000}, .step = {.i = 10}}, }, .parm_gran = {}, .vfo_ops = TS2000_VFO_OPS, .scan_ops = TS2000_SCAN_OP, .ctcss_list = ts2000_ctcss_list, .dcs_list = ts2000_dcs_list, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 12, RIG_DBLST_END, }, .max_rit = kHz(20), .max_xit = kHz(20), .max_ifshift = kHz(1), .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 5, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_MEDIUM, RIG_AGC_FAST, RIG_AGC_SUPERFAST }, .bank_qty = 0, .chan_desc_sz = 7, .chan_list = { { 0, 299, RIG_MTYPE_MEM, TS2000_MEM_CAP }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(430), MHz(440), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1830), kHz(1850), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1830), kHz(1850), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), kHz(3800), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7100), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(50.2), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(146), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(146), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(440), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(300), MHz(60), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO, TS2000_ANTS}, {MHz(142), MHz(152), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(420), MHz(450), TS2000_ALL_MODES, -1, -1, TS2000_MAINVFO}, {MHz(118), MHz(174), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, {MHz(220), MHz(512), TS2000_ALL_MODES, -1, -1, TS2000_SUBVFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(1800), MHz(2), TS2000_AM_TX_MODES, 2000, 25000, TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(3500), MHz(4), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(7), kHz(7300), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(10.1), MHz(10.15), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(14), kHz(14350), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(18068), kHz(18168), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(21), kHz(21450), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {kHz(24890), kHz(24990), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(28), kHz(29700), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO, TS2000_ANTS}, {MHz(50), MHz(54), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO, TS2000_ANTS}, {MHz(144), MHz(148), TS2000_OTHER_TX_MODES, W(5), W(100), TS2000_MAINVFO}, {MHz(144), MHz(148), TS2000_AM_TX_MODES, W(5), W(25), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_OTHER_TX_MODES, W(5), W(50), TS2000_MAINVFO}, {MHz(430), MHz(450), TS2000_AM_TX_MODES, W(5), W(12.5), TS2000_MAINVFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, 1}, {TS2000_ALL_MODES, 10}, {TS2000_ALL_MODES, 100}, {TS2000_ALL_MODES, kHz(1)}, {TS2000_ALL_MODES, kHz(2.5)}, {TS2000_ALL_MODES, kHz(5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(6.25)}, {TS2000_ALL_MODES, kHz(10)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(12.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(15)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(20)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(25)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(30)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(50)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(100)}, {TS2000_ALL_MODES, MHz(1)}, {TS2000_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(200)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(1000)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(80)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(100)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(150)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(400)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(600)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(2000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(250)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1000)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(1500)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(2.4)}, {RIG_MODE_FM, kHz(12)}, {RIG_MODE_FM, kHz(6)}, RIG_FLT_END, }, .str_cal = TS2000_STR_CAL, .swr_cal = TS2000_SWR_CAL, .ext_tokens = ts2000_ext_tokens, .extfuncs = ts2000_ext_funcs, .extlevels = ts2000_ext_levels, .priv = (void *)& ts2000_priv_caps, .rig_init = ts2000_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, //.set_rit = ts2000_set_rit, //.get_rit = ts2000_get_rit, //.set_xit = ts2000_set_rit, //.get_xit = ts2000_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_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, //.set_ctcss_tone = kenwood_set_ctcss_tone_tn, //.get_ctcss_tone = kenwood_get_ctcss_tone, //.set_ctcss_sql = kenwood_set_ctcss_sql, //.get_ctcss_sql = kenwood_get_ctcss_sql, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, //.get_dcd = kenwood_get_dcd, //.set_func = ts2000_set_func, //.get_func = ts2000_get_func, .set_level = ts2000_set_level, .get_level = ts2000_get_level, //.set_ext_func = ts2000_set_ext_func, //.get_ext_func = ts2000_get_ext_func, //.set_ext_level = ts2000_set_ext_level, //.get_ext_level = ts2000_get_ext_level, //.set_ant = kenwood_set_ant, //.get_ant = kenwood_get_ant, //.send_morse = kenwood_send_morse, //.wait_morse = rig_wait_morse, //.send_voice_mem = kenwood_send_voice_mem, //.stop_voice_mem = kenwood_stop_voice_mem, //.vfo_op = kenwood_vfo_op, //.scan = kenwood_scan, //.set_mem = kenwood_set_mem, //.get_mem = kenwood_get_mem, //.get_channel = ts2000_get_channel, //.set_channel = ts2000_set_channel, //.set_trn = kenwood_set_trn, //.get_trn = kenwood_get_trn, //.set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .get_info = kenwood_get_info, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/kenwood/ts140.c0000644000175000017500000001335414752216205013343 00000000000000/* * Hamlib Kenwood backend - TS140 description * Copyright (c) 2000-2009 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include "hamlib/rig.h" #include "bandplan.h" #include "kenwood.h" #define TS140_ALL_MODES (RIG_MODE_AM|RIG_MODE_FM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_CWR) #define TS140_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_CWR) #define TS140_AM_TX_MODES RIG_MODE_AM #define TS140_VFO (RIG_VFO_A|RIG_VFO_B|RIG_VFO_MEM) #define TS140_ANTS (0) /* * vfo defines */ #define VFO_A '0' #define VFO_B '1' #define VFO_MEM '2' static struct kenwood_priv_caps ts140_priv_caps = { .cmdtrm = EOM_KEN, }; static int ts140_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[16]; char vfo_function; switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = VFO_A; break; case RIG_VFO_B: vfo_function = VFO_B; break; case RIG_VFO_MEM: vfo_function = VFO_MEM; break; case RIG_VFO_CURR: return RIG_OK; default: rig_debug(RIG_DEBUG_ERR, "ts140_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "FN%c", vfo_function); /* The 680 and 140 need this to set the VFO on the radio */ return kenwood_transaction(rig, cmdbuf, NULL, 0); } /* * ts140 rig capabilities. * GW0VNR 09042006 */ struct rig_caps ts140_caps = { RIG_MODEL(RIG_MODEL_TS140S), .model_name = "TS-140S", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 9600, /* Rig only capable of 4800 baud from factory and 9k6 with jumper change */ .serial_data_bits = 8, .serial_stop_bits = 2, /* TWO stop bits. This is correct. */ .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 500, .retry = 10, .has_get_func = RIG_FUNC_LOCK, .has_set_func = RIG_FUNC_LOCK, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* No PARAMS controllable */ .level_gran = {}, /* FIXME: granularity */ .parm_gran = {}, .preamp = { RIG_DBLST_END, }, /* Not controllable */ .attenuator = { RIG_DBLST_END, }, /* Not controllable */ .max_rit = kHz(1.2), .max_xit = kHz(1.2), .max_ifshift = Hz(0), /* Not controllable */ .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 19, RIG_MTYPE_MEM }, { 20, 30, RIG_MTYPE_EDGE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(50), kHz(34999), TS140_ALL_MODES, -1, -1, TS140_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, TS140_OTHER_TX_MODES, W(5), W(100), TS140_VFO, TS140_ANTS), FRQ_RNG_HF(1, TS140_AM_TX_MODES, W(2), W(40), TS140_VFO, TS140_ANTS), RIG_FRNG_END, }, .rx_range_list2 = { {kHz(50), kHz(34999), TS140_ALL_MODES, -1, -1, TS140_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, TS140_OTHER_TX_MODES, W(5), W(100), TS140_VFO, TS140_ANTS), FRQ_RNG_HF(2, TS140_AM_TX_MODES, W(2), W(40), TS140_VFO, TS140_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { /* FIXME: Done */ {TS140_ALL_MODES, 10}, {TS140_ALL_MODES, 100}, {TS140_ALL_MODES, kHz(1)}, {TS140_ALL_MODES, kHz(5)}, {TS140_ALL_MODES, kHz(9)}, {TS140_ALL_MODES, kHz(10)}, {TS140_ALL_MODES, 12500}, {TS140_ALL_MODES, kHz(20)}, {TS140_ALL_MODES, kHz(25)}, {TS140_ALL_MODES, kHz(100)}, {TS140_ALL_MODES, MHz(1)}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_AM, kHz(6)}, {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_AM, kHz(2.2)}, {RIG_MODE_CWR, 600}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts140_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_mode = kenwood_set_mode, .get_mode = kenwood_get_mode_if, .set_vfo = ts140_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_ptt = kenwood_set_ptt, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem_if, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/ts440.c0000644000175000017500000001427514752216205013351 00000000000000/* * Hamlib Kenwood backend - TS440 description * Copyright (c) 2000-2004 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "kenwood.h" #include "ic10.h" #define TS440_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS440_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS440_AM_TX_MODES RIG_MODE_AM #define TS440_FUNC_ALL (RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT) #define TS440_LEVEL_ALL RIG_LEVEL_NONE #define TS440_VFO (RIG_VFO_A|RIG_VFO_B) #define TS440_VFO_OPS (RIG_OP_UP|RIG_OP_DOWN) #define TS440_SCAN_OPS (RIG_SCAN_VFO) static struct kenwood_priv_caps ts440_priv_caps = { .cmdtrm = EOM_KEN, .if_len = 37, .tone_table_base = 1, }; /* * ts440 rig capabilities. * * part of infos comes from .http = //www.n7uic.net/radio/kenwood/ts440/specs.htm * .http = //public.srce.hr/9A1CDD/mods/kenwood/knwdif.mod * .http = //www.ifrance.fr/clucas/modposte/ts440/mod440.htm * */ struct rig_caps ts440_caps = { RIG_MODEL(RIG_MODEL_TS440), .model_name = "TS-440S", .mfg_name = "Kenwood", .version = IC10_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_NONE, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 20, .timeout = 500, .retry = 10, .has_get_func = RIG_FUNC_NONE, .has_set_func = TS440_FUNC_ALL, .has_get_level = TS440_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS440_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = {}, .parm_gran = {}, .ctcss_list = NULL, .dcs_list = NULL, .preamp = { RIG_DBLST_END, }, .attenuator = { RIG_DBLST_END, }, .max_rit = Hz(1270), .max_xit = Hz(1270), .max_ifshift = Hz(0), .targetable_vfo = RIG_TARGETABLE_FREQ, .vfo_ops = TS440_VFO_OPS, .scan_ops = TS440_SCAN_OPS, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM, {IC10_CHANNEL_CAPS} }, RIG_CHAN_END, }, .rx_range_list1 = { RIG_FRNG_END, }, /* FIXME: enter region 1 setting */ .tx_range_list1 = { RIG_FRNG_END, }, .rx_range_list2 = { {kHz(100), MHz(30), TS440_ALL_MODES, -1, -1, TS440_VFO}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(1800), MHz(2) - 1, TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(3500), MHz(4) - 1, TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(3500), MHz(4) - 1, TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(7), kHz(7300), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(7), kHz(7300), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(10100), kHz(10150), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(10100), kHz(10150), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(14), kHz(14350), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(14), kHz(14350), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(18068), kHz(18168), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(18068), kHz(18168), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(21), kHz(21450), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(21), kHz(21450), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {kHz(24890), kHz(24990), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {kHz(24890), kHz(24990), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, {MHz(28), kHz(29700), TS440_OTHER_TX_MODES, 5000, W(200), TS440_VFO}, {MHz(28), kHz(29700), TS440_AM_TX_MODES, 2000, W(110), TS440_VFO}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS440_ALL_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.2)}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_FM, kHz(12)}, RIG_FLT_END, }, .priv = (void *)& ts440_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_close = kenwood_close, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .set_mode = ic10_set_mode, .get_mode = ic10_get_mode, .set_vfo = ic10_set_vfo, .get_vfo = ic10_get_vfo, .set_split_freq = ic10_set_split_freq, .get_split_freq = ic10_get_split_freq, .set_split_vfo = ic10_set_split_vfo, .get_split_vfo = ic10_get_split_vfo, .set_ptt = ic10_set_ptt, .get_ptt = ic10_get_ptt, .set_func = kenwood_set_func, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = ic10_get_mem, .set_trn = kenwood_set_trn, .scan = kenwood_scan, .set_channel = ic10_set_channel, .get_channel = ic10_get_channel, .decode_event = ic10_decode_event, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ hamlib-4.6.2/rigs/kenwood/k2.c0000644000175000017500000005155414752216205013010 00000000000000/* * Hamlib Kenwood backend - Elecraft K2 description * Copyright (c) 2002-2009 by Stephane Fillod * Copyright (c) 2010 by Nate Bargmann, n0nb@arrl.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include "kenwood.h" #include "elecraft.h" #define K2_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|RIG_MODE_PKTLSB|RIG_MODE_PKTUSB) #define K2_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_LOCK) #define K2_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ RIG_LEVEL_STRENGTH|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD) #define K2_VFO (RIG_VFO_A|RIG_VFO_B) #define K2_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TUNE) #define K2_ANTS (RIG_ANT_1|RIG_ANT_2) static rmode_t k2_mode_table[KENWOOD_MODE_TABLE_MAX] = { [0] = RIG_MODE_NONE, [1] = RIG_MODE_LSB, [2] = RIG_MODE_USB, [3] = RIG_MODE_CW, [4] = RIG_MODE_NONE, [5] = RIG_MODE_NONE, [6] = RIG_MODE_PKTLSB, /* AFSK */ [7] = RIG_MODE_CWR, [8] = RIG_MODE_NONE, /* TUNE mode */ [9] = RIG_MODE_PKTUSB /* AFSK */ }; /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps k2_priv_caps = { .cmdtrm = EOM_KEN, .mode_table = k2_mode_table, }; /* K2 Filter list, four per mode */ struct k2_filt_s { shortfreq_t width; /* Filter width in Hz */ char fslot; /* Crystal filter slot number--1-4 */ char afslot; /* AF filter slot number--0-2 */ }; /* Number of filter slot arrays to allocate (TNX Diane, VA3DB) */ #define K2_FILT_NUM 4 /* K2 Filter List * * This struct will be populated as modes are queried or in response * to a request to set a given mode. This way a cache can be maintained * of the installed filters and an appropriate filter can be selected * for a requested bandwidth. Each mode has up to four filter slots available. */ struct k2_filt_lst_s { struct k2_filt_s filt_list[K2_FILT_NUM]; }; struct k2_filt_lst_s k2_fwmd_ssb; struct k2_filt_lst_s k2_fwmd_cw; struct k2_filt_lst_s k2_fwmd_rtty; /* K2 specific rig_caps API function declarations */ int k2_open(RIG *rig); int k2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int k2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int k2_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int k2_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); /* Private function declarations */ int k2_probe_mdfw(RIG *rig, struct kenwood_priv_data *priv); int k2_mdfw_rest(RIG *rig, const char *mode, const char *fw); int k2_pop_fw_lst(RIG *rig, const char *cmd); /* * KIO2 rig capabilities. * This kit can recognize a large subset of TS-570 commands. * * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K2 * look for KIO2 Programmer's Reference PDF */ struct rig_caps k2_caps = { RIG_MODEL(RIG_MODEL_K2), .model_name = "K2", .mfg_name = "Elecraft", .version = BACKEND_VER ".2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 4800, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 100, /* Timing between command strings */ // Note that 2000 timeout exceeds usleep but hl_usleep handles it .timeout = 2000, /* FA and FB make take up to 500 ms on band change */ .retry = 10, .has_get_func = K2_FUNC_ALL, .has_set_func = K2_FUNC_ALL, .has_get_level = K2_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K2_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_elecraft.h" }, /* FIXME: granularity */ .parm_gran = {}, .extlevels = elecraft_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 14, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K2_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 8, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K2_MODES, -1, -1, K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, /* 15W class */ {kHz(3500), kHz(3800) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(7), kHz(7100), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(10100), kHz(10150), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(14), kHz(14350), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(18068), kHz(18168), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(21), kHz(21450), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(24890), kHz(24990), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(28), kHz(29700), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K2_MODES, -1, -1, K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, /* 15W class */ {kHz(3500), MHz(4) - 1, K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(7), kHz(7300), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(10100), kHz(10150), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(14), kHz(14350), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(18068), kHz(18168), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(21), kHz(21450), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {kHz(24890), kHz(24990), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, {MHz(28), kHz(29700), K2_MODES, 10, W(15), K2_VFO, K2_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K2_MODES, 10}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.5)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_PKTLSB | RIG_MODE_PKTUSB, kHz(2.5)}, RIG_FLT_END, }, .priv = (void *)& k2_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = k2_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k2_set_mode, .get_mode = k2_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, .set_rit = kenwood_set_rit, .get_rit = kenwood_get_rit, .set_xit = kenwood_set_xit, .get_xit = kenwood_get_xit, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = kenwood_set_func, .get_func = kenwood_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = kenwood_set_level, .get_level = kenwood_get_level, .get_ext_level = k2_get_ext_level, .vfo_op = k2_vfo_op, .set_trn = kenwood_set_trn, .get_powerstat = kenwood_get_powerstat, .get_trn = kenwood_get_trn, .set_ant = kenwood_set_ant, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * K2 extension function definitions follow */ /* k2_open() * */ int k2_open(RIG *rig) { int err; struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = elecraft_open(rig); if (err != RIG_OK) { return err; } err = k2_probe_mdfw(rig, priv); if (err != RIG_OK) { return err; } return RIG_OK; } /* k2_set_mode() * * Based on the passed in bandwidth, looks up the nearest bandwidth filter * wider than the passed value and sets the radio accordingly. */ int k2_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int err; char f = '*'; struct k2_filt_lst_s *flt; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* Select the filter array per mode. */ switch (mode) { case RIG_MODE_LSB: case RIG_MODE_USB: flt = &k2_fwmd_ssb; break; case RIG_MODE_CW: case RIG_MODE_CWR: flt = &k2_fwmd_cw; break; case RIG_MODE_PKTLSB: case RIG_MODE_PKTUSB: if (priv->k2_md_rtty == 0) { return -RIG_EINVAL; /* RTTY module not installed */ } else { flt = &k2_fwmd_rtty; } break; default: return -RIG_EINVAL; } if (width != RIG_PASSBAND_NOCHANGE) { shortfreq_t freq = 0; if (width < 0) { width = labs(width); } /* Step through the filter list looking for the best match * for the passed in width. The choice is to select the filter * that is wide enough for the width without being too narrow * if possible. */ if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } if ((width > flt->filt_list[0].width) || (width > flt->filt_list[1].width)) { width = flt->filt_list[0].width; f = '1'; } // cppcheck-suppress knownConditionTrueFalse else if ((flt->filt_list[1].width >= width) && (width > flt->filt_list[2].width)) { width = flt->filt_list[1].width; f = '2'; } else if ((flt->filt_list[2].width >= width) && (width > flt->filt_list[3].width)) { width = flt->filt_list[2].width; f = '3'; } else if ((flt->filt_list[3].width >= width) && (width >= freq)) { width = flt->filt_list[3].width; f = '4'; } else { return -RIG_EINVAL; } } /* kenwood_set_mode() ignores width value for K2/K3/TS-570 */ err = kenwood_set_mode(rig, vfo, mode, width); if (err != RIG_OK) { return err; } if (width != RIG_PASSBAND_NOCHANGE) { char fcmd[16]; err = kenwood_transaction(rig, "K22", NULL, 0); if (err != RIG_OK) { return err; } /* Construct the filter command and set the radio mode and width*/ SNPRINTF(fcmd, sizeof(fcmd), "FW0000%c", f); /* Set the filter slot */ err = kenwood_transaction(rig, fcmd, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K20", NULL, 0); if (err != RIG_OK) { return err; } } return RIG_OK; } /* k2_get_mode() * * Uses the FW command in K22 mode to query the filter bandwidth reported * by the radio and returns it to the caller. */ int k2_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int err; char buf[KENWOOD_MAX_BUF_LEN]; char tmp[16]; char *bufptr; pbwidth_t temp_w; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !width) { return -RIG_EINVAL; } err = kenwood_get_mode(rig, vfo, mode, &temp_w); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K22", NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K20", NULL, 0); if (err != RIG_OK) { return err; } /* Convert received filter string value's first four digits to width */ bufptr = buf; strncpy(tmp, bufptr + 2, 4); tmp[4] = '\0'; *width = atoi(tmp); rig_debug(RIG_DEBUG_VERBOSE, "%s: Mode: %s, Width: %d\n", __func__, rig_strrmode(*mode), (int)*width); return RIG_OK; } /* TQ command is a quick transmit status query--K2/K3 only. * * token Defined in elecraft.h or this file * val Type depends on token type from confparams structure: * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ int k2_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { char buf[KENWOOD_MAX_BUF_LEN]; int err; const struct confparams *cfp; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } cfp = rig_ext_lookup_tok(rig, token); switch (token) { case TOK_TX_STAT: err = kenwood_safe_transaction(rig, "TQ", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { return err; } if (cfp->type == RIG_CONF_CHECKBUTTON) { val->i = atoi(&buf[2]); } else { rig_debug(RIG_DEBUG_ERR, "%s: protocol error, invalid token type\n", __func__); return -RIG_EPROTO; } break; default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported get_ext_level %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } return RIG_OK; } /* K2 private helper functions follow */ /* Probes for mode and filter settings, based on information * by Chris Bryant, G3WIE. */ int k2_probe_mdfw(RIG *rig, struct kenwood_priv_data *priv) { int err, i, c; char buf[KENWOOD_MAX_BUF_LEN]; char mode[16]; char fw[16]; char cmd[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!priv) { return -RIG_EINVAL; } /* The K2 extension level has been stored by elecraft_open(). Now set rig * to K22 for detailed query of mode and filter width values... */ err = kenwood_transaction(rig, "K22", NULL, 0); if (err != RIG_OK) { return err; } /* Check for mode and store it for later. */ err = kenwood_safe_transaction(rig, "MD", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { return err; } strcpy(mode, buf); /* Check for filter width and store it for later. */ err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8); if (err != RIG_OK) { return err; } strcpy(fw, buf); rig_debug(RIG_DEBUG_VERBOSE, "%s: Mode value: %s, Filter Width value: %s\n", __func__, mode, fw); /* Now begin the process of querying the available modes and filters. */ /* First try to put the K2 into RTTY mode and check if it's available. */ priv->k2_md_rtty = 0; /* Assume RTTY module not installed */ err = kenwood_transaction(rig, "MD6", NULL, 0); if (err != RIG_OK && err != -RIG_ERJCTED) { return err; } if (RIG_OK == err) { /* Read back mode and test to see if K2 reports RTTY. */ err = kenwood_safe_transaction(rig, "MD", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { return err; } if (!strcmp("MD6", buf)) { priv->k2_md_rtty = 1; /* set flag for RTTY mode enabled */ } } rig_debug(RIG_DEBUG_VERBOSE, "%s: RTTY flag is: %d\n", __func__, priv->k2_md_rtty); i = (priv->k2_md_rtty == 1) ? 2 : 1; /* Now loop through the modes checking for installed filters. */ for (c = 0; i > -1; i--, c++) { if (c == 0) { strcpy(cmd, "MD1"); /* SSB */ } else if (c == 1) { strcpy(cmd, "MD3"); /* CW */ } else if (c == 2) { strcpy(cmd, "MD6"); /* RTTY */ } else /* Oops! */ { err = k2_mdfw_rest(rig, mode, fw); if (err != RIG_OK) { return err; } return -RIG_EINVAL; } /* Now populate the Filter arrays */ err = k2_pop_fw_lst(rig, cmd); if (err != RIG_OK) { return err; } } /* Restore mode, filter, extension level */ if (strlen(fw) == 8) { fw[7] = '\0'; /* Truncate AFSlot to set filter slot */ } err = k2_mdfw_rest(rig, mode, fw); if (err != RIG_OK) { return err; } return RIG_OK; } /* Restore mode, filter, and ext_lvl to original values */ int k2_mdfw_rest(RIG *rig, const char *mode, const char *fw) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!mode || !fw) { return -RIG_EINVAL; } if (strlen(mode) != 3 || strlen(fw) != 7) { return -RIG_EINVAL; } err = kenwood_transaction(rig, mode, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, fw, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_transaction(rig, "K20", NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* Populate k2_filt_lst_s structure for each mode */ int k2_pop_fw_lst(RIG *rig, const char *cmd) { int err, f; char fcmd[16]; char buf[KENWOOD_MAX_BUF_LEN]; char tmp[16]; struct k2_filt_lst_s *flt; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!cmd) { return -RIG_EINVAL; } /* Store filter data in the correct structure depending on mode */ if (strcmp(cmd, "MD1") == 0) { flt = &k2_fwmd_ssb; } else if (strcmp(cmd, "MD3") == 0) { flt = &k2_fwmd_cw; } else if (strcmp(cmd, "MD6") == 0) { flt = &k2_fwmd_rtty; } else { return -RIG_EINVAL; } /* Set the mode */ err = kenwood_transaction(rig, cmd, NULL, 0); if (err != RIG_OK) { return err; } for (f = 1; f < 5; f++) { char *bufptr = buf; SNPRINTF(fcmd, sizeof(fcmd), "FW0000%d", f); err = kenwood_transaction(rig, fcmd, NULL, 0); if (err != RIG_OK) { return err; } err = kenwood_safe_transaction(rig, "FW", buf, KENWOOD_MAX_BUF_LEN, 8); if (err != RIG_OK) { return err; } /* buf should contain a string "FWxxxxfa;" which corresponds to: * xxxx = filter width in Hz * f = crystal filter slot number--1-4 * a = audio filter slot number--0-2 */ strncpy(tmp, bufptr + 2, 4); tmp[4] = '\0'; flt->filt_list[f - 1].width = atoi(tmp); strncpy(tmp, bufptr + 6, 1); tmp[1] = '\0'; flt->filt_list[f - 1].fslot = atoi(tmp); strncpy(tmp, bufptr + 7, 1); tmp[1] = '\0'; flt->filt_list[f - 1].afslot = atoi(tmp); rig_debug(RIG_DEBUG_VERBOSE, "%s: Width: %04li, FSlot: %i, AFSlot %i\n", __func__, flt->filt_list[f - 1].width, flt->filt_list[f - 1].fslot, flt->filt_list[f - 1].afslot); } return RIG_OK; } int k2_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char buf[32]; switch (op) { case RIG_OP_TUNE: // K2 SNPRINTF(buf, sizeof(buf), "SWH20"); break; default: return kenwood_vfo_op(rig, vfo, op); } return kenwood_transaction(rig, buf, NULL, 0); } hamlib-4.6.2/rigs/kenwood/th.h0000644000175000017500000000727314752216205013113 00000000000000/* * Hamlib Kenwood backend - TH handheld header * Copyright (c) 2001-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef __TH_H__ #define __TH_H__ 1 #include #include "rig.h" #define TH_VER "20231001" extern int th_transaction (RIG *rig, const char *cmdstr, char *data, size_t datasize); extern int th_get_vfo_char(RIG *rig, vfo_t *vfo, char *vfoch); extern int th_decode_event (RIG *rig); extern int th_set_freq (RIG *rig, vfo_t vfo, freq_t freq); extern int th_get_freq (RIG *rig, vfo_t vfo, freq_t *freq); extern int th_set_mode (RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); extern int th_get_mode (RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); extern int th_set_vfo(RIG *rig, vfo_t vfo); extern int th_get_vfo(RIG *rig, vfo_t *vfo); extern int tm_set_vfo_bc2 (RIG *rig, vfo_t vfo); extern int th_set_split_vfo (RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo); extern int th_get_split_vfo (RIG *rig, vfo_t vfo, split_t *split, vfo_t *txvfo); extern int th_set_trn(RIG *rig, int trn); extern int th_get_trn (RIG *rig, int *trn); extern int th_set_powerstat (RIG *rig, powerstat_t status); extern int th_get_powerstat (RIG *rig, powerstat_t *status); extern int th_set_func (RIG *rig, vfo_t vfo, setting_t func, int status); extern int th_get_func (RIG *rig, vfo_t vfo, setting_t func, int *status); extern int th_set_parm (RIG *rig, setting_t parm, value_t val); extern int th_get_parm (RIG *rig, setting_t parm, value_t *val); extern int th_get_level (RIG *rig, vfo_t vfo, setting_t level, value_t *val); extern int th_set_level (RIG *rig, vfo_t vfo, setting_t level, value_t val); extern int th_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); extern int th_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone); extern int th_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone); extern int th_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone); extern int th_set_dcs_sql(RIG *rig, vfo_t vfo, tone_t code); extern int th_get_dcs_sql(RIG *rig, vfo_t vfo, tone_t *code); extern const char *th_get_info(RIG *rig); extern int th_set_mem(RIG *rig, vfo_t vfo, int ch); extern int th_get_mem(RIG *rig, vfo_t vfo, int *ch); extern int th_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); extern int th_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); extern int th_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); extern int th_get_channel(RIG *rig, vfo_t vfo, channel_t *chan, int read_only); extern int th_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan); extern int th_set_ant (RIG * rig, vfo_t vfo, ant_t ant, value_t option); extern int th_get_ant (RIG * rig, vfo_t vfo, ant_t dummy, value_t *option, ant_t * ant_curr, ant_t *ant_tx, ant_t *ant_rx); extern int th_reset(RIG *rig, reset_t reset); extern int th_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch); #define TH_CHANNEL_CAPS \ .freq=1,\ .tx_freq=1,\ .split=1,\ .mode=1,\ .width=1,\ .tuning_step=1,\ .rptr_shift=1,\ .rptr_offs=1,\ .funcs=RIG_FUNC_REV,\ .ctcss_tone=1,\ .ctcss_sql=1,\ .channel_desc=1 #endif /* __TH_H__ */ /* end of file */ hamlib-4.6.2/rigs/kenwood/k3.c0000644000175000017500000025134214752216205013006 00000000000000/* * Hamlib Kenwood backend - Elecraft K3 description * Copyright (c) 2002-2009 by Stephane Fillod * Copyright (C) 2010,2011,2012,2013 by Nate Bargmann, n0nb@arrl.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * See the file 'COPYING.LIB' in the main Hamlib distribution directory for * the complete text of the GNU Lesser Public License version 2.1. * */ #include #include #include #include #include #include "idx_builtin.h" #include "kenwood.h" #include "misc.h" #include "bandplan.h" #include "elecraft.h" #include "cal.h" #define K3_MODES (RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_SSB|\ RIG_MODE_RTTY|RIG_MODE_RTTYR|RIG_MODE_FM|RIG_MODE_AM|RIG_MODE_PKTUSB|\ RIG_MODE_PKTLSB) #define K3_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_VOX|RIG_FUNC_APF|\ RIG_FUNC_DUAL_WATCH|RIG_FUNC_DIVERSITY|\ RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT|RIG_FUNC_SEND_MORSE) #define K4_FUNC_ALL (K3_FUNC_ALL|RIG_FUNC_MUTE) #define K3_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ RIG_LEVEL_STRENGTH|RIG_LEVEL_ALC|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|\ RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_COMP|\ RIG_LEVEL_NR|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER_METER|RIG_LEVEL_RFPOWER_METER_WATTS) #define K3_VFO (RIG_VFO_A|RIG_VFO_B) #define K3_VFO_OP (RIG_OP_UP|RIG_OP_DOWN|RIG_OP_TUNE) #define K3_ANTS (RIG_ANT_1|RIG_ANT_2) #define K4_ANTS (RIG_ANT_1|RIG_ANT_2|RIG_ANT_3|RIG_ANT_4) #define KX3_FUNC_ALL (RIG_FUNC_NB|RIG_FUNC_VOX|RIG_FUNC_APF|\ RIG_FUNC_DUAL_WATCH|RIG_FUNC_LOCK|RIG_FUNC_RIT|RIG_FUNC_XIT) #define KX3_LEVEL_ALL (RIG_LEVEL_ATT|RIG_LEVEL_PREAMP|RIG_LEVEL_AGC|RIG_LEVEL_SQL|\ RIG_LEVEL_STRENGTH|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|\ RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_MICGAIN|RIG_LEVEL_COMP|\ RIG_LEVEL_NR|RIG_LEVEL_MONITOR_GAIN|RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER_METER|\ RIG_LEVEL_RFPOWER_METER_WATTS|RIG_LEVEL_SWR) /* * Elecraft K3/K3S extra level definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams k3_ext_levels[] = { { TOK_IF_FREQ, "ifctr", "IF freq", "IF center frequency", NULL, RIG_CONF_NUMERIC, { .n = { 0, 9990, 10 } } }, { TOK_TX_STAT, "txst", "TX status", "TX status", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", NULL, RIG_CONF_BUTTON, { { } }, }, { TOK_ESSB, "essb", "ESSB", "Extended SSB frequency response", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RX_ANT, "rx_ant", "RX ANT", "RX antenna", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_LINK_VFOS, "link_vfos", "Link VFOs", "Link VFOs", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_TX_METER, "tx_meter", "TX meter", "Transmit meter mode", NULL, RIG_CONF_COMBO, { .c = { .combostr = { "SWR", "ALC", NULL } } } }, { TOK_IF_NB, "if_nb", "IF NB", "IF noise blanker level", NULL, RIG_CONF_NUMERIC, { .n = { 0, 21, 1 } }, }, { RIG_CONF_END, NULL, } }; /* * Elecraft KX3/KX2 extra level definitions * * Token definitions for .cfgparams in rig_caps * See enum rig_conf_e and struct confparams in rig.h */ const struct confparams kx3_ext_levels[] = { { TOK_TX_STAT, "txst", "TX status", "TX status", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { TOK_RIT_CLR, "ritclr", "RIT clear", "RIT clear", NULL, RIG_CONF_BUTTON, { { } }, }, { TOK_ESSB, "essb", "ESSB", "Extended SSB frequency response", NULL, RIG_CONF_CHECKBUTTON, { { } }, }, { RIG_CONF_END, NULL, } }; /* kenwood_transaction() will add this to command strings * sent to the rig and remove it from strings returned from * the rig, so no need to append ';' manually to command strings. */ static struct kenwood_priv_caps k3_priv_caps = { .cmdtrm = EOM_KEN, }; /* K3 specific function declarations */ int k3_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int k3_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int k3_get_vfo(RIG *rig, vfo_t *vfo); int k3_set_vfo(RIG *rig, vfo_t vfo); int k3_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val); int k3_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val); int k3_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit); int k3_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit); int k3_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width); int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width); int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int kx3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int kx3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int k3_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int k3_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int k3_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op); int k3_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode); /* Private helper functions */ int set_rit_xit(RIG *rig, shortfreq_t rit); int k3_set_nb_level(RIG *rig, float dsp_nb, float if_nb); int k3_get_nb_level(RIG *rig, float *dsp_nb, float *if_nb); int k3_get_bar_graph_level(RIG *rig, float *smeter, float *pwr, float *alc, int *mode_tx); int k4_get_bar_graph_level(RIG *rig, float *swr, float *pwr, float *alc, int *mode_tx); int kx3_get_bar_graph_level(RIG *rig, float *level); int k3_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k3_stop_voice_mem(RIG *rig, vfo_t vfo); int k3_stop_morse(RIG *rig, vfo_t vfo); /* K4 functions */ int k4_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int k4_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int k4_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k4_stop_voice_mem(RIG *rig, vfo_t vfo); int k4_stop_morse(RIG *rig, vfo_t vfo); /* * K3 rig capabilities. * This kit can recognize a large subset of TS-570/K2 commands and has many * extensions of its own. Extension backend functions to standard Kenwood * command are defined in elecraft.c (shared with K2) and in this file. * * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K3 * look for K3 Programmer's Reference PDF */ int kx3_get_bar_graph_level(RIG *rig, float *level); int k3_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k3_stop_voice_mem(RIG *rig, vfo_t vfo); int k3_stop_morse(RIG *rig, vfo_t vfo); /* K4 functions */ int k4_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int k4_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); int k4_send_voice_mem(RIG *rig, vfo_t vfo, int ch); int k4_stop_voice_mem(RIG *rig, vfo_t vfo); int k4_stop_morse(RIG *rig, vfo_t vfo); /* * K3 rig capabilities. * This kit can recognize a large subset of TS-570/K2 commands and has many * extensions of its own. Extension backend functions to standard Kenwood * command are defined in elecraft.c (shared with K2) and in this file. * * Part of info comes from http://www.elecraft.com/K2_Manual_Download_Page.htm#K3 * look for K3 Programmer's Reference PDF * */ struct rig_caps k3_caps = { RIG_MODEL(RIG_MODEL_K3), .model_name = "K3", .mfg_name = "Elecraft", .version = BACKEND_VER ".31", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 10, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = K3_FUNC_ALL, .has_set_func = K3_FUNC_ALL, .has_get_level = K3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { // cppcheck-suppress * #include "level_gran_elecraft.h" }, .parm_gran = {}, .extlevels = k3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = k3_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = k3_set_level, .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .send_voice_mem = k3_send_voice_mem, .stop_voice_mem = k3_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps k3s_caps = { RIG_MODEL(RIG_MODEL_K3S), .model_name = "K3S", .mfg_name = "Elecraft", .version = BACKEND_VER ".25", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 10, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = K3_FUNC_ALL, .has_set_func = K3_FUNC_ALL, .has_get_level = K3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #include "level_gran_elecraft.h" #undef NO_LVL_ATT [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 15 }, .step = { .i = 5 } }, }, .parm_gran = {}, .extlevels = k3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 5, 10, 15, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = k3_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = k3_set_level, .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .send_voice_mem = k3_send_voice_mem, .stop_voice_mem = k3_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; // How similar is this to the K3S? struct rig_caps k4_caps = { RIG_MODEL(RIG_MODEL_K4), .model_name = "K4", .mfg_name = "Elecraft", .version = BACKEND_VER ".32", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 115200, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 0, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = K4_FUNC_ALL, .has_set_func = K4_FUNC_ALL, .has_get_level = K3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(K3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #define NO_LVL_ATT #define NO_LVL_CWPITCH #define NO_LVL_VOXDELAY #define NO_LVL_PREAMP #include "level_gran_elecraft.h" #undef NO_LVL_ATT #undef NO_LVL_CWPITCH #undef NO_LVL_VOXDELAY #undef NO_LVL_PREAMP [LVL_CWPITCH] = { .min = { .i = 250 }, .max = { .i = 950 }, .step = { .i = 10 } }, [LVL_ATT] = { .min = { .i = 0 }, .max = { .i = 15 }, .step = { .i = 5 } }, [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 255 }, .step = { .i = 10 } }, [LVL_PREAMP] = { .min = { .i = 0 }, .max = { .i = 30}, .step = { .i = 10 } }, }, .parm_gran = {}, .extlevels = k3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 10, 20, 30, RIG_DBLST_END, }, .attenuator = { 5, 10, 15, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .agc_level_count = 3, .agc_levels = { RIG_AGC_OFF, RIG_AGC_SLOW, RIG_AGC_FAST }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K4_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K4_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K4_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K4_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(100), K3_VFO, K4_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = elecraft_get_vfo_tq, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = k3_set_level, .get_level = k3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k4_stop_morse, .send_voice_mem = k4_send_voice_mem, .stop_voice_mem = k4_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps kx3_caps = { RIG_MODEL(RIG_MODEL_KX3), .model_name = "KX3", .mfg_name = "Elecraft", .version = BACKEND_VER ".22", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 0, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = KX3_FUNC_ALL, .has_set_func = KX3_FUNC_ALL, .has_get_level = KX3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(KX3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_elecraft.h" }, .parm_gran = {}, .extlevels = kx3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_VOICE }, { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(10), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = k4_get_ptt, .set_ptt = k4_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = kx3_set_level, .get_level = kx3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .send_voice_mem = k3_send_voice_mem, .stop_voice_mem = k3_stop_voice_mem, .power2mW = k3_power2mW, .morse_qsize = 24, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; struct rig_caps kx2_caps = { RIG_MODEL(RIG_MODEL_KX2), .model_name = "KX2", .mfg_name = "Elecraft", .version = BACKEND_VER ".21", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 4800, .serial_rate_max = 38400, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, /* Timing between bytes */ .post_write_delay = 0, /* Timing between command strings */ .timeout = 1000, /* FA and FB make take up to 500 ms on band change */ .retry = 5, .has_get_func = KX3_FUNC_ALL, .has_set_func = KX3_FUNC_ALL, .has_get_level = KX3_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(KX3_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_elecraft.h" }, .parm_gran = {}, .extlevels = kx3_ext_levels, .extparms = kenwood_cfg_params, .preamp = { 1, RIG_DBLST_END, }, .attenuator = { 10, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = K3_VFO_OP, .targetable_vfo = RIG_TARGETABLE_FREQ | RIG_TARGETABLE_MODE, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 1, 4, RIG_MTYPE_MORSE }, RIG_CHAN_END }, .rx_range_list1 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, - 1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { FRQ_RNG_HF(1, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), FRQ_RNG_6m(1, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, { MHz(48), MHz(54), K3_MODES, -1, -1, K3_VFO, K3_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { FRQ_RNG_HF(2, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), FRQ_RNG_6m(2, K3_MODES, mW(10), W(12), K3_VFO, K3_ANTS), RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {K3_MODES, 1}, RIG_TS_END, }, /* mode/filter list, remember: order matters! */ /* Values are arbitrary based on common K3 filter options. */ .filters = { {RIG_MODE_SSB, kHz(2.7)}, {RIG_MODE_SSB, kHz(2.8)}, {RIG_MODE_SSB, kHz(1.8)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, RIG_FLT_ANY}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(1)}, {RIG_MODE_CW | RIG_MODE_CWR, kHz(2.8)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(50)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(500)}, {RIG_MODE_CW | RIG_MODE_CWR, Hz(300)}, {RIG_MODE_CW | RIG_MODE_CWR, RIG_FLT_ANY}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, kHz(2.7)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(500)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, Hz(300)}, {RIG_MODE_RTTY | RIG_MODE_RTTYR, RIG_FLT_ANY}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.7)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, kHz(2.8)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(50)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(2400)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(500)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, Hz(300)}, {RIG_MODE_PKTUSB | RIG_MODE_PKTLSB, RIG_FLT_ANY}, {RIG_MODE_AM, kHz(6)}, {RIG_MODE_AM, kHz(13)}, {RIG_MODE_AM, kHz(2.7)}, {RIG_MODE_AM, RIG_FLT_ANY}, {RIG_MODE_FM, kHz(13)}, /* TBC */ RIG_FLT_END, }, .priv = (void *)& k3_priv_caps, .rig_init = kenwood_init, .rig_cleanup = kenwood_cleanup, .rig_open = elecraft_open, .rig_close = elecraft_close, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_mode = k3_set_mode, .get_mode = k3_get_mode, .set_vfo = k3_set_vfo, .get_vfo = k3_get_vfo, .set_split_mode = k3_set_split_mode, .get_split_mode = k3_get_split_mode, .set_split_vfo = kenwood_set_split_vfo, .get_split_vfo = kenwood_get_split_vfo_if, .set_rit = k3_set_rit, .get_rit = kenwood_get_rit, .set_xit = k3_set_xit, .get_xit = kenwood_get_xit, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = k3_set_func, .get_func = k3_get_func, .set_ext_parm = kenwood_set_ext_parm, .get_ext_parm = kenwood_get_ext_parm, .set_level = kx3_set_level, .get_level = kx3_get_level, .set_ext_level = k3_set_ext_level, .get_ext_level = k3_get_ext_level, .vfo_op = k3_vfo_op, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .stop_morse = k3_stop_morse, .power2mW = k3_power2mW, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * K3 extension function definitions follow */ /* k3_get_mode() * * The K3 supports a new command, DT, to query the data submode so * RIG_MODE_PKTUSB and RIG_MODE_PKTLSB can be supported. */ int k3_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[KENWOOD_MAX_BUF_LEN]; int err; rmode_t temp_m; pbwidth_t temp_w; char *cmd_data = "DT"; char *cmd_bw = "BW"; int cmd_bw_len = 6; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s\n", __func__, rig_strvfo(vfo)); if ((priv->is_k3 || priv->is_k3s || priv->is_k4 || priv->is_k4d || priv->is_k4hd) && vfo == RIG_VFO_B) { if (!(priv->is_k3 || priv->is_k3s)) { cmd_data = "DT$"; } cmd_bw = "BW$"; cmd_bw_len = 7; } if (!mode || !width) { return -RIG_EINVAL; } if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } err = kenwood_get_mode(rig, vfo, &temp_m, &temp_w); if (err != RIG_OK) { return err; } if (temp_m == RIG_MODE_RTTY) { err = kenwood_safe_transaction(rig, cmd_data, buf, KENWOOD_MAX_BUF_LEN, strlen(cmd_data) + 1); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *mode = RIG_MODE_PKTUSB; break; case K3_MODE_AFSK_A: *mode = RIG_MODE_PKTLSB; break; default: *mode = temp_m; break; } } else if (temp_m == RIG_MODE_RTTYR) { err = kenwood_safe_transaction(rig, cmd_data, buf, KENWOOD_MAX_BUF_LEN, strlen(cmd_data) + 1); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *mode = RIG_MODE_PKTUSB; break; case K3_MODE_AFSK_A: *mode = RIG_MODE_PKTLSB; break; case K3_MODE_FSK_D: default: *mode = temp_m; break; } } else { *mode = temp_m; } /* The K3 is not limited to specific filter widths so we can query * the actual bandwidth using the BW command */ err = kenwood_safe_transaction(rig, cmd_bw, buf, KENWOOD_MAX_BUF_LEN, cmd_bw_len); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 BW value\n", __func__); return err; } *width = atoi(&buf[cmd_bw_len - 4]) * 10; return RIG_OK; } /* k3_set_mode() * * As with k3_get_mode(), the K3 can also set the data sub-modes which * allows use of RIG_MODE_PKTUSB and RIG_MODE_PKTLSB. * * The K3 supports AFSK & FSK sub-modes and for the D versions it also * has an internal RTTY and PSK31 decoder. The decoder sub-modes are * reported as FSK (RTTY) and the AFSK sub-modes are reported as * PKT(USB & LSB). The Submode determines if MD6 starts off in USB * or LSB. To get the reverse of that, you send MD9 and the the submode. * On KX3 it's * * DT0 defaults MD6 to USB * DT1 defaults MD6 to LSB * DT2 defaults MD6 to LSB * DT3 defaults MD6 to USB * * So to inverse that DT0 for LSB, you'd send MD9 then DT0. * * For mode set the data sub-modes are set as follows: * * PKTUSB = sets the rig to DATA mode submode Data A (DT0) * PKTLSB = sets the rig to DATA REV mode submode Data A (DT0) * RTTY = sets the rig to AFSK A 45 bps rtty (DT1) * RTTYR = sets the rig to FSK D 45 bps rtty (DT2) * PSK = sets the rig to PSK D (DT3) * Not all data sub-mode combinations are possible but the above * mapping seems most likely to cover the user requirements. */ int k3_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int err, err2; char cmd_m[5]; char buf[KENWOOD_MAX_BUF_LEN]; char *dtcmd; struct kenwood_priv_caps *caps = kenwood_caps(rig); struct kenwood_priv_data *priv = STATE(rig)->priv; ENTERFUNC; rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo=%s mode=%s width=%d\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), (int)width); if (vfo == RIG_VFO_CURR) { vfo = STATE(rig)->current_vfo; } rmode_t tmodeA, tmodeB; pbwidth_t twidth; err = k3_get_mode(rig, RIG_VFO_A, &tmodeA, &twidth); err2 = k3_get_mode(rig, RIG_VFO_B, &tmodeB, &twidth); // we keep both vfos in the same mode -- any reason they should ever be different? If so, fix this // if we change mode on one VFO we'll also change the other if (err == RIG_OK && err2 == RIG_OK && tmodeA == mode && tmodeB == mode && width == RIG_PASSBAND_NOCHANGE) { rig_debug(RIG_DEBUG_TRACE, "%s(%d): mode/width no change, skipping\n", __FILE__, __LINE__); RETURNFUNC(RIG_OK); } else { rig_debug(RIG_DEBUG_TRACE, "%s(%d): changing oldmode=A=%s B=%s, to mode=%s, oldwidth=%ld, to width=%ld\n", __FILE__, __LINE__, rig_strrmode(tmodeA), rig_strrmode(tmodeB), rig_strrmode(mode), twidth, width); } dtcmd = "DT"; if ((priv->is_k4 || priv->is_k4d || priv->is_k4hd) && vfo == RIG_VFO_B) { dtcmd = "DT$"; } switch (mode) { case RIG_MODE_PKTLSB: mode = RIG_MODE_RTTYR; // in "DT0" Subband RIG_MODE_RTTYR = USB and RIG_MODE_RTTY = LSB SNPRINTF(cmd_m, sizeof(cmd_m), "%s0", dtcmd); /* DATA A mode - DATA (REV) on LSB optimized for HF Packet, VFO dial is suppressed carrier QRG */ break; case RIG_MODE_PKTUSB: mode = RIG_MODE_RTTY; // in "DT0" Subband RIG_MODE_RTTYR = USB and RIG_MODE_RTTY = LSB SNPRINTF(cmd_m, sizeof(cmd_m), "%s0", dtcmd); /* DATA A mode - DATA on USB general, VFO dial is suppressed carrier QRG */ break; case RIG_MODE_RTTY: mode = RIG_MODE_RTTY; // in "DT1" Subband RIG_MODE_RTTY = LSB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "%s2", dtcmd); /* FSK D mode - direct FSK on LSB optimized for RTTY, VFO dial is MARK */ break; case RIG_MODE_RTTYR: mode = RIG_MODE_RTTYR; // in "DT2" Subband RIG_MODE_RTTY = LSB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "%s1", dtcmd); /* FSK D mode - direct FSK keying, LSB is "normal", VFO dial is MARK */ break; case RIG_MODE_PSK: mode = RIG_MODE_PSK; // in "DT3" subband RIG_MODE_PSK = USB # kenwood.c mode but may need kenwwod.c mode table review. SNPRINTF(cmd_m, sizeof(cmd_m), "%s3", dtcmd); /* PSK D Mode - direct PSK keying, USB is "normal", VFO dial is MARK */ break; default: break; } int kmode; int c; kmode = rmode2kenwood(mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(mode)); RETURNFUNC(-RIG_EINVAL); } if (kmode <= 9) { c = '0' + kmode; } else { c = 'A' + kmode - 10; } rig_debug(RIG_DEBUG_VERBOSE, "%s: kmode=%d, cmode=%c\n", __func__, kmode, c); if (vfo == RIG_VFO_B) { SNPRINTF(buf, sizeof(buf), "MD$%c", c); } else { SNPRINTF(buf, sizeof(buf), "MD%c", c); } if (priv->split) { // then we keep both VFOS in the same mode SNPRINTF(buf, sizeof(buf), "MD%c;MD$%c", c, c); } err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { RETURNFUNC(err); } if (width != RIG_PASSBAND_NOCHANGE) { char cmd_s[64]; /* and set the requested bandwidth. On my K3, the bandwidth is rounded * down to the nearest 50 Hz, i.e. sending BW0239; will cause the bandwidth * to be set to 2.350 kHz. As the width must be divided by 10, 10 Hz values * between 0 and 4 round down to the nearest 100 Hz and values between 5 * and 9 round down to the nearest 50 Hz. * * width string value must be padded with leading '0' to equal four * characters. */ /* passband widths vary by mode so gather lower and upper limits */ //pbwidth_t pb_nar = rig_passband_narrow(rig, mode); //pbwidth_t pb_wid = rig_passband_wide(rig, mode); if (width < 0) { width = labs(width); } if (width == RIG_PASSBAND_NORMAL) { width = rig_passband_normal(rig, mode); } #if 0 else if (width < pb_nar) { width = pb_nar; } else if (width > pb_wid) { width = pb_wid; } #endif width += 9; // rounds to 10Hz if (width > 99999) { width = 99999; } if (vfo == RIG_VFO_B) { SNPRINTF(cmd_s, sizeof(cmd_s), "BW$%04ld", width / 10); } else { SNPRINTF(cmd_s, sizeof(cmd_s), "BW%04ld", width / 10); } err = kenwood_transaction(rig, cmd_s, NULL, 0); if (err != RIG_OK) { RETURNFUNC(err); } } /* Now set data sub-mode. K3 needs to be in a DATA mode before setting * the sub-mode. */ if (mode == RIG_MODE_PKTLSB || mode == RIG_MODE_PKTUSB || mode == RIG_MODE_RTTY || mode == RIG_MODE_RTTYR) { err = kenwood_transaction(rig, cmd_m, NULL, 0); if (err != RIG_OK) { RETURNFUNC(err); } } RETURNFUNC(RIG_OK); } /* Elecraft rigs don't really know about swappings vfos. * We just emulate them so rigctl can work correctly. */ int k3_set_vfo(RIG *rig, vfo_t vfo) { ENTERFUNC; // we emulate vfo selection for Elecraft STATE(rig)->current_vfo = vfo; RETURNFUNC(RIG_OK); } int k3_get_vfo(RIG *rig, vfo_t *vfo) { ENTERFUNC; *vfo = STATE(rig)->current_vfo; RETURNFUNC(RIG_OK); } /* Support the RC command for clearing RIT/XIT, * * token Defined in elecraft.h or this file * val Type depends on token type from confparams structure: * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 * * See Private Elecraft extra levels definitions in elecraft.c and * private token #define in elecraft.h */ int k3_set_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t val) { char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (token) { case TOK_RIT_CLR: return kenwood_transaction(rig, "RC", NULL, 0); case TOK_ESSB: SNPRINTF(buf, sizeof(buf), "ES%c", (val.i == 0) ? '0' : '1'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_RX_ANT: SNPRINTF(buf, sizeof(buf), "AR%c", (val.i == 0) ? '0' : '1'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_LINK_VFOS: SNPRINTF(buf, sizeof(buf), "LN%c", (val.i == 0) ? '0' : '1'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_TX_METER: SNPRINTF(buf, sizeof(buf), "TM%c", val.i + '0'); return kenwood_transaction(rig, buf, NULL, 0); case TOK_IF_NB: return k3_set_nb_level(rig, -1, val.f / 21.0f); default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported set_ext_level %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } } /* Support the FI command for reading the IF center frequency, * useful for panadapters and such that need to know the IF center. * TQ command is a quick transmit status query--K2/K3 only. * * token Defined in elecraft.h or this file * val Type depends on token type from confparams structure: * NUMERIC: val.f * COMBO: val.i, starting from 0 Index to a string table. * STRING: val.cs for set, val.s for get * CHECKBUTTON: val.i 0/1 */ int k3_get_ext_level(RIG *rig, vfo_t vfo, hamlib_token_t token, value_t *val) { char buf[KENWOOD_MAX_BUF_LEN]; int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (token) { case TOK_IF_FREQ: err = kenwood_safe_transaction(rig, "FI", buf, KENWOOD_MAX_BUF_LEN, 6); if (err != RIG_OK) { return err; } val->f = 8210000.0 + (float) atoi(&buf[2]); break; case TOK_TX_STAT: return get_kenwood_func(rig, "TQ", &val->i); case TOK_ESSB: return get_kenwood_func(rig, "ES", &val->i); case TOK_RX_ANT: return get_kenwood_func(rig, "AR", &val->i); case TOK_LINK_VFOS: return get_kenwood_func(rig, "LN", &val->i); case TOK_TX_METER: return get_kenwood_func(rig, "TM", &val->i); case TOK_IF_NB: { float if_nb; err = k3_get_nb_level(rig, NULL, &if_nb); if (err != RIG_OK) { return err; } val->f = (float)((int)(if_nb * 21.0f)); break; } default: rig_debug(RIG_DEBUG_WARN, "%s: Unsupported get_ext_level %s\n", __func__, rig_strlevel(token)); return -RIG_EINVAL; } return RIG_OK; } /* * k3_set_rit() -- Differs from from generic Kenwood function as K3 can set * RIT to an arbitrary offset. When rit == 0, the RIT offset is cleared. */ int k3_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = set_rit_xit(rig, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * k3_set_xit() -- Differs from from generic Kenwood function as K3 can set * XIT to an arbitrary offset. When rit == 0, the XIT offset is cleared. */ int k3_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); err = set_rit_xit(rig, rit); if (err != RIG_OK) { return err; } return RIG_OK; } /* * The K3 *always* uses VFOB for TX. */ int k3_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { struct kenwood_priv_caps *caps = kenwood_caps(rig); char buf[32]; char kmode; int err; char cmd_m[16]; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (tx_mode) { case RIG_MODE_PKTLSB: tx_mode = RIG_MODE_RTTYR; // "DT0" RIG_MODE_RTTY = LSB SNPRINTF(cmd_m, sizeof(cmd_m), "DT0;"); /* DATA A mode - DATA-R LSB, suppressed carrier */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$0;"); } break; case RIG_MODE_PKTUSB: tx_mode = RIG_MODE_RTTY; // "DT0" RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "DT0;"); /* DATA A mode - DATA on USB, suppressed carrier */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$0;"); } break; case RIG_MODE_RTTY: tx_mode = RIG_MODE_RTTY; // DT1" RIG_MODE_RTTY = LSB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "DT2;"); /* FSK D mode - direct FSK on LSB optimized for RTTY, VFO dial is MARK */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$2;"); } break; case RIG_MODE_RTTYR: tx_mode = RIG_MODE_RTTYR; // "DT2" RIG_MODE_RTTY = USB and RIG_MODE_RTTYR = USB SNPRINTF(cmd_m, sizeof(cmd_m), "DT1;"); /* FSK D mode - direct FSK on USB optimized for RTTY, VFO dial is MARK */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$1;"); } break; case RIG_MODE_PSK: tx_mode = RIG_MODE_PSK; SNPRINTF(cmd_m, sizeof(cmd_m), "DT3;FT1;"); /* PSK D Mode - direct PSK keying, USB is "normal", VFO dial is MARK */ if (priv->is_k4d || priv->is_k4hd) { strcat(cmd_m, "DT$3;"); } break; default: break; } // Enabling this clause for just the K4 for now #if 1 if (priv->is_k4d || priv->is_k4hd) { // split can get turned off when modes are changing // so if the rig did this independently of us we turn it back on // even if the rig changes the split status should be the last thing we did if (priv->split) { strcat(cmd_m, "FT1;"); } /* Set data sub-mode. K3 needs to be in a DATA mode before setting * the sub-mode or switching to VFOB so we do this before the MD$ command. */ if (tx_mode == RIG_MODE_PKTLSB || tx_mode == RIG_MODE_PKTUSB || tx_mode == RIG_MODE_RTTY || tx_mode == RIG_MODE_RTTYR) { err = kenwood_transaction(rig, cmd_m, NULL, 0); if (err != RIG_OK) { return err; } } } #endif kmode = rmode2kenwood(tx_mode, caps->mode_table); if (kmode < 0) { rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode '%s'\n", __func__, rig_strrmode(tx_mode)); return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD$%c", '0' + kmode); err = kenwood_transaction(rig, buf, NULL, 0); if (err != RIG_OK) { return err; } if (tx_width != RIG_PASSBAND_NOCHANGE) { char cmd_s[32]; /* and set the requested bandwidth. On my K3, the bandwidth is rounded * down to the nearest 50 Hz, i.e. sending BW0239; will cause the bandwidth * to be set to 2.350 kHz. As the width must be divided by 10, 10 Hz values * between 0 and 4 round down to the nearest 100 Hz and values between 5 * and 9 round down to the nearest 50 Hz. * * tx_width string value must be padded with leading '0' to equal four * characters. */ /* passband widths vary by mode so gather lower and upper limits */ //pbwidth_t pb_nar = rig_passband_narrow(rig, tx_mode); //pbwidth_t pb_wid = rig_passband_wide(rig, tx_mode); if (tx_width < 0) { tx_width = labs(tx_width); } if (tx_width == RIG_PASSBAND_NORMAL) { tx_width = rig_passband_normal(rig, tx_mode); } #if 0 else if (tx_width < pb_nar) { tx_width = pb_nar; } else if (tx_width > pb_wid) { tx_width = pb_wid; } #endif SNPRINTF(cmd_s, sizeof(cmd_s), "BW$%04ld", tx_width / 10); err = kenwood_transaction(rig, cmd_s, NULL, 0); if (err != RIG_OK) { return err; } } return RIG_OK; } /* The K3 *always* uses VFOB for TX. */ int k3_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { char buf[KENWOOD_MAX_BUF_LEN]; int err; rmode_t temp_m; struct kenwood_priv_caps *caps = kenwood_caps(rig); rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!tx_mode || !tx_width) { return -RIG_EINVAL; } err = kenwood_safe_transaction(rig, "MD$", buf, KENWOOD_MAX_BUF_LEN, 4); if (err != RIG_OK) { return err; } temp_m = kenwood2rmode(buf[3] - '0', caps->mode_table); if (temp_m == RIG_MODE_RTTY) { err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *tx_mode = RIG_MODE_PKTUSB; break; case K3_MODE_AFSK_A: *tx_mode = RIG_MODE_PKTLSB; break; default: *tx_mode = temp_m; break; } } else if (temp_m == RIG_MODE_RTTYR) { err = kenwood_safe_transaction(rig, "DT", buf, KENWOOD_MAX_BUF_LEN, 3); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 DT value\n", __func__); return err; } switch (atoi(&buf[2])) { case K3_MODE_DATA_A: case K3_MODE_PSK_D: *tx_mode = RIG_MODE_PKTLSB; break; case K3_MODE_AFSK_A: *tx_mode = RIG_MODE_PKTUSB; break; case K3_MODE_FSK_D: break; default: *tx_mode = temp_m; break; } } else { *tx_mode = temp_m; } /* The K3 is not limited to specific filter widths so we can query * the actual bandwidth using the BW$ command */ err = kenwood_safe_transaction(rig, "BW$", buf, KENWOOD_MAX_BUF_LEN, 7); if (err != RIG_OK) { rig_debug(RIG_DEBUG_VERBOSE, "%s: Cannot read K3 BW$ value\n", __func__); return err; } *tx_width = atoi(&buf[3]) * 10; return RIG_OK; } static int k3_get_maxpower(RIG *rig) { //int retval; int maxpower = 15; // K3 default power level //char levelbuf[KENWOOD_MAX_BUF_LEN]; const struct kenwood_priv_data *priv = STATE(rig)->priv; // default range is 0-15 if there is no KPA3 installed if (priv->has_kpa3 || priv->has_kpa100) { maxpower = 110; } else if (RIG_IS_KX2 || RIG_IS_KX3) { int bandnum = -1; char levelbuf[KENWOOD_MAX_BUF_LEN]; int retval = kenwood_safe_transaction(rig, "BN", levelbuf, KENWOOD_MAX_BUF_LEN, 4); if (retval != RIG_OK) { return retval; } sscanf(levelbuf, "BN%d", &bandnum); switch (bandnum) { case 1: case 2: case 3: case 4: case 5: maxpower = 15; break; case 0: // 160M case 6: // 17M case 7: // 15M case 8: // 12M case 9: // 10M maxpower = 12; break; case 10: // 6M maxpower = 10; break; default: // are transverters all limited to 3W?? maxpower = 3; break; } } rig_debug(RIG_DEBUG_TRACE, "%s: maxpower=%d\n", __func__, maxpower); return maxpower; } int k3_power2mW(RIG *rig, unsigned int *mwpower, float power, freq_t freq, rmode_t mode) { char buf[32]; snprintf(buf, sizeof(buf), "%.0f", power * k3_get_maxpower(rig) * 1000); *mwpower = atoi(buf); return RIG_OK; } int k3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; float pwr; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { kenwood_val = val.f * 255; } else { kenwood_val = val.i; } switch (level) { case RIG_LEVEL_AGC: switch (val.i) { case RIG_AGC_OFF: kenwood_val = 0; break; case RIG_AGC_SUPERFAST: case RIG_AGC_FAST: kenwood_val = 2; break; case RIG_AGC_MEDIUM: case RIG_AGC_SLOW: kenwood_val = 4; break; case RIG_AGC_USER: case RIG_AGC_AUTO: return -RIG_EINVAL; } SNPRINTF(levelbuf, sizeof(levelbuf), "GT%03d", kenwood_val); break; case RIG_LEVEL_ATT: if (val.i == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA00"); } else if (val.i == 10) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA01"); } else { int i; int foundit = 0; for (i = 0; i < HAMLIB_MAXDBLSTSIZ && STATE(rig)->attenuator[i]; i++) { if (val.i == STATE(rig)->attenuator[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "RA%02d", i + 1); foundit = 1; break; } } if (!foundit) { return -RIG_EINVAL; } } break; case RIG_LEVEL_MICGAIN: SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d", (int)(val.f * 60.0f)); break; case RIG_LEVEL_COMP: SNPRINTF(levelbuf, sizeof(levelbuf), "CP%03d", (int)(val.f * 40.0f)); break; case RIG_LEVEL_SQL: SNPRINTF(levelbuf, sizeof(levelbuf), "SQ%03d", (int)(val.f * 29.0f)); break; case RIG_LEVEL_AF: SNPRINTF(levelbuf, sizeof(levelbuf), "AG%03d", (int)(val.f * 250.0f)); break; case RIG_LEVEL_RF: SNPRINTF(levelbuf, sizeof(levelbuf), "RG%03d", (int)(val.f * 250.0f)); break; case RIG_LEVEL_NR: return k3_set_nb_level(rig, val.f, -1); case RIG_LEVEL_MONITOR_GAIN: SNPRINTF(levelbuf, sizeof(levelbuf), "ML%03d", (int)(val.f * 60.0f)); break; case RIG_LEVEL_RFPOWER: pwr = val.f * k3_get_maxpower(rig); SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03.f%c", pwr > 15.0 ? pwr : 10.0 * pwr, pwr > 15.0 ? '1' : '0'); break; default: return kenwood_set_level(rig, vfo, level, val); } return kenwood_transaction(rig, levelbuf, NULL, 0); } /* * Handle S-meter (SM, SMH) level locally and pass rest to kenwood_get_level() */ int k3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char levelbuf[16]; int retval; int lvl; size_t len; const struct kenwood_priv_data *priv = STATE(rig)->priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!val) { return -RIG_EINVAL; } switch (level) { float firmware_have; float firmware_need; case RIG_LEVEL_STRENGTH: /* As of FW rev 4.37 the K3 supports an 'SMH' command that * offers a higher resolution, 0-100 (mine went to 106), * rawstr value for more precise S-meter reporting. */ firmware_have = 0; if (priv->fw_rev != NULL) { sscanf(priv->fw_rev, "%f", &firmware_have); } sscanf("4.37", "%f", &firmware_need); if (firmware_have < firmware_need) { cal_table_t str_cal = K3_SM_CAL; retval = kenwood_safe_transaction(rig, "SM", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &val->i); /* rawstr */ val->i = (int) rig_raw2val(val->i, &str_cal); } else { cal_table_t str_cal = K3_SMH_CAL; retval = kenwood_safe_transaction(rig, "SMH", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 3, "%d", &val->i); /* rawstr */ val->i = (int) rig_raw2val(val->i, &str_cal); } break; case RIG_LEVEL_ALC: { int tx_mode; float alc; if (RIG_IS_K4) { retval = k4_get_bar_graph_level(rig, NULL, NULL, &alc, &tx_mode); tx_mode = 1; // Assume ALC is zero when in Tx so we don't care about ptt status } else { retval = k3_get_bar_graph_level(rig, NULL, NULL, &alc, &tx_mode); } if (retval != RIG_OK) { return retval; } if (!tx_mode) { val->f = 0.0f; return RIG_OK; } if (alc < 0) { return -RIG_EINVAL; } val->f = alc; break; } case RIG_LEVEL_RFPOWER_METER: case RIG_LEVEL_RFPOWER_METER_WATTS: { int tx_mode; float pwr; if (RIG_IS_K4) { retval = k4_get_bar_graph_level(rig, NULL, &pwr, NULL, &tx_mode); tx_mode = 1; // Does K4 return pwr=0 when in Rx? Hope so. } else { retval = k3_get_bar_graph_level(rig, NULL, &pwr, NULL, &tx_mode); } if (retval != RIG_OK) { return retval; } if (!tx_mode) { val->f = 0.0f; return RIG_OK; } if (pwr < 0) { return -RIG_EINVAL; } val->f = pwr; if (level == RIG_LEVEL_RFPOWER_METER_WATTS) { val->f *= 100; } break; } case RIG_LEVEL_AGC: retval = kenwood_safe_transaction(rig, "GT", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = RIG_AGC_OFF; } else if (lvl == 2) { val->i = RIG_AGC_FAST; } else if (lvl == 4) { val->i = RIG_AGC_SLOW; } else { return -RIG_EPROTO; } break; case RIG_LEVEL_ATT: retval = kenwood_safe_transaction(rig, "RA", levelbuf, sizeof(levelbuf), 4); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); if (lvl == 0) { val->i = 0; } else if (lvl == 1) { val->i = 10; } else { int i; for (i = 0; i < lvl && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->attenuator[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected att level %d\n", __func__, lvl); return -RIG_EPROTO; } } if (i != lvl) { return -RIG_EINTERNAL; } val->i = STATE(rig)->attenuator[i - 1]; } break; case RIG_LEVEL_MICGAIN: retval = kenwood_safe_transaction(rig, "MG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 60.0f; break; case RIG_LEVEL_COMP: retval = kenwood_safe_transaction(rig, "CP", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 40.0f; break; case RIG_LEVEL_SQL: retval = kenwood_safe_transaction(rig, "SQ", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 29.0f; break; case RIG_LEVEL_RF: retval = kenwood_safe_transaction(rig, "RG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 250.0f; break; case RIG_LEVEL_AF: retval = kenwood_safe_transaction(rig, "AG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 250.0f; break; case RIG_LEVEL_NR: return k3_get_nb_level(rig, &val->f, NULL); case RIG_LEVEL_MONITOR_GAIN: retval = kenwood_safe_transaction(rig, "ML", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &lvl); val->f = (float) lvl / 60.0f; break; case RIG_LEVEL_RFPOWER: retval = kenwood_transaction(rig, "PC", levelbuf, sizeof(levelbuf)); if (retval != RIG_OK) { return retval; } len = strlen(levelbuf); if (len == 5 || len == 6) { sscanf(levelbuf + 2, "%3d", &lvl); } else { return RIG_EPROTO; } // extended K22 format PCnnnx where 0=.1W units and 1=1W units if (len == 6 && levelbuf[5] == '0') { val->f = (float) lvl / 10.0 / k3_get_maxpower(rig); } else { val->f = (float) lvl / k3_get_maxpower(rig); } break; case RIG_LEVEL_SWR: if (RIG_IS_K4) { retval = k4_get_bar_graph_level(rig, &val->f, NULL, NULL, NULL); return RIG_OK; } else { retval = kenwood_safe_transaction(rig, "SW", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &val->i); } val->f = (float) val->i / 10.0f; break; default: return kenwood_get_level(rig, vfo, level, val); } return RIG_OK; } int kx3_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ival; char cmdbuf[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (val.f > 1.0 || val.f < 0) { return -RIG_EINVAL; } switch (level) { case RIG_LEVEL_RF: ival = val.f * (250.0 - 190.0) + 190.0; SNPRINTF(cmdbuf, sizeof(cmdbuf) - 1, "RG%03d", ival); return kenwood_transaction(rig, cmdbuf, NULL, 0); case RIG_LEVEL_AF: // manual says 0-255 as of Rev G5 but experiment says 0-60 SNPRINTF(cmdbuf, sizeof(cmdbuf), "AG%03d", (int)(val.f * 60.0f)); return kenwood_transaction(rig, cmdbuf, NULL, 0); case RIG_LEVEL_MICGAIN: // manual says 0-255 as of Rev G5 but experiment says 0-80 SNPRINTF(cmdbuf, sizeof(cmdbuf), "MG%03d", (int)(val.f * 80.0f)); return kenwood_transaction(rig, cmdbuf, NULL, 0); } return k3_set_level(rig, vfo, level, val); } int kx3_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval; float f; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (level) { case RIG_LEVEL_AF: retval = get_kenwood_level(rig, "AG", NULL, &val->i); if (retval != RIG_OK) { return retval; } // manual says 0-255 as of Rev G5 but experiment says 0-60 f = val->i / 60.0; val->f = f; return retval; case RIG_LEVEL_RF: retval = get_kenwood_level(rig, "RG", NULL, &val->i); if (retval != RIG_OK) { return retval; } f = (val->i - 190.0) / (250.0 - 190.0); val->f = f; return retval; case RIG_LEVEL_MICGAIN: retval = get_kenwood_level(rig, "MG", NULL, &val->i); if (retval != RIG_OK) { return retval; } f = val->i / 80.0; val->f = f; return retval; case RIG_LEVEL_RFPOWER_METER: { int tx_status = 0; float pwr; // Return zero RF power when not in TX mode retval = get_kenwood_func(rig, "TQ", &tx_status); if (retval != RIG_OK) { return retval; } if (!tx_status) { val->f = 0.0f; return RIG_OK; } retval = kx3_get_bar_graph_level(rig, &pwr); if (retval != RIG_OK) { return retval; } val->f = pwr; return retval; } case RIG_LEVEL_RFPOWER_METER_WATTS: { struct kenwood_priv_data *priv = STATE(rig)->priv; char levelbuf[KENWOOD_MAX_BUF_LEN]; int pwr; retval = kenwood_safe_transaction(rig, "PO", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%d", &pwr); val->f = priv->has_kpa100 ? pwr : pwr / 10.0; return retval; } } return k3_get_level(rig, vfo, level, val); } int k3_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char buf[10]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); switch (func) { case RIG_FUNC_APF: SNPRINTF(buf, sizeof(buf), "AP%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_DUAL_WATCH: SNPRINTF(buf, sizeof(buf), "SB%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_DIVERSITY: SNPRINTF(buf, sizeof(buf), "DV%c", (status == 0) ? '0' : '1'); break; case RIG_FUNC_SEND_MORSE: // Transmit a CW character - K3 does not return any response snprintf(buf, sizeof(buf), "KYW%c", status); break; case RIG_FUNC_MUTE: // K4 Only that we know of SNPRINTF(buf, sizeof(buf), "AG%c", (status == 0) ? '/' : '0'); break; case RIG_FUNC_TUNER: // K2 KX2 K3 K3S KX3 K4 SNPRINTF(buf, sizeof(buf), "SWT16"); break; default: return kenwood_set_func(rig, vfo, func, status); } return kenwood_transaction(rig, buf, NULL, 0); } int k3_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { char buf[32]; ENTERFUNC; switch (op) { case RIG_OP_TUNE: // KX2 K3 K3S KX3 K4 -- K2 needs SWH20 to it's in k2.c switch (rig->caps->rig_model) { case RIG_MODEL_KX2: SNPRINTF(buf, sizeof(buf), "SWT20"); break; case RIG_MODEL_K3S: case RIG_MODEL_K3: SNPRINTF(buf, sizeof(buf), "SWT19"); break; case RIG_MODEL_KX3: SNPRINTF(buf, sizeof(buf), "SWT44"); break; case RIG_MODEL_K4: SNPRINTF(buf, sizeof(buf), "SW40"); break; default: rig_debug(RIG_DEBUG_ERR, "%s: unknown rig=%d\n", __func__, rig->caps->rig_model); RETURNFUNC(-RIG_EINVAL); } break; default: RETURNFUNC(kenwood_vfo_op(rig, vfo, op)); } RETURNFUNC(kenwood_transaction(rig, buf, NULL, 0)); } /* * Some functions, notably RIT and XIT On/Off status, can be queried * on the K3. Those functions are handled here and others are passed * through to kenwood_get_func(). */ int k3_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!status) { return -RIG_EINVAL; } switch (func) { case RIG_FUNC_RIT: return get_kenwood_func(rig, "RT", status); case RIG_FUNC_XIT: return get_kenwood_func(rig, "XT", status); case RIG_FUNC_APF: return get_kenwood_func(rig, "AP", status); case RIG_FUNC_DUAL_WATCH: return get_kenwood_func(rig, "SB", status); case RIG_FUNC_DIVERSITY: return get_kenwood_func(rig, "DV", status); default: return kenwood_get_func(rig, vfo, func, status); } } /* Private K3 helper functions */ /* * set_rit_xit() -- Differs from from generic Kenwood function as K3 can set * RIT/XIT to an arbitrary offset. When rit == 0, the RIT/XIT offset is * cleared. */ int set_rit_xit(RIG *rig, shortfreq_t rit) { int err; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (rit == 0) { /* Clear offset and return */ err = kenwood_transaction(rig, "RC", NULL, 0); if (err != RIG_OK) { return err; } return RIG_OK; } /* Set offset */ if (rit <= 9999 && rit >= -9999) { char cmd[16]; char offs; offs = (rit < 0) ? '-' : '+'; SNPRINTF(cmd, 8, "RO%c%04d", offs, abs((int)rit)); err = kenwood_transaction(rig, cmd, NULL, 0); if (err != RIG_OK) { return err; } } else { return -RIG_EINVAL; } return RIG_OK; } int k3_set_nb_level(RIG *rig, float dsp_nb, float if_nb) { char levelbuf[16]; int dsp_nb_raw = 0; int if_nb_raw = 0; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (dsp_nb >= 0) { dsp_nb_raw = (int)(dsp_nb * 21.0f); } if (if_nb >= 0) { if_nb_raw = (int)(if_nb * 21.0f); } if (dsp_nb < 0 || if_nb < 0) { int current_dsp_nb_raw; int current_if_nb_raw; int retval = kenwood_safe_transaction(rig, "NL", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d%02d", ¤t_dsp_nb_raw, ¤t_if_nb_raw); if (dsp_nb < 0) { dsp_nb_raw = current_dsp_nb_raw; } if (if_nb < 0) { if_nb_raw = current_if_nb_raw; } } SNPRINTF(levelbuf, sizeof(levelbuf), "NL%02d%02d", dsp_nb_raw, if_nb_raw); return kenwood_transaction(rig, levelbuf, NULL, 0); } int k3_get_nb_level(RIG *rig, float *dsp_nb, float *if_nb) { char levelbuf[16]; int retval; int dsp_nb_raw; int if_nb_raw; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "NL", levelbuf, sizeof(levelbuf), 6); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d%02d", &dsp_nb_raw, &if_nb_raw); if (dsp_nb != NULL) { *dsp_nb = (float) dsp_nb_raw / 21.0f; } if (if_nb != NULL) { *if_nb = (float) if_nb_raw / 21.0f; } return RIG_OK; } int k4_get_bar_graph_level(RIG *rig, float *swr, float *pwr, float *alc, int *mode_tx) { int retval; int ialc, icmp, ifwd, iswr; char levelbuf[16]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "TM", levelbuf, sizeof(levelbuf), 14); if (retval != RIG_OK) { return retval; } sscanf(levelbuf, "TM%03d%03d%03d%03d", &ialc, &icmp, &ifwd, &iswr); if (swr) { *swr = iswr / 10.0; } if (pwr) { *pwr = ifwd / 100.0; } // pwr is returned in 0-1 sscale if (alc) { *alc = ialc; } return RIG_OK; } int k3_get_bar_graph_level(RIG *rig, float *smeter, float *pwr, float *alc, int *mode_tx) { char levelbuf[16]; int retval; int tm_raw; int bg_raw; char mode; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // Determine transmit metering mode: 0 = RF POWER, 1 = ALC retval = get_kenwood_func(rig, "TM", &tm_raw); if (retval != RIG_OK) { return retval; } retval = kenwood_safe_transaction(rig, "BG", levelbuf, sizeof(levelbuf), 5); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d%c", &bg_raw, &mode); if (mode == 'R') { // S-meter: nn is 00 - 21 (CWT off) or 00 - 09 (CWT on) if (smeter != NULL) { *smeter = (float) bg_raw / 21.0f; } if (pwr != NULL) { *pwr = -1; } if (alc != NULL) { *alc = -1; } } else if (mode == 'T') { if (tm_raw) { // ALC: nn is 00 - 07 if (alc != NULL) { *alc = (float) bg_raw / 7.0f; } if (pwr != NULL) { *pwr = -1; } if (smeter != NULL) { *smeter = -1; } } else { // PWR: nn is 00 - 12 if (pwr != NULL) { *pwr = (float) bg_raw / 12.0f; } if (alc != NULL) { *alc = -1; } if (smeter != NULL) { *smeter = -1; } } } else { return -RIG_EPROTO; } if (mode_tx != NULL) { *mode_tx = (mode == 'T'); } return RIG_OK; } int kx3_get_bar_graph_level(RIG *rig, float *level) { char levelbuf[16]; int retval; int bg_raw; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); retval = kenwood_safe_transaction(rig, "BG", levelbuf, sizeof(levelbuf), 4); if (retval != RIG_OK) { return retval; } sscanf(levelbuf + 2, "%02d", &bg_raw); if (bg_raw >= 0 && bg_raw <= 10) { if (level != NULL) { *level = (float) bg_raw / 10.0f; } } else if (bg_raw >= 12 && bg_raw <= 22) { if (level != NULL) { *level = (float)(bg_raw - 12) / 10.0f; } } else { return -RIG_EPROTO; } return RIG_OK; } int k4_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[6]; int retval; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (!ptt) { return -RIG_EINVAL; } retval = kenwood_safe_transaction(rig, "TQ", pttbuf, 6, 3); if (retval != RIG_OK) { return retval; } *ptt = pttbuf[2] == '1' ? RIG_PTT_ON : RIG_PTT_OFF; // we're not caching this for now return RIG_OK; } // The K4 has a problem in Fake It mode where the FA command is ignored // We will use its special TQ command to try and ensure PTT is really off int k4_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char pttbuf[6]; int i; int retval; ptt_t ptt2 = -1; char cmd[4]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); SNPRINTF(cmd, sizeof(cmd), "RX"); if (ptt) { cmd[0] = 'T'; } retval = kenwood_transaction(rig, cmd, NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < 5 && ptt2 != ptt; ++i) { retval = kenwood_safe_transaction(rig, "TQ", pttbuf, 6, 3); if (retval != RIG_OK) { return retval; } ptt2 = pttbuf[2] == '1' ? RIG_PTT_ON : RIG_PTT_OFF; if (ptt2 != ptt) { hl_usleep(100 * 1000); rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d, expected=%d\n", __func__, ptt2, ptt); } } // had one report of Fake It not returning to RX freq after TX -- so a little more time for the K4 if (ptt == RIG_PTT_OFF) { hl_usleep(100 * 1000); } return RIG_OK; } // K3S band memory needs some time to do its thing after freq change // K3 probably does too // But what about the K4? int k3_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int retval; freq_t tfreq; retval = kenwood_get_freq(rig, vfo, &tfreq); if (retval != RIG_OK) { return retval; } retval = kenwood_set_freq(rig, vfo, freq); // if more than 1MHz probably a band change so give it some time // before continuing if (fabs(tfreq - freq) > 1e6) { hl_usleep(200 * 1000); // give 200ms for rig to do band switch if needed } return retval; } int k3_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { char *cmd; int retval; if (ch < 1 || ch > 4) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1<=ch<=4, got %d\n", __func__, ch); return (-RIG_EINVAL); } switch (ch) { case 1: cmd = "SWT21;"; break; case 2: cmd = "SWT31;"; break; case 3: cmd = "SWT35;"; break; case 4: cmd = "SWT39;"; break; } retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } int k3_stop_voice_mem(RIG *rig, vfo_t vfo) { int retval; retval = kenwood_transaction(rig, "SWT37;", NULL, 0); return retval; } int k4_send_voice_mem(RIG *rig, vfo_t vfo, int ch) { int retval; char cmd[32]; if (ch < 1 || ch > 8) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1<=ch<=8, got %d\n", __func__, ch); return (-RIG_EINVAL); } sprintf(cmd, "DAMP%d00000;", ch); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } int k4_stop_voice_mem(RIG *rig, vfo_t vfo) { int retval; retval = kenwood_transaction(rig, "DA0;", NULL, 0); return retval; } int k4_stop_morse(RIG *rig, vfo_t vfo) { int retval; retval = kenwood_transaction(rig, "KY @;", NULL, 0); return retval; } int k3_stop_morse(RIG *rig, vfo_t vfo) { int retval; char cmd[32]; SNPRINTF(cmd, sizeof(cmd), "KY %c;", 0x04); retval = kenwood_transaction(rig, cmd, NULL, 0); return retval; } hamlib-4.6.2/rigs/kenwood/ts570.c0000644000175000017500000010744014752216205013352 00000000000000/* * Hamlib Kenwood backend - TS570 description * Copyright (c) 2001-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include #include #include #include #include #include "kenwood.h" #define TS570_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS570_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM|RIG_MODE_RTTY) #define TS570_AM_TX_MODES RIG_MODE_AM #define TS570_FUNC_ALL (RIG_FUNC_FAGC|RIG_FUNC_TSQL|RIG_FUNC_TONE|RIG_FUNC_NB|RIG_FUNC_COMP|RIG_FUNC_VOX|RIG_FUNC_NR|RIG_FUNC_LOCK|RIG_FUNC_BC|RIG_FUNC_TUNER) #define TS570_LEVEL_ALL (RIG_LEVEL_PREAMP|RIG_LEVEL_ATT|RIG_LEVEL_AGC|RIG_LEVEL_SQL|RIG_LEVEL_STRENGTH|RIG_LEVEL_AF|RIG_LEVEL_RF|RIG_LEVEL_RFPOWER|RIG_LEVEL_MICGAIN|RIG_LEVEL_SLOPE_LOW|RIG_LEVEL_SLOPE_HIGH|RIG_LEVEL_KEYSPD) #define TS570_VFO (RIG_VFO_A|RIG_VFO_B) #define TS570_VFO_OP (RIG_OP_UP|RIG_OP_DOWN) #define TS570_SCAN_OPS (RIG_SCAN_VFO) #define TS570_ANTS (RIG_ANT_1|RIG_ANT_2) #define TS570_STR_CAL {9, {\ { 0, -60},\ { 3, -48},\ { 6, -36},\ { 9, -24},\ {12, -12},\ {15, 0},\ {20, 20},\ {25, 40},\ {30, 60}}\ } static struct kenwood_priv_caps ts570_priv_caps = { .cmdtrm = EOM_KEN, .tone_table_base = 1, }; static int ts570_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { char buf[50]; size_t length; int retval; retval = kenwood_transaction(rig, "MD", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length != 3 || buf[1] != 'D') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected MD answer, len=%d\n", __func__, (int)length); return -RIG_ERJCTED; } switch (buf[2]) { case MD_CW: *mode = RIG_MODE_CW; break; case MD_CWR: *mode = RIG_MODE_CWR; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_FM: *mode = RIG_MODE_FM; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FSK: *mode = RIG_MODE_RTTY; break; case MD_FSKR: *mode = RIG_MODE_RTTYR; break; case MD_NONE: *mode = RIG_MODE_NONE; break; default: rig_debug(RIG_DEBUG_ERR, "ts570_get_mode: " "unsupported mode '%c'\n", buf[2]); return -RIG_EINVAL; } /* * Use FW (Filter Width) for CW and RTTY, * SL (dsp Slope Low cut-off) for all the other modes. * This is how it works on the TS870S, which does not have SL/SH commands. * TODO: combine SL and SH to set/read bandwidth.... */ switch (*mode) { case RIG_MODE_CW: case RIG_MODE_CWR: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: retval = kenwood_transaction(rig, "FW", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length != 6 || buf[1] != 'W') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected FW answer, len=%d\n", __func__, (int)length); return -RIG_ERJCTED; } *width = atoi(&buf[2]); break; case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_FM: case RIG_MODE_AM: retval = kenwood_transaction(rig, "SL", buf, sizeof(buf)); if (retval != RIG_OK) { return retval; } length = strlen(buf); if (length != 4 || buf[1] != 'L') { rig_debug(RIG_DEBUG_ERR, "%s: unexpected SL answer, len=%d\n", __func__, (int)length); return -RIG_ERJCTED; } *width = 50 * atoi(&buf[2]); break; default: return -RIG_EINVAL; } return RIG_OK; } static char mode_to_char(rmode_t mode) { switch (mode) { case RIG_MODE_CW: return (MD_CW); case RIG_MODE_CWR: return (MD_CWR); case RIG_MODE_USB: return (MD_USB); case RIG_MODE_LSB: return (MD_LSB); case RIG_MODE_FM: return (MD_FM); case RIG_MODE_AM: return (MD_AM); case RIG_MODE_RTTY: return (MD_FSK); case RIG_MODE_RTTYR: return (MD_FSKR); default: rig_debug(RIG_DEBUG_WARN, "%s: unsupported mode %s\n", __func__, rig_strrmode(mode)); } return (RIG_MODE_NONE); } static int ts570_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char buf[16]; int kmode, retval; if ((kmode = mode_to_char(mode)) == RIG_MODE_NONE) { return -RIG_EINVAL; } SNPRINTF(buf, sizeof(buf), "MD%c", kmode); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } if (RIG_PASSBAND_NOCHANGE == width) { return retval; } switch (mode) { case RIG_MODE_CW: case RIG_MODE_CWR: case RIG_MODE_RTTY: case RIG_MODE_RTTYR: SNPRINTF(buf, sizeof(buf), "FW%04d", (int)width); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } break; case RIG_MODE_USB: case RIG_MODE_LSB: case RIG_MODE_FM: case RIG_MODE_AM: SNPRINTF(buf, sizeof(buf), "SL%02d", (int)width / 50); retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } break; default: return -RIG_EINVAL; } return RIG_OK; } /* * extends kenwood_set_func * Assumes rig!=NULL, val!=NULL */ int ts570_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char fctbuf[6]; /* Filter unimplemented RIG_FUNC_TUNER and allow settings 0..2 for * RIG_FUNC_NR. * Send all other requests to kenwood_set_func() */ switch (func) { case RIG_FUNC_NR: if ((status < 0) || (status > 2)) { return -RIG_EINVAL; } SNPRINTF(fctbuf, sizeof(fctbuf), "NR%01d", status); return kenwood_transaction(rig, fctbuf, NULL, 0); case RIG_FUNC_TUNER: SNPRINTF(fctbuf, sizeof(fctbuf), "AC %c0", (0 == status) ? '0' : '1'); return kenwood_transaction(rig, fctbuf, NULL, 0); default: return kenwood_set_func(rig, vfo, func, status); } return RIG_OK; } /* * extends kenwood_get_func * Assumes rig!=NULL, val!=NULL */ int ts570_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { char fctbuf[50]; size_t fct_len; int retval; fct_len = 50; /* filter unimplemented RIG_FUNC_TUNER * and send all other requests to kenwood_get_func() */ switch (func) { case RIG_FUNC_NR: retval = kenwood_transaction(rig, "NR", fctbuf, sizeof(fctbuf)); if (retval != RIG_OK) { return retval; } fct_len = strlen(fctbuf); if (fct_len != 3) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)fct_len); return -RIG_ERJCTED; } *status = atoi(&fctbuf[2]); break; case RIG_FUNC_TUNER: retval = kenwood_transaction(rig, "AC", fctbuf, sizeof(fctbuf)); if (retval != RIG_OK) { return retval; } fct_len = strlen(fctbuf); if (fct_len != 5) { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)fct_len); return -RIG_ERJCTED; } *status = fctbuf[3] == '0' ? 0 : 1; break; default: return kenwood_get_func(rig, vfo, func, status); } return RIG_OK; } /* * ts570_set_level * Assumes rig!=NULL * * set levels of most functions */ int ts570_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { char levelbuf[16]; int kenwood_val; switch (level) { case RIG_LEVEL_PREAMP: kenwood_val = val.i; /* set the preamplifier if a correct value is entered */ if (kenwood_val == 0) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA0"); } else { int i; for (i = 0; i < HAMLIB_MAXDBLSTSIZ; i++) if (kenwood_val == STATE(rig)->preamp[i]) { SNPRINTF(levelbuf, sizeof(levelbuf), "PA%01d", i + 1); break; /* found - stop searching */ } else { return -RIG_EINVAL; } } return kenwood_transaction(rig, levelbuf, NULL, 0); case RIG_LEVEL_RFPOWER: /* level for TS570D is from 0.. 100W in SSB and CW */ kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "PC%03d", kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); case RIG_LEVEL_MICGAIN: /* level is from 0..100 */ kenwood_val = val.f * 100; SNPRINTF(levelbuf, sizeof(levelbuf), "MG%03d", kenwood_val); return kenwood_transaction(rig, levelbuf, NULL, 0); default: return kenwood_set_level(rig, vfo, level, val); } return RIG_OK; /* never reached */ } /* * ts570_get_level * Assumes rig!=NULL, val!=NULL */ int ts570_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { char ackbuf[50]; size_t ack_len; int levelint; int retval; switch (level) { case RIG_LEVEL_RFPOWER: /* ts570d returns 5..100 measured in watt */ retval = kenwood_transaction(rig, "PC", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_MICGAIN: /* reads from 0..100 */ retval = kenwood_transaction(rig, "MG", ackbuf, sizeof(ackbuf)); if (RIG_OK != retval) { return retval; } ack_len = strlen(ackbuf); if (5 != ack_len) { return -RIG_EPROTO; } if (1 != sscanf(&ackbuf[2], "%d", &levelint)) { return -RIG_EPROTO; } val->f = (float) levelint / 100.; return RIG_OK; case RIG_LEVEL_PREAMP: retval = kenwood_transaction(rig, "PA", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } ack_len = strlen(ackbuf); if (3 != ack_len) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected answer len=%d\n", __func__, (int)ack_len); return -RIG_ERJCTED; } sscanf(ackbuf + 2, "%d", &levelint); if (levelint == 0) { val->i = 0; } else { int i; for (i = 0; i < levelint && i < HAMLIB_MAXDBLSTSIZ; i++) { if (STATE(rig)->preamp[i] == 0) { rig_debug(RIG_DEBUG_ERR, "%s: unexpected att level %d\n", __func__, (int)levelint); return -RIG_EPROTO; } } if (i != levelint) { return -RIG_EINTERNAL; } val->i = STATE(rig)->preamp[i - 1]; } break; default: return kenwood_get_level(rig, vfo, level, val); } return RIG_OK; /* never reached */ } /* * ts570_get_split_vfo */ int ts570_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { char ack[10]; char ack2[10]; int retval; retval = kenwood_transaction(rig, "FR", ack, sizeof(ack)); if (retval != RIG_OK) { return retval; } retval = kenwood_transaction(rig, "FT", ack2, sizeof(ack2)); if (retval != RIG_OK) { return retval; } if (ack[2] != ack2[2]) { *split = RIG_SPLIT_ON; switch (ack2[2]) { case '0': *tx_vfo = RIG_VFO_A; break; case '1': *tx_vfo = RIG_VFO_B; break; case '2': *tx_vfo = RIG_VFO_MEM; break; default: rig_debug(RIG_DEBUG_ERR, "ts570_get_split_vfo: unknown tx vfo: %d\n", ack2[2]); return -RIG_EINVAL; } } else { *split = RIG_SPLIT_OFF; *tx_vfo = RIG_VFO_CURR; } return RIG_OK; } #define cmd_trm(rig) ((struct kenwood_priv_caps *)(rig)->caps->priv)->cmdtrm /* * ts570_set_split_vfo */ int ts570_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t txvfo) { char cmdbuf[16], ackbuf[20]; int retval; unsigned char vfo_function; if (vfo != RIG_VFO_CURR) { switch (vfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; default: rig_debug(RIG_DEBUG_ERR, "ts570_set_split_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } /* set RX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FR%c%c", vfo_function, cmd_trm(rig)); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } } if (split == RIG_SPLIT_ON) { switch (txvfo) { case RIG_VFO_VFO: case RIG_VFO_A: vfo_function = '0'; break; case RIG_VFO_B: vfo_function = '1'; break; case RIG_VFO_MEM: vfo_function = '2'; break; case RIG_VFO_TX: if (vfo == RIG_VFO_A) { vfo_function = '0'; } else if (vfo == RIG_VFO_B) { vfo_function = '1'; } else if (vfo == RIG_VFO_MEM) { vfo_function = '2'; } else { rig_debug(RIG_DEBUG_ERR, "%s: unsupported vfo/txvfo combination vfo=%s, txvfo=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(txvfo)); return -RIG_EINVAL; } break; default: rig_debug(RIG_DEBUG_ERR, "ts570_set_split_vfo: unsupported VFO %s\n", rig_strvfo(txvfo)); return -RIG_EINVAL; } /* set TX VFO */ SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT%c%c", vfo_function, cmd_trm(rig)); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } } else /* RIG_SPLIT_OFF */ if (vfo == RIG_VFO_CURR) { /* switch to current RX VFO */ /* first ask for it */ retval = kenwood_transaction(rig, "FR", ackbuf, sizeof(ackbuf)); if (retval != RIG_OK) { return retval; } /* and then set it to both vfo's */ vfo_function = ackbuf[2]; SNPRINTF(cmdbuf, sizeof(cmdbuf), "FT%c%c", vfo_function, cmd_trm(rig)); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* memory capabilities */ #define TS570_MEM_CAP { \ .freq = 1, \ .mode = 1, \ .tx_freq=1, \ .tx_mode=1, \ .split=1, \ .ctcss_tone=1 \ } int ts570_set_channel(RIG *rig, vfo_t vfo, const channel_t *chan) { char cmdbuf[30]; int retval; int num, freq, tx_freq, tone; char mode, tx_mode, tones; num = chan->channel_num; freq = (int)chan->freq; mode = mode_to_char(chan->mode); if (chan->split == RIG_SPLIT_ON) { tx_freq = (int)chan->tx_freq; tx_mode = mode_to_char(chan->tx_mode); } else { tx_freq = 0; tx_mode = '\0'; } for (tone = 1; rig->caps->ctcss_list[tone - 1] != 0 && tone < 39; tone++) { if (rig->caps->ctcss_list[tone - 1] == chan->ctcss_tone) { break; } } if (chan->ctcss_tone != 0) { tones = '1'; } else { tones = '0'; tone = 0; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW0 %02d%011d%c0%c%02d ", num, freq, mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } SNPRINTF(cmdbuf, sizeof(cmdbuf), "MW1 %02d%011d%c0%c%02d ", num, tx_freq, tx_mode, tones, tone); retval = kenwood_transaction(rig, cmdbuf, NULL, 0); if (retval != RIG_OK) { return retval; } return RIG_OK; } int ts570_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { char infobuf[50]; int retval; size_t info_len; retval = kenwood_transaction(rig, "IF", infobuf, sizeof(infobuf)); if (retval != RIG_OK) { return retval; } info_len = strlen(infobuf); if (info_len != 37 || infobuf[1] != 'F') { rig_debug(RIG_DEBUG_ERR, "%s: wrong answer len=%d\n", __func__, (int)info_len); return -RIG_ERJCTED; } if (infobuf[24] == '0') /* RIT off? */ { *rit = 0; } else { infobuf[23] = '\0'; *rit = atoi(&infobuf[18]); } return RIG_OK; } int ts570_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[50]; unsigned char c; int retval, i; if (rit == 0) { retval = kenwood_transaction(rig, "RT0", NULL, 0); if (retval != RIG_OK) { return retval; } else { return RIG_OK; } } else { retval = kenwood_transaction(rig, "RT1", NULL, 0); if (retval != RIG_OK) { return retval; } } if (rit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 10)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } int ts570_set_xit(RIG *rig, vfo_t vfo, shortfreq_t rit) { char buf[50]; unsigned char c; int retval, i; if (rit == 0) { retval = kenwood_transaction(rig, "XT0", NULL, 0); if (retval != RIG_OK) { return retval; } else { return RIG_OK; } } else { retval = kenwood_transaction(rig, "XT1", NULL, 0); if (retval != RIG_OK) { return retval; } } if (rit > 0) { c = 'U'; } else { c = 'D'; } SNPRINTF(buf, sizeof(buf), "R%c", c); retval = kenwood_transaction(rig, "RC", NULL, 0); if (retval != RIG_OK) { return retval; } for (i = 0; i < labs(lrint(rit / 10)); i++) { retval = kenwood_transaction(rig, buf, NULL, 0); if (retval != RIG_OK) { return retval; } } return RIG_OK; } /* * ts570 rig capabilities. * Notice that some rigs share the same functions. * RIT: Variable Range ±9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts570s_caps = { RIG_MODEL(RIG_MODEL_TS570S), .model_name = "TS-570S", .mfg_name = "Kenwood", .version = BACKEND_VER ".3", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 30, .timeout = 500, .retry = 10, .has_get_func = TS570_FUNC_ALL, .has_set_func = TS570_FUNC_ALL, .has_get_level = TS570_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS570_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 18, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = TS570_VFO_OP, .scan_ops = TS570_SCAN_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .agc_level_count = 2, .agc_levels = { RIG_AGC_FAST, RIG_AGC_SLOW }, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS570_MEM_CAP }, { 90, 99, RIG_MTYPE_EDGE, TS570_MEM_CAP }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(60), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), kHz(3800) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), kHz(3800) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(60), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), MHz(4) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(50), MHz(54), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS570_ALL_MODES, 50}, {TS570_ALL_MODES, 100}, {TS570_ALL_MODES, kHz(1)}, {TS570_ALL_MODES, kHz(5)}, {TS570_ALL_MODES, kHz(9)}, {TS570_ALL_MODES, kHz(10)}, {TS570_ALL_MODES, 12500}, {TS570_ALL_MODES, kHz(20)}, {TS570_ALL_MODES, kHz(25)}, {TS570_ALL_MODES, kHz(100)}, {TS570_ALL_MODES, MHz(1)}, {TS570_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_CW, Hz(200)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_AM, kHz(9)}, {RIG_MODE_FM, kHz(14)}, RIG_FLT_END, }, .priv = (void *)& ts570_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts570_set_rit, .get_rit = kenwood_get_rit, .set_xit = ts570_set_xit, .get_xit = ts570_get_xit, .set_mode = ts570_set_mode, .get_mode = ts570_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = ts570_set_split_vfo, .get_split_vfo = ts570_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = ts570_set_func, .get_func = ts570_get_func, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .set_level = ts570_set_level, .get_level = ts570_get_level, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = kenwood_get_channel, .set_channel = ts570_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .scan = kenwood_scan, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * ts570d rig capabilities, which is basically the ts570s without 6m. * Notice that some rigs share the same functions. * RIT: Variable Range ±9.99 kHz * * part of infos comes from .http = //www.kenwood.net/ */ struct rig_caps ts570d_caps = { RIG_MODEL(RIG_MODEL_TS570D), .model_name = "TS-570D", .mfg_name = "Kenwood", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 1200, .serial_rate_max = 57600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_HARDWARE, .write_delay = 0, .post_write_delay = 30, .timeout = 500, .retry = 10, .has_get_func = TS570_FUNC_ALL, .has_set_func = TS570_FUNC_ALL, .has_get_level = TS570_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(TS570_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, /* FIXME: parms */ .level_gran = { #include "level_gran_kenwood.h" }, .parm_gran = {}, .ctcss_list = kenwood38_ctcss_list, .dcs_list = NULL, .preamp = { 12, RIG_DBLST_END, }, .attenuator = { 18, RIG_DBLST_END, }, .max_rit = Hz(9990), .max_xit = Hz(9990), .max_ifshift = Hz(0), .vfo_ops = TS570_VFO_OP, .scan_ops = TS570_SCAN_OPS, .targetable_vfo = RIG_TARGETABLE_FREQ, .transceive = RIG_TRN_RIG, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 89, RIG_MTYPE_MEM, TS570_MEM_CAP }, { 90, 99, RIG_MTYPE_EDGE, TS570_MEM_CAP }, { 1, 3, RIG_MTYPE_MORSE }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(500), MHz(30), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list1 = { {kHz(1810), kHz(1850) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), kHz(3800) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), kHz(3800) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7100), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .rx_range_list2 = { {kHz(500), MHz(30), TS570_ALL_MODES, -1, -1, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* rx range */ .tx_range_list2 = { {kHz(1800), MHz(2) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, /* 100W class */ {kHz(1800), MHz(2) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, /* 25W class */ {kHz(3500), MHz(4) - 1, TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(3500), MHz(4) - 1, TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(7), kHz(7300), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(10100), kHz(10150), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(14), kHz(14350), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(18068), kHz(18168), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(21), kHz(21450), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {kHz(24890), kHz(24990), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_OTHER_TX_MODES, 5000, 100000, TS570_VFO, TS570_ANTS}, {MHz(28), kHz(29700), TS570_AM_TX_MODES, 5000, 25000, TS570_VFO, TS570_ANTS}, RIG_FRNG_END, }, /* tx range */ .tuning_steps = { {TS570_ALL_MODES, 50}, {TS570_ALL_MODES, 100}, {TS570_ALL_MODES, kHz(1)}, {TS570_ALL_MODES, kHz(5)}, {TS570_ALL_MODES, kHz(9)}, {TS570_ALL_MODES, kHz(10)}, {TS570_ALL_MODES, 12500}, {TS570_ALL_MODES, kHz(20)}, {TS570_ALL_MODES, kHz(25)}, {TS570_ALL_MODES, kHz(100)}, {TS570_ALL_MODES, MHz(1)}, {TS570_ALL_MODES, 0}, /* any tuning step */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB, Hz(500)}, {RIG_MODE_SSB, Hz(0)}, {RIG_MODE_SSB, kHz(1)}, {RIG_MODE_CW, Hz(400)}, {RIG_MODE_CW, Hz(100)}, {RIG_MODE_CW, Hz(1000)}, {RIG_MODE_RTTY, Hz(1000)}, {RIG_MODE_RTTY, Hz(500)}, {RIG_MODE_RTTY, Hz(1500)}, {RIG_MODE_AM, Hz(500)}, {RIG_MODE_AM, Hz(0)}, {RIG_MODE_AM, kHz(1)}, {RIG_MODE_FM, Hz(500)}, {RIG_MODE_FM, Hz(0)}, {RIG_MODE_FM, kHz(1)}, RIG_FLT_END, }, .str_cal = TS570_STR_CAL, .priv = (void *)& ts570_priv_caps, .rig_init = kenwood_init, .rig_open = kenwood_open, .rig_cleanup = kenwood_cleanup, .set_freq = kenwood_set_freq, .get_freq = kenwood_get_freq, .set_rit = ts570_set_rit, .get_rit = kenwood_get_rit, .set_xit = ts570_set_xit, .get_xit = ts570_get_xit, .set_mode = ts570_set_mode, .get_mode = ts570_get_mode, .set_vfo = kenwood_set_vfo, .get_vfo = kenwood_get_vfo_if, .set_split_vfo = ts570_set_split_vfo, .get_split_vfo = ts570_get_split_vfo, .set_ctcss_tone = kenwood_set_ctcss_tone, .get_ctcss_tone = kenwood_get_ctcss_tone, .get_ptt = kenwood_get_ptt, .set_ptt = kenwood_set_ptt, .get_dcd = kenwood_get_dcd, .set_func = ts570_set_func, .get_func = ts570_get_func, .set_ant = kenwood_set_ant_no_ack, .get_ant = kenwood_get_ant, .set_level = ts570_set_level, .get_level = ts570_get_level, .send_morse = kenwood_send_morse, .wait_morse = rig_wait_morse, .vfo_op = kenwood_vfo_op, .set_mem = kenwood_set_mem, .get_mem = kenwood_get_mem, .get_channel = kenwood_get_channel, .set_channel = ts570_set_channel, .set_trn = kenwood_set_trn, .get_trn = kenwood_get_trn, .set_powerstat = kenwood_set_powerstat, .get_powerstat = kenwood_get_powerstat, .scan = kenwood_scan, .reset = kenwood_reset, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; hamlib-4.6.2/rigs/alinco/0000755000175000017500000000000014752216242012176 500000000000000hamlib-4.6.2/rigs/alinco/alinco.c0000644000175000017500000000217314752216205013531 00000000000000/* * Hamlib Alinco backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include "alinco.h" /* * initrigs_alinco is called by rig_backend_load */ DECLARE_INITRIG_BACKEND(alinco) { rig_register(&dx77_caps); rig_register(&dxsr8_caps); return RIG_OK; } /* * Function definitions below */ hamlib-4.6.2/rigs/alinco/Makefile.am0000644000175000017500000000023314752216205014147 00000000000000ALINCOSRC = dx77.c dxsr8.c alinco.c alinco.h noinst_LTLIBRARIES = libhamlib-alinco.la libhamlib_alinco_la_SOURCES = $(ALINCOSRC) EXTRA_DIST = Android.mk hamlib-4.6.2/rigs/alinco/Makefile.in0000644000175000017500000005265514752216215014200 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = rigs/alinco ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libhamlib_alinco_la_LIBADD = am__objects_1 = dx77.lo dxsr8.lo alinco.lo am_libhamlib_alinco_la_OBJECTS = $(am__objects_1) libhamlib_alinco_la_OBJECTS = $(am_libhamlib_alinco_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/alinco.Plo ./$(DEPDIR)/dx77.Plo \ ./$(DEPDIR)/dxsr8.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libhamlib_alinco_la_SOURCES) DIST_SOURCES = $(libhamlib_alinco_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ ALINCOSRC = dx77.c dxsr8.c alinco.c alinco.h noinst_LTLIBRARIES = libhamlib-alinco.la libhamlib_alinco_la_SOURCES = $(ALINCOSRC) EXTRA_DIST = Android.mk all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu rigs/alinco/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu rigs/alinco/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libhamlib-alinco.la: $(libhamlib_alinco_la_OBJECTS) $(libhamlib_alinco_la_DEPENDENCIES) $(EXTRA_libhamlib_alinco_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libhamlib_alinco_la_OBJECTS) $(libhamlib_alinco_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alinco.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dx77.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dxsr8.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/alinco.Plo -rm -f ./$(DEPDIR)/dx77.Plo -rm -f ./$(DEPDIR)/dxsr8.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/alinco.Plo -rm -f ./$(DEPDIR)/dx77.Plo -rm -f ./$(DEPDIR)/dxsr8.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-noinstLTLIBRARIES \ cscopelist-am ctags ctags-am distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/rigs/alinco/Android.mk0000644000175000017500000000041114752216205014022 00000000000000LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := dx77.c alinco.c dxsr8.c LOCAL_MODULE := alinco LOCAL_CFLAGS := LOCAL_C_INCLUDES := android include src LOCAL_LDLIBS := -lhamlib -Lobj/local/$(TARGET_ARCH_ABI) include $(BUILD_STATIC_LIBRARY) hamlib-4.6.2/rigs/alinco/dxsr8.c0000644000175000017500000005063314752216205013340 00000000000000/* * Hamlib Alinco backend - DXSR8 description * Copyright (c) 2020 by Wes Bustraan (W8WJB) * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include /* String function definitions */ #include #include #include "tones.h" #include #include #include #include "idx_builtin.h" #include "alinco.h" #define DXSR8_ALL_MODES (RIG_MODE_USB|RIG_MODE_LSB|RIG_MODE_CW|RIG_MODE_CWR|RIG_MODE_AM|RIG_MODE_FM) #define DXSR8_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DXSR8_AM_TX_MODES RIG_MODE_AM #define DXSR8_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB) #define DXSR8_LEVEL_ALL (RIG_LEVEL_RFPOWER|RIG_LEVEL_RF) #define DXSR8_PARM_ALL RIG_PARM_NONE #define DXSR8_VFO RIG_VFO_A /* Line Feed */ #define EOM "\r\n" #define LF "\n" #define MD_USB 0 #define MD_LSB 1 #define MD_CWU 2 #define MD_CWL 3 #define MD_AM 4 #define MD_FM 5 int dxsr8_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int dxsr8_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int dxsr8_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int dxsr8_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int dxsr8_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int dxsr8_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int dxsr8_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int dxsr8_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int dxsr8_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int dxsr8_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt); /* * DX-SR8 rig capabilities. * * thanks to * https://yo5ptd.wordpress.com/2017/02/12/alinco-dx-sr8/ * for a partially documented protocol */ struct rig_caps dxsr8_caps = { RIG_MODEL(RIG_MODEL_DXSR8), .model_name = "DX-SR8", .mfg_name = "Alinco", .version = BACKEND_VER ".0", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_RIG, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 1, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = DXSR8_FUNC, .has_set_func = DXSR8_FUNC, .has_get_level = DXSR8_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DXSR8_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, 20, RIG_DBLST_END }, .max_rit = kHz(1.2), .max_xit = kHz(1.2), .max_ifshift = kHz(1.5), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 199, RIG_MTYPE_MEM }, { 0, 199, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { {kHz(135), MHz(30), DXSR8_ALL_MODES, -1, -1, DXSR8_VFO, 0, "DX-SR8T"}, RIG_FRNG_END, }, .tx_range_list1 = { {kHz(1800), MHz(2) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(1800), MHz(2) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(3500), MHz(4) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(3500), MHz(4) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {5330500, 5330500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5346500, 5346500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5366500, 5366500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5371500, 5371500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {5403500, 5403500, DXSR8_AM_TX_MODES, W(1), W(50), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(7), kHz(7300), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(7), kHz(7300), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(10100), kHz(10150), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(10100), kHz(10150), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(14), kHz(14350), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(14), kHz(14350), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(18068), kHz(18168), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(18068), kHz(18168), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(21), kHz(21450), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(21), kHz(21450), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(24890), kHz(24990), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {kHz(24890), kHz(24990), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(28), kHz(29700), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8T"}, {MHz(28), kHz(29700), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8T"}, RIG_FRNG_END, }, .rx_range_list2 = { {kHz(135), MHz(30), DXSR8_ALL_MODES, -1, -1, DXSR8_VFO, 0, "DX-SR8E"}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(1800), MHz(2) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(3500), MHz(4) - 100, DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(3500), MHz(4) - 100, DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(6900), kHz(7500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(6900), kHz(7500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(9900), kHz(10500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(9900), kHz(10500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(13900), kHz(14500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(13900), kHz(14500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(17900), kHz(18500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(17900), kHz(18500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(20900), kHz(21500), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(20900), kHz(21500), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(24400), kHz(25099), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {kHz(24400), kHz(25099), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, {MHz(28), MHz(30), DXSR8_OTHER_TX_MODES, W(10), W(100), DXSR8_VFO, 0, "DX-SR8E"}, {MHz(28), MHz(30), DXSR8_AM_TX_MODES, W(4), W(40), DXSR8_VFO, 0, "DX-SR8E"}, RIG_FRNG_END, }, .tuning_steps = { {DXSR8_ALL_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_CW, kHz(1)}, {RIG_MODE_CW, kHz(0.5)}, {RIG_MODE_SSB, kHz(2.4)}, {RIG_MODE_SSB, kHz(1)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(9)}, {RIG_MODE_AM, kHz(2.4)}, RIG_FLT_END, }, .set_freq = dxsr8_set_freq, // AL~RW_RXF14212000 .get_freq = dxsr8_get_freq, // AL~RR_RXF .set_mode = dxsr8_set_mode, // AL~RW_RFM00, AL~RW_NAR00 .get_mode = dxsr8_get_mode, // AL~RR_RFM, AL~RR_NAR .get_ptt = dxsr8_get_ptt, // AL~RR_PTT .set_ptt = dxsr8_set_ptt, // AL~RW_PTT00 .set_func = dxsr8_set_func, // AL~RW_AGC00, AL~RW_NZB00 .get_func = dxsr8_get_func, // AL~RR_AGC, AL~RR_NZB .set_level = dxsr8_set_level, // AL~RW_RFG00, AL~RW_PWR00 .get_level = dxsr8_get_level, // AL~RR_RFG, AL~RR_PWR .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * dxsr8_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ int dxsr8_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char replybuf[BUFSZ + 1]; int reply_len; if (cmd == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: null argument for cmd?\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* * Transceiver sends an echo of cmd followed by a CR/LF * TODO: check whether cmd and echobuf match (optional) */ retval = read_string(rp, (unsigned char *) replybuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } retval = read_string(rp, (unsigned char *) replybuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } /* no data expected, check for OK returned */ if (data == NULL) { if (retval > 2) { retval -= 2; } replybuf[retval] = 0; if (strcmp(replybuf, "OK") == 0) { return RIG_OK; } else { return -RIG_ERJCTED; } } // strip CR/LF from string reply_len = strcspn(replybuf, "\r\n"); replybuf[reply_len] = 0; strcpy(data, replybuf); *data_len = reply_len; return RIG_OK; } /** * dxsr8_read_num * Convenience function to read a numeric value from the radio */ int dxsr8_read_num(RIG *rig, const char *cmd, int *reply_num) { int retval; int reply_len; char replybuf[10]; retval = dxsr8_transaction(rig, cmd, strlen(cmd), replybuf, &reply_len); if (retval != RIG_OK) { return retval; } *reply_num = atoi(replybuf); return RIG_OK; } /* * dxsr8_set_freq * Assumes rig!=NULL */ int dxsr8_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char cmd[BUFSZ]; /* max 10 digits */ if (freq >= GHz(10)) { return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), AL "~RW_RXF%08"PRIll EOM, (int64_t)freq); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); } /* * dxsr8_get_freq * Assumes rig!=NULL, freq!=NULL */ int dxsr8_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval, data_len; const char cmd[] = AL "~RR_RXF" EOM; char freqbuf[BUFSZ]; retval = dxsr8_transaction(rig, cmd, strlen(cmd), freqbuf, &data_len); if (retval != RIG_OK) { return retval; } /* extract RX freq */ num_sscanf(freqbuf, "%"SCNfreq, freq); return RIG_OK; } /* * dxsr8_set_mode * Assumes rig!=NULL */ int dxsr8_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int wide_filter, retval; int amode; switch (mode) { case RIG_MODE_CW: amode = MD_CWU; break; case RIG_MODE_CWR: amode = MD_CWL; break; case RIG_MODE_USB: amode = MD_USB; break; case RIG_MODE_LSB: amode = MD_LSB; break; case RIG_MODE_FM: amode = MD_FM; break; case RIG_MODE_AM: amode = MD_AM; break; default: rig_debug(RIG_DEBUG_ERR, "dxsr8_set_mode: unsupported mode %s\n", rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), AL "~RW_RFM%02d" EOM, amode); retval = dxsr8_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } if (width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { wide_filter = 1; // AL~RW_NAR01 Set narrow bandwidth } else { wide_filter = 0; // AL~RW_NAR00 Set wide bandwidth } SNPRINTF(mdbuf, sizeof(mdbuf), AL "~RW_NAR%02d" EOM, wide_filter); retval = dxsr8_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * dxsr8_get_mode * Assumes rig!=NULL, mode!=NULL */ int dxsr8_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int amode; int filter; retval = dxsr8_read_num(rig, AL "~RR_RFM" EOM, &amode); if (retval != RIG_OK) { return retval; } switch (amode) { case MD_CWL: case MD_CWU: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "dxsr8_get_mode: unknown mode %02d\n", amode); return -RIG_EINVAL; } filter = 0; // avoid compiler warnings of being possibly uninitialized retval = dxsr8_read_num(rig, AL "~RR_NAR" EOM, &filter); if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s: dxsr8_read_num:%s\n", __func__, rigerror(retval)); return retval; } if (filter == 0) { *width = rig_passband_wide(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * dxsr8_set_func * Assumes rig!=NULL */ int dxsr8_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmd[BUFSZ]; switch (func) { case RIG_FUNC_FAGC: SNPRINTF(cmd, sizeof(cmd), AL "~RW_AGC%02d" EOM, status ? 0 : 1); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); case RIG_FUNC_NB: SNPRINTF(cmd, sizeof(cmd), AL "~RW_NZB%d" EOM, status ? 1 : 0); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_get_func * Assumes rig!=NULL, status!=NULL */ int dxsr8_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; int setting; switch (func) { case RIG_FUNC_FAGC: retval = dxsr8_read_num(rig, AL "~RR_AGC" EOM, &setting); if (retval != RIG_OK) { return retval; } // 00 = Fast AGC // 01 = Slow AGC *status = setting ? 0 : 1; break; case RIG_FUNC_NB: retval = dxsr8_read_num(rig, AL "~RR_NZB" EOM, &setting); if (retval != RIG_OK) { return retval; } // 00 = noise blanker off // 01 = noise blanker on *status = setting ? 1 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sense though) */ int dxsr8_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int lvl; char cmd[BUFSZ]; switch (level) { case RIG_LEVEL_PREAMP: switch (val.i) { case 0: lvl = 0; break; // AL~RW_RFG00 - RF gain 0dB case 10: lvl = 3; break; // AL~RW_RFG03 - RF gain +10dB default: rig_debug(RIG_DEBUG_ERR, "Unsupported Preamp %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), AL "~RW_RFG%02d" EOM, lvl); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); case RIG_LEVEL_ATT: switch (val.i) { case 0: lvl = 0; break; // AL~RW_RFG00 - RF gain 0dB case 10: lvl = 1; break; // AL~RW_RFG01 - RF gain -10dB case 20: lvl = 2; break; // AL~RW_RFG02 - RF gain -20dB default: rig_debug(RIG_DEBUG_ERR, "Unsupported Att %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmd, sizeof(cmd), AL "~RW_RFG%02d" EOM, lvl); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); case RIG_LEVEL_RFPOWER: if (val.f <= 0.01) { lvl = 2; // AL~RW_PWR02 - Sub low power (QRP mode) } else if (val.f <= 0.1) { lvl = 1; // AL~RW_PWR01 - Low power } else { lvl = 0; // AL~RW_PWR00 - High power } SNPRINTF(cmd, sizeof(cmd), AL "~RW_PWR%02d" EOM, lvl); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_get_level * Assumes rig!=NULL, val!=NULL */ int dxsr8_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval; int lvl; switch (level) { case RIG_LEVEL_PREAMP: retval = dxsr8_read_num(rig, AL "~RR_RFG" EOM, &lvl); if (retval != RIG_OK) { return retval; } switch (lvl) { case 0: val->i = 0; break; // RF gain 0dB case 3: val->i = 10; break; // RF gain +10dB default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %02d\n", lvl); } break; case RIG_LEVEL_ATT: retval = dxsr8_read_num(rig, AL "~RR_RFG" EOM, &lvl); if (retval != RIG_OK) { return retval; } switch (lvl) { case 0: val->i = 0; break; // RF gain 0dB case 1: val->i = 10; break; // RF gain -10dB case 2: val->i = 10; break; // RF gain -20dB default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %02d\n", lvl); } break; case RIG_LEVEL_RFPOWER: retval = dxsr8_read_num(rig, AL "~RR_PWR" EOM, &lvl); if (retval != RIG_OK) { return retval; } switch (lvl) { case 0: // 00 - High power val->f = 1.0; // 100 W break; case 1: // 01 - Low power val->f = 0.1; // 10 W break; case 3: // 02 - Sub low power (QRP mode) val->f = 0.01; // 1 W break; default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Power %02d\n", lvl); break; } break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dxsr8_get_ptt * Assumes rig!=NULL, ptt!=NULL */ int dxsr8_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int retval; int pttval; retval = dxsr8_read_num(rig, AL "~RR_PTT" EOM, &pttval); if (retval != RIG_OK) { return retval; } *ptt = pttval ? RIG_PTT_ON : RIG_PTT_OFF; return RIG_OK; } /* * dxsr8_set_ptt * Assumes rig!=NULL */ int dxsr8_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { char cmd[BUFSZ]; SNPRINTF(cmd, sizeof(cmd), AL "~RW_PTT%02d" EOM, ptt); return dxsr8_transaction(rig, cmd, strlen(cmd), NULL, NULL); } hamlib-4.6.2/rigs/alinco/alinco.h0000644000175000017500000000210414752216205013530 00000000000000/* * Hamlib Alinco backend - main header * Copyright (c) 2001-2003 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef _ALINCO_H #define _ALINCO_H 1 #include #define BACKEND_VER "20200323" extern struct rig_caps dx77_caps; extern struct rig_caps dxsr8_caps; #define BUFSZ 32 #define AL "AL" #endif /* _ALINCO_H */ hamlib-4.6.2/rigs/alinco/dx77.c0000644000175000017500000010534614752216205013063 00000000000000/* * Hamlib Alinco backend - DX77 description * Copyright (c) 2001-2005 by Stephane Fillod * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include #include #include #include /* String function definitions */ #include #include "idx_builtin.h" #include "alinco.h" #include #include "tones.h" #include /* * modes in use by the "2G" command */ #define MD_LSB '0' #define MD_USB '1' #define MD_CWL '2' #define MD_CWU '3' #define MD_AM '4' #define MD_FM '5' /* Line Feed */ #define EOM "\x0d" #define LF "\x0a" #define CMD_TXFREQ "0A" /* Transmit frequency */ #define CMD_RXFREQ "0B" /* Receive frequency */ #define CMD_VFO "1A" #define CMD_MEMMD "1B" /* Memory mode */ #define CMD_CHAN "1D" /* Channel Display */ #define CMD_UPDWN "2A" /* UP/DOWN */ #define CMD_MON "2B" /* Check Transmit Frequency */ #define CMD_PWR "2C" /* Transmit Output Power */ #define CMD_SCAN "2D" /* Scanning */ #define CMD_PRIO "2E" /* Priority */ #define CMD_SPLT "2F" /* Split */ #define CMD_MODE "2G" /* Mode */ #define CMD_RFGAIN "2H" /* RF Gain */ #define CMD_AGC "2I" #define CMD_FLTER "2J" /* Filter */ #define CMD_NB "2K" #define CMD_CTCSS "2L" #define CMD_TUNE "2M" #define CMD_SELECT "2N" #define CMD_MCALL "2V" /* Memory Channel Call Up */ #define CMD_SDATA "2W" /* Set Data */ /* Data Output Commands */ #define CMD_SMETER "3A" /* S-meter read */ #define CMD_PTT "3B" /* PTT status read */ #define CMD_SQL "3C" /* Squelch status */ #define CMD_RIT "3D" /* RIT status */ #define CMD_RMEM "3E" /* Current Memory-channel Number read */ #define CMD_RMV "3G" /* Memory/VFO -mode read */ #define CMD_RDATA "3H" /* Current Data read */ #define CMD_RSPLT "3I" /* Split read */ #define CMD_RPOWER "3J" /* Transmitter Output read */ #define CMD_RSELECT "3K" /* SELECT Position read */ #define DX77_ALL_MODES (RIG_MODE_AM|RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DX77_OTHER_TX_MODES (RIG_MODE_CW|RIG_MODE_SSB|RIG_MODE_FM) #define DX77_AM_TX_MODES RIG_MODE_AM #define DX77_FUNC (RIG_FUNC_FAGC|RIG_FUNC_NB|RIG_FUNC_TONE) #define DX77_LEVEL_ALL (RIG_LEVEL_RAWSTR|RIG_LEVEL_RFPOWER|RIG_LEVEL_KEYSPD|RIG_LEVEL_BKINDL|RIG_LEVEL_CWPITCH) #define DX77_PARM_ALL (RIG_PARM_BEEP|RIG_PARM_BACKLIGHT) #define DX77_VFO (RIG_VFO_A|RIG_VFO_B) /* 90 is S9 */ #define DX77_STR_CAL { 13, { \ { 0, -60 }, \ { 28, -48 }, \ { 36, -42 }, \ { 42, -36 }, \ { 50, -30 }, \ { 58, -24 }, \ { 66, -18 }, \ { 74, -12 }, \ { 82, -6 }, \ { 90, 0 }, \ { 132, 20 }, \ { 174, 40 }, \ { 216, 60 }, \ } } int dx77_set_vfo(RIG *rig, vfo_t vfo); int dx77_get_vfo(RIG *rig, vfo_t *vfo); int dx77_set_freq(RIG *rig, vfo_t vfo, freq_t freq); int dx77_get_freq(RIG *rig, vfo_t vfo, freq_t *freq); int dx77_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width); int dx77_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width); int dx77_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo); int dx77_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo); int dx77_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq); int dx77_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq); int dx77_set_func(RIG *rig, vfo_t vfo, setting_t func, int status); int dx77_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status); int dx77_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val); int dx77_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val); int dx77_set_parm(RIG *rig, setting_t parm, value_t val); int dx77_get_parm(RIG *rig, setting_t parm, value_t *val); int dx77_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone); int dx77_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit); int dx77_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt); int dx77_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd); int dx77_set_mem(RIG *rig, vfo_t vfo, int ch); int dx77_get_mem(RIG *rig, vfo_t vfo, int *ch); /* * dx77 rig capabilities. * * protocol is documented at * http://www.alinco.com/pdf.files/DX77-77_SOFTWARE_MANUAL.pdf * * This backend was a pleasure to develop. Documentation is clear, * and the protocol logical. I'm wondering is the rig's good too. --SF * * TODO: * - get_parm/set_parm and some LEVELs left (Set Data "2W" command). * - tuner * - up/down * - scan */ struct rig_caps dx77_caps = { RIG_MODEL(RIG_MODEL_DX77), .model_name = "DX-77", .mfg_name = "Alinco", .version = BACKEND_VER ".1", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_TRANSCEIVER, .ptt_type = RIG_PTT_NONE, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_SERIAL, .serial_rate_min = 9600, .serial_rate_max = 9600, .serial_data_bits = 8, .serial_stop_bits = 2, .serial_parity = RIG_PARITY_NONE, .serial_handshake = RIG_HANDSHAKE_NONE, .write_delay = 0, .post_write_delay = 0, .timeout = 200, .retry = 3, .has_get_func = DX77_FUNC, .has_set_func = DX77_FUNC | RIG_FUNC_MON | RIG_FUNC_COMP, .has_get_level = DX77_LEVEL_ALL, .has_set_level = RIG_LEVEL_SET(DX77_LEVEL_ALL), .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_SET(DX77_PARM_ALL), .level_gran = { [LVL_RAWSTR] = { .min = { .i = 0 }, .max = { .i = 255 } }, }, .parm_gran = {}, .ctcss_list = common_ctcss_list, .dcs_list = NULL, .preamp = { 10, RIG_DBLST_END }, .attenuator = { 10, 20, RIG_DBLST_END }, .max_rit = kHz(1), .max_xit = Hz(0), .max_ifshift = Hz(0), .targetable_vfo = 0, .transceive = RIG_TRN_OFF, .bank_qty = 0, .chan_desc_sz = 0, .chan_list = { { 0, 99, RIG_MTYPE_MEM }, RIG_CHAN_END, }, .rx_range_list1 = { { .startf = kHz(500), .endf = MHz(30), .modes = DX77_OTHER_TX_MODES, .low_power = -1, .high_power = -1, RIG_VFO_A, RIG_ANT_NONE }, { .startf = kHz(500), .endf = MHz(30), .modes = DX77_AM_TX_MODES, .low_power = -1, .high_power = -1, RIG_VFO_A, RIG_ANT_NONE }, RIG_FRNG_END, }, .tx_range_list1 = {RIG_FRNG_END,}, .rx_range_list2 = { {kHz(500), MHz(30), DX77_ALL_MODES, -1, -1, DX77_VFO}, RIG_FRNG_END, }, .tx_range_list2 = { {kHz(1800), MHz(2) - 100, DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(1800), MHz(2) - 100, DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(3500), MHz(4) - 100, DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(3500), MHz(4) - 100, DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(7), kHz(7300), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(7), kHz(7300), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(10100), kHz(10150), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(10100), kHz(10150), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(14), kHz(14350), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(14), kHz(14350), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(18068), kHz(18168), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(18068), kHz(18168), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(21), kHz(21450), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(21), kHz(21450), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {kHz(24890), kHz(24990), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {kHz(24890), kHz(24990), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, {MHz(28), kHz(29700), DX77_OTHER_TX_MODES, W(10), W(100), DX77_VFO}, {MHz(28), kHz(29700), DX77_AM_TX_MODES, W(4), W(40), DX77_VFO}, RIG_FRNG_END, }, .tuning_steps = { {DX77_ALL_MODES, 10}, /* FIXME: add other ts */ RIG_TS_END, }, /* mode/filter list, remember: order matters! */ .filters = { {RIG_MODE_SSB | RIG_MODE_CW, kHz(2.7)}, {RIG_MODE_CW, kHz(0.5)}, {RIG_MODE_AM | RIG_MODE_FM, kHz(8)}, {RIG_MODE_AM, kHz(2.7)}, RIG_FLT_END, }, .str_cal = DX77_STR_CAL, .set_freq = dx77_set_freq, .get_freq = dx77_get_freq, .set_mode = dx77_set_mode, .get_mode = dx77_get_mode, .set_vfo = dx77_set_vfo, .get_vfo = dx77_get_vfo, .set_split_vfo = dx77_set_split_vfo, .get_split_vfo = dx77_get_split_vfo, .set_split_freq = dx77_set_split_freq, .get_split_freq = dx77_get_split_freq, .set_ctcss_tone = dx77_set_ctcss_tone, .get_rit = dx77_get_rit, .get_ptt = dx77_get_ptt, .get_dcd = dx77_get_dcd, .set_func = dx77_set_func, .get_func = dx77_get_func, .set_parm = dx77_set_parm, .set_level = dx77_set_level, .get_level = dx77_get_level, .set_mem = dx77_set_mem, .get_mem = dx77_get_mem, .hamlib_check_rig_caps = HAMLIB_CHECK_RIG_CAPS }; /* * Function definitions below */ /* * dx77_transaction * We assume that rig!=NULL, RIGPORT(rig)!= NULL, data!=NULL, data_len!=NULL * Otherwise, you'll get a nice seg fault. You've been warned! * TODO: error case handling */ int dx77_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, int *data_len) { int retval; hamlib_port_t *rp = RIGPORT(rig); char echobuf[BUFSZ + 1]; if (cmd == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: null argument for cmd?\n", __func__); return -RIG_EINTERNAL; } rig_flush(rp); retval = write_block(rp, (unsigned char *) cmd, cmd_len); if (retval != RIG_OK) { return retval; } /* * Transceiver sends an echo of cmd followed by a CR/LF * TODO: check whether cmd and echobuf match (optional) */ retval = read_string(rp, (unsigned char *) echobuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } if (((data == NULL) && (data_len > 0)) || ((data != NULL) && (data_len == 0))) { rig_debug(RIG_DEBUG_ERR, "%s: data and datalen not both NULL??\n", __func__); return -RIG_EINTERNAL; } /* no data expected, check for OK returned */ if (data == NULL) { retval = read_string(rp, (unsigned char *) echobuf, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } if (retval > 2) { retval -= 2; } echobuf[retval] = 0; if (strcmp(echobuf, "OK") == 0) { return RIG_OK; } else { return -RIG_ERJCTED; } } retval = read_string(rp, (unsigned char *) data, BUFSZ, LF, strlen(LF), 0, 1); if (retval < 0) { return retval; } *data_len = retval; /* strip CR/LF from string */ data[0] = 0; if (*data_len > 2) { *data_len -= 2; data[*data_len] = 0; } return RIG_OK; } /* * dx77_set_vfo * Assumes rig!=NULL */ int dx77_set_vfo(RIG *rig, vfo_t vfo) { char cmdbuf[BUFSZ]; char vfo_num; switch (vfo) { case RIG_VFO_A: vfo_num = '1'; break; case RIG_VFO_B: vfo_num = '2'; break; case RIG_VFO_MEM: return dx77_transaction(rig, AL CMD_MEMMD "0" EOM, strlen(AL CMD_MEMMD "0" EOM), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "dx77_set_vfo: unsupported VFO %s\n", rig_strvfo(vfo)); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_VFO "%c" EOM, vfo_num); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * dx77_get_vfo * Assumes rig!=NULL, !vfo */ int dx77_get_vfo(RIG *rig, vfo_t *vfo) { char vfobuf[BUFSZ]; int vfo_len, retval; retval = dx77_transaction(rig, AL CMD_RMV EOM, strlen(AL CMD_RMV EOM), vfobuf, &vfo_len); if (retval != RIG_OK) { return retval; } if (vfo_len != 4) { rig_debug(RIG_DEBUG_ERR, "dx77_get_vfo: wrong answer %s, " "len=%d\n", vfobuf, vfo_len); return -RIG_ERJCTED; } vfobuf[vfo_len] = '\0'; if (!strcmp(vfobuf, "VFOA")) { *vfo = RIG_VFO_A; } else if (!strcmp(vfobuf, "VFOB")) { *vfo = RIG_VFO_B; } else if (!strcmp(vfobuf, "MEMO")) { *vfo = RIG_VFO_MEM; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_vfo: unsupported VFO %s\n", vfobuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_set_freq * Assumes rig!=NULL */ int dx77_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { char freqbuf[BUFSZ]; /* max 10 digits */ if (freq >= GHz(10)) { return -RIG_EINVAL; } /* at least 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), AL CMD_RXFREQ "%06"PRIll EOM, (int64_t)freq); return dx77_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); } /* * where databuf points to a 26 char long buffer */ static int current_data_read(RIG *rig, char *databuf) { int data_len, retval; retval = dx77_transaction(rig, AL CMD_RDATA EOM, strlen(AL CMD_RDATA EOM), databuf, &data_len); if (retval != RIG_OK) { return retval; } if (data_len != 26) { rig_debug(RIG_DEBUG_ERR, "dx77_current_data_read: wrong answer %s, len=%d\n", databuf, data_len); return -RIG_ERJCTED; } return RIG_OK; } /* * dx77_get_freq * Assumes rig!=NULL, freq!=NULL */ int dx77_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int retval; char freqbuf[BUFSZ]; retval = current_data_read(rig, freqbuf); if (retval != RIG_OK) { return retval; } /* extract RX freq */ freqbuf[16] = '\0'; sscanf(freqbuf + 6, "%"SCNfreq, freq); return RIG_OK; } /* * dx77_set_mode * Assumes rig!=NULL */ int dx77_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { char mdbuf[BUFSZ]; int wide_filter, retval; char amode; switch (mode) { /* FIXME: MD_CWL or MD_CWU? */ case RIG_MODE_CW: amode = MD_CWU; break; case RIG_MODE_USB: amode = MD_USB; break; case RIG_MODE_LSB: amode = MD_LSB; break; case RIG_MODE_FM: amode = MD_FM; break; case RIG_MODE_AM: amode = MD_AM; break; default: rig_debug(RIG_DEBUG_ERR, "dx77_set_mode: unsupported mode %s\n", rig_strrmode(mode)); return -RIG_EINVAL; } SNPRINTF(mdbuf, sizeof(mdbuf), AL CMD_MODE "%c" EOM, amode); retval = dx77_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); if (retval != RIG_OK) { return retval; } if (width == RIG_PASSBAND_NOCHANGE) { return retval; } /* * TODO: please DX77 owners, check this, I'm not sure * which passband is default! */ if (width != RIG_PASSBAND_NORMAL && width < rig_passband_normal(rig, mode)) { wide_filter = 0; } else { wide_filter = 1; } SNPRINTF(mdbuf, sizeof(mdbuf), AL CMD_FLTER "%02d" EOM, wide_filter); retval = dx77_transaction(rig, mdbuf, strlen(mdbuf), NULL, NULL); return retval; } /* * dx77_get_mode * Assumes rig!=NULL, mode!=NULL */ int dx77_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int retval; int settings; char modebuf[BUFSZ]; retval = current_data_read(rig, modebuf); if (retval != RIG_OK) { return retval; } /* FIXME: CWL&CWU: what are they? CW & CWR? */ switch (modebuf[3]) { case MD_CWL: case MD_CWU: *mode = RIG_MODE_CW; break; case MD_USB: *mode = RIG_MODE_USB; break; case MD_LSB: *mode = RIG_MODE_LSB; break; case MD_AM: *mode = RIG_MODE_AM; break; case MD_FM: *mode = RIG_MODE_FM; break; default: rig_debug(RIG_DEBUG_ERR, "dx77_get_mode: unknown mode %c%c\n", modebuf[2], modebuf[3]); return -RIG_EINVAL; } modebuf[2] = '\0'; settings = strtol(modebuf, (char **)NULL, 16); /* * TODO: please DX77 owners, check this, I'm not sure * which passband is default! */ if (settings & 0x02) { *width = rig_passband_narrow(rig, *mode); } else { *width = rig_passband_normal(rig, *mode); } return RIG_OK; } /* * dx77_set_split * Assumes rig!=NULL */ int dx77_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { char cmdbuf[BUFSZ]; SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SPLT "%d" EOM, split == RIG_SPLIT_ON ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * dx77_get_split * Assumes rig!=NULL, split!=NULL */ int dx77_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int splt_len, retval; char spltbuf[BUFSZ]; retval = dx77_transaction(rig, AL CMD_RSPLT EOM, strlen(AL CMD_RSPLT EOM), spltbuf, &splt_len); if (retval != RIG_OK) { return retval; } if (splt_len != 2) { rig_debug(RIG_DEBUG_ERR, "dx77_get_split: wrong answer %s, len=%d\n", spltbuf, splt_len); return -RIG_ERJCTED; } spltbuf[splt_len] = '\0'; if (!strcmp(spltbuf, "OF")) { *split = RIG_SPLIT_OFF; } else if (!strcmp(spltbuf, "ON")) { *split = RIG_SPLIT_ON; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_split: unsupported SPLIT %s\n", spltbuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_set_split_freq * Assumes rig!=NULL */ int dx77_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { char freqbuf[BUFSZ]; int retval; /* max 10 digits */ if (tx_freq >= GHz(10)) { return -RIG_EINVAL; } /* at least 6 digits */ SNPRINTF(freqbuf, sizeof(freqbuf), AL CMD_TXFREQ "%06"PRIll EOM, (int64_t)tx_freq); retval = dx77_transaction(rig, freqbuf, strlen(freqbuf), NULL, NULL); return retval; } /* * dx77_get_split_freq * Assumes rig!=NULL, rx_freq!=NULL, tx_freq!=NULL */ int dx77_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int retval; char freqbuf[BUFSZ]; retval = current_data_read(rig, freqbuf); if (retval != RIG_OK) { return retval; } /* extract TX freq first, as RX kills freqbuf[16] */ freqbuf[26] = '\0'; sscanf(freqbuf + 16, "%"SCNfreq, tx_freq); return RIG_OK; } /* * dx77_get_rit * Assumes rig!=NULL, split!=NULL */ int dx77_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int rit_len, retval; char ritbuf[BUFSZ]; /* read in Hertz unit */ retval = dx77_transaction(rig, AL CMD_RIT "0" EOM, strlen(AL CMD_RIT "0" EOM), ritbuf, &rit_len); if (retval != RIG_OK) { return retval; } if (rit_len != 8) /* || (ritbuf[0] != '+' && ritbuf[0] != '-')) { */ { rig_debug(RIG_DEBUG_ERR, "dx77_get_rit: wrong answer %s, len=%d\n", ritbuf, rit_len); return -RIG_ERJCTED; } ritbuf[rit_len] = '\0'; ritbuf[0] = ' '; ritbuf[1] = ' '; ritbuf[2] = ' '; *rit = atoi(ritbuf); return RIG_OK; } /* * dx77_set_func * Assumes rig!=NULL */ int dx77_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_TONE: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_CTCSS "%02d" EOM, status ? 51 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_FAGC: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_AGC "%02d" EOM, status ? 1 : 2); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_NB: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_NB "%d" EOM, status ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_COMP: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "C%d" EOM, status ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_FUNC_MON: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_MON "%d" EOM, status ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_get_func * Assumes rig!=NULL, status!=NULL */ int dx77_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int retval; int settings; char funcbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (func) { case RIG_FUNC_TONE: retval = current_data_read(rig, funcbuf); if (retval != RIG_OK) { return retval; } funcbuf[2] = '\0'; settings = strtol(funcbuf, (char **)NULL, 16); *status = (settings & 0x08) ? 1 : 0; break; case RIG_FUNC_FAGC: retval = current_data_read(rig, funcbuf); if (retval != RIG_OK) { return retval; } funcbuf[2] = '\0'; settings = strtol(funcbuf, (char **)NULL, 16); *status = (settings & 0x01) ? 1 : 0; break; case RIG_FUNC_NB: retval = current_data_read(rig, funcbuf); if (retval != RIG_OK) { return retval; } funcbuf[2] = '\0'; settings = strtol(funcbuf, (char **)NULL, 16); *status = (settings & 0x04) ? 1 : 0; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_func %d\n", (int)func); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_set_level * Assumes rig!=NULL * FIXME: cannot support PREAMP and ATT both at same time (make sense though) */ int dx77_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int lvl; char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_PREAMP: switch (val.i) { case 0: lvl = 0; break; case 10: lvl = 1; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported Preamp %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_RFGAIN "%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_ATT: switch (val.i) { case 0: lvl = 0; break; case 10: lvl = 11; break; case 20: lvl = 10; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported Att %d\n", val.i); return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_RFGAIN "%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_RFPOWER: SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_PWR "%1d" EOM, val.f < 0.5 ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_KEYSPD: if (val.i < 6) { lvl = 31; } else if (val.i < 20) { lvl = val.i + 25; } else if (val.i <= 50) { lvl = val.i - 20; } else { lvl = 30; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "P%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_LEVEL_CWPITCH: lvl = 4; if (val.i < 426) { lvl = 5; } else if (val.i >= 426 && val.i <= 475) { lvl = 6; } else if (val.i >= 476 && val.i <= 525) { lvl = 7; } else if (val.i >= 526 && val.i <= 575) { lvl = 8; } else if (val.i >= 576 && val.i <= 625) { lvl = 9; } else if (val.i >= 626 && val.i <= 675) { lvl = 10; } else if (val.i >= 676 && val.i <= 725) { lvl = 11; } else if (val.i >= 726 && val.i <= 775) { lvl = 12; } else if (val.i >= 776 && val.i <= 825) { lvl = 0; } else if (val.i >= 826 && val.i <= 875) { lvl = 1; } else if (val.i >= 876 && val.i <= 925) { lvl = 2; } else if (val.i >= 926 && val.i <= 975) { lvl = 3; } else if (val.i >= 976 && val.i <= 1025) { lvl = 4; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "M%02d" EOM, lvl); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_get_level * Assumes rig!=NULL, val!=NULL */ int dx77_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int retval, lvl_len; char lvlbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (level) { case RIG_LEVEL_RAWSTR: /* read A/D converted value */ retval = dx77_transaction(rig, AL CMD_SMETER "1" EOM, strlen(AL CMD_SMETER "1" EOM), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 6) { rig_debug(RIG_DEBUG_ERR, "dx77_get_level: wrong answer len=%d\n", lvl_len); return -RIG_ERJCTED; } lvlbuf[6] = '\0'; val->i = atoi(lvlbuf + 3); break; case RIG_LEVEL_PREAMP: retval = current_data_read(rig, lvlbuf); if (retval != RIG_OK) { return retval; } switch (lvlbuf[5]) { case '2': case '3': case '0': val->i = 0; break; case '1': val->i = 10; break; default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %c%c\n", lvlbuf[4], lvlbuf[5]); } break; case RIG_LEVEL_ATT: retval = current_data_read(rig, lvlbuf); if (retval != RIG_OK) { return retval; } switch (lvlbuf[5]) { case '1': case '0': val->i = 0; break; case '2': val->i = 20; break; case '3': val->i = 10; break; default: rig_debug(RIG_DEBUG_ERR, "Unknown RF Gain %c%c\n", lvlbuf[4], lvlbuf[5]); } break; case RIG_LEVEL_RFPOWER: retval = dx77_transaction(rig, AL CMD_RPOWER EOM, strlen(AL CMD_RPOWER EOM), lvlbuf, &lvl_len); if (retval != RIG_OK) { return retval; } if (lvl_len != 1) { rig_debug(RIG_DEBUG_ERR, "dx77_get_level: wrong answer len=%d\n", lvl_len); return -RIG_ERJCTED; } /* H or L */ val->f = lvlbuf[0] == 'H' ? 1.0 : 0.0; break; default: rig_debug(RIG_DEBUG_ERR, "Unsupported get_level %s\n", rig_strlevel(level)); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_set_parm */ int dx77_set_parm(RIG *rig, setting_t parm, value_t val) { char cmdbuf[BUFSZ]; /* Optimize: * sort the switch cases with the most frequent first */ switch (parm) { case RIG_PARM_BEEP: rig_debug(RIG_DEBUG_ERR, "val is %d\n", val.i); SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "A%d" EOM, val.i ? 1 : 0); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); case RIG_PARM_BACKLIGHT: rig_debug(RIG_DEBUG_ERR, "val is %0f\n", val.f); SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_SDATA "O%d" EOM, (int)(val.f * 5)); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); default: rig_debug(RIG_DEBUG_ERR, "Unsupported set_parm %d\n", (int)parm); return -RIG_EINVAL; } return RIG_OK; } /* * dx77_set_ctcss_tone * Assumes rig!=NULL, rig->caps->ctcss_list != NULL */ int dx77_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { struct rig_caps *caps; unsigned char tonebuf[BUFSZ]; int i; caps = rig->caps; for (i = 0; caps->ctcss_list[i] != 0; i++) { if (caps->ctcss_list[i] == tone) { break; } } if (caps->ctcss_list[i] != tone) { return -RIG_EINVAL; } SNPRINTF((char *) tonebuf, sizeof(tonebuf), AL CMD_CTCSS "%02d" EOM, i + 1); return dx77_transaction(rig, (char *) tonebuf, strlen((char *)tonebuf), NULL, NULL); } /* * dx77_get_ptt * Assumes rig!=NULL, ptt!=NULL */ int dx77_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { char pttbuf[BUFSZ]; int ptt_len, retval; retval = dx77_transaction(rig, AL CMD_PTT EOM, strlen(AL CMD_PTT EOM), pttbuf, &ptt_len); if (retval != RIG_OK) { return retval; } if (ptt_len != 3 && ptt_len != 4) { rig_debug(RIG_DEBUG_ERR, "dx77_get_ptt: wrong answer %s, len=%d\n", pttbuf, ptt_len); return -RIG_ERJCTED; } pttbuf[ptt_len] = '\0'; if (!strcmp(pttbuf, "SEND")) { *ptt = RIG_PTT_OFF; } else if (!strcmp(pttbuf, "REV")) { *ptt = RIG_PTT_ON; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_ptt: unknown PTT %s\n", pttbuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_get_dcd * Assumes rig!=NULL, dcd!=NULL */ int dx77_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { char dcdbuf[BUFSZ]; int dcd_len, retval; retval = dx77_transaction(rig, AL CMD_SQL EOM, strlen(AL CMD_SQL EOM), dcdbuf, &dcd_len); if (retval != RIG_OK) { return retval; } if (dcd_len != 4 && dcd_len != 5) { rig_debug(RIG_DEBUG_ERR, "dx77_get_dcd: wrong answer %s, len=%d\n", dcdbuf, dcd_len); return -RIG_ERJCTED; } dcdbuf[dcd_len] = '\0'; if (!strcmp(dcdbuf, "OPEN")) { *dcd = RIG_DCD_ON; } else if (!strcmp(dcdbuf, "CLOSE")) { *dcd = RIG_DCD_OFF; } else { rig_debug(RIG_DEBUG_ERR, "dx77_get_dcd: unknown SQL %s\n", dcdbuf); return -RIG_EPROTO; } return RIG_OK; } /* * dx77_set_mem * Assumes rig!=NULL * FIXME: check we're in memory mode first */ int dx77_set_mem(RIG *rig, vfo_t vfo, int ch) { char cmdbuf[BUFSZ]; if (ch < 0 || ch > 99) { return -RIG_EINVAL; } SNPRINTF(cmdbuf, sizeof(cmdbuf), AL CMD_MCALL "%02d" EOM, ch); return dx77_transaction(rig, cmdbuf, strlen(cmdbuf), NULL, NULL); } /* * dx77_get_mem * Assumes rig!=NULL, !vfo */ int dx77_get_mem(RIG *rig, vfo_t vfo, int *ch) { char membuf[BUFSZ]; int mem_len, retval; retval = dx77_transaction(rig, AL CMD_RMEM EOM, strlen(AL CMD_RMEM EOM), membuf, &mem_len); if (retval != RIG_OK) { return retval; } if (mem_len != 2) { rig_debug(RIG_DEBUG_ERR, "dx77_get_mem: wrong answer %s, len=%d\n", membuf, mem_len); return -RIG_ERJCTED; } membuf[mem_len] = '\0'; *ch = atoi(membuf); if (*ch < 0 || *ch > 99) { rig_debug(RIG_DEBUG_ERR, "dx77_get_mem: unknown mem %s\n", membuf); return -RIG_EPROTO; } return RIG_OK; } hamlib-4.6.2/README.md0000644000175000017500000001520014752216205011161 00000000000000Hamlib - (C) Frank Singleton 2000 (vk3fcs@ix.netcom.com) (C) Stephane Fillod 2000-2011 (C) The Hamlib Group 2000-2022 The purpose of this project is to provide stable, flexible, shared libraries that enable quicker development of Amateur Radio Equipment Control Applications. The master repository is https://github.com/Hamlib/Hamlib Daily snapshots are available at https://n0nb.users.sourceforge.net/ Development happens on the github master (often by merging feature branches) and each release has a release branch. Many Amateur Radio Transceivers come with serial interfaces that allows software to control the radio. This project will endeavour to provide shared libraries that greatly simplify the application programmer's interaction with radio equipment and other controllable devices such as rotators, switches, etc. Supported Radios ---------------- The Hamlib Wiki page, Supported Radios, contains a snapshot of the supported radios at the time of the last Hamlib release. Go to http://www.hamlib.org to reach the Wiki. Hamlib Design ------------- The library provides functions for both radio and rotator control, and data retrieval from the radio or rotator. A number of functions useful for calculating distance and bearing and grid square conversion are included. libhamlib.so - library that provides generic API for all RIG types. This is what Application programmers will "see". Will have different names on other platforms, e.g. libhamlib-2.dll on MS windows. Also contains all radio and rotator "backends" (formerly in their own dlopen'ed libraries) provided by Hamlib. Backend Examples are: --------------------- 1. yaesu will provide connectivity to Yaesu FT 747GX Transceiver, FT 847 "Earth Station", etc. via a standard API. 2. xxxx. will provide connectivity to the Wiz-bang moon-melter 101A (yikes..) Hamlib will also enable developers to develop professional looking GUI's towards a standard control library API, and they would not have to worry about the underlying connection towards physical hardware. Initially serial (RS232) connectivity will be handled, but we expect that IP (and other) connectivity will follow afterwards. Connection via a USB port is accomplished via the Linux kernel support. USB to serial converters are well supported. Other such devices may be supported as long as they present a serial (RS-232) interface to Hamlib. Availability ------------ Most distributions have the latest Hamlib release in their testing or alpha versions of their distribution. Check your package manager for the Hamlib version included in your distribution. Developing with Hamlib API -------------------------- API documentation is at: https://github.com/Hamlib/Hamlib/wiki/Documentation Take a look at tests/README for more info on simple programming examples and test programs. C++ programming is supported and language bindings are available for Perl, Python, and TCL. A network daemon utility is also available for any programming language that supports network sockets (even netcat!). Recompiling ----------- Hamlib is entirely developed using GNU tools, under various Linux systems. The library may be recompiled by the familiar "three step": Note: if ./configure does not exist run ./bootstrap first ./configure make sudo make install For debugging use this configure ./configure CFLAGS=-g -O0 -fPIC --no-create --no-recursio See the INSTALL file for more information. Contributing ------------ Consult the README.betatester and README.developer files in this directory if you feel like testing or helping with Hamlib development. Contributions of rig specifications and protocol documentation are highly encouraged. Do keep in mind that in some cases the manufacturer may not provide complete control information or it is only available under a Non-Disclosure Agreement (NDA). Any documentation *must* be publicly available so we can legally write and distribute Free Software supporting a given device. The Hamlib team is very interested to hear from you, how Hamlib builds and works on your system, especially on non-Linux system or non-PC systems. We try to make Hamlib as portable as possible. Please report in case of problems at hamlib-developer@lists.sourceforge.net Git email formatted patches or in unified diff format are welcome! Also, take a look at http://sourceforge.net/projects/hamlib/ Here you will find a mail list, link to the Wiki, and the latest releases. Feedback, questions, etc. about Hamlib are very welcome at the mail list: Hamlib Version Numbers ---------------------- Like other software projects, Hamlib uses a version numbering scheme to help program authors and users understand which releases are compatible and which are not. Hamlib releases now follow the format of: Major.minor.incremental Where Major: Currently at 4, but can be advanced when changes to the API require client programs to be rewritten to take advantage of new features of Hamlib. This number has advanced a couple of times throughout the life of Hamlib. Advancement of the major number is only for frontend API changes that require modification of client source. ABI compatibility is presently maintained to prior releases so that a program linked to an earlier 1.2.Y.[Z] release will work with a later 3.Y[.Z] release without recompiling. It is our intention to maintain such ABI compatibility as long as practical. Minor: This number advances when either new backend(s) or new rig model(s) to existing backend(s) are added. Advancing this number informs client program authors (and users of those programs) that new model/backend support has been added. Will also include bug fixes since the last Incremental release. Incremental: May be undefined (e.g. Hamlib 3.0) and would advance to 1 (e.g. Hamlib 3.0.1) for any bug fixes or feature additions to existing model(s) or backend(s), then to 2, etc. New rig models or backends are not included in Incremental. When Release is advanced, Incremental will reset to undefined and will not be included as part of the version number. Release schedule ---------------- Hamlib has in the past maintained a "ready when it's ready" philosophy. However, given that much of the Linux user base is now influenced by the Ubuntu distribution and its timed six month release schedule, Hamlib releases will be scheduled in advance of Ubuntu releases. Planned release dates for Hamlib are now 1 February and 1 August of each calendar year. Between those dates various Incremental releases will occur as development warrants. Have Fun / Frank S / Stephane F / The Hamlib Group 73's de vk3fcs/km5ws / f8cfe hamlib-4.6.2/COPYING0000644000175000017500000004325414752216205010747 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. hamlib-4.6.2/Makefile.in0000644000175000017500000010362014752216215011754 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = hamlib.pc CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(aclocaldir)" "$(DESTDIR)$(docdir)" \ "$(DESTDIR)$(pkgconfigdir)" DATA = $(aclocal_DATA) $(doc_DATA) $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/hamlib.pc.in \ $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \ $(top_srcdir)/build-aux/config.guess \ $(top_srcdir)/build-aux/config.sub \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing \ $(top_srcdir)/include/hamlib/config.h.in AUTHORS COPYING \ COPYING.LIB ChangeLog INSTALL NEWS README THANKS \ build-aux/ar-lib build-aux/compile build-aux/config.guess \ build-aux/config.sub build-aux/install-sh build-aux/ltmain.sh \ build-aux/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = -D_TIME_BITS=64 -Winitializer-overrides AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ aclocaldir = $(datadir)/aclocal aclocal_DATA = hamlib.m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = hamlib.pc EXTRA_DIST = PLAN LICENSE hamlib.m4 hamlib.pc.in README.md README.developer \ README.betatester README.freqranges README.multicast README.osx \ Android.mk doc_DATA = ChangeLog COPYING COPYING.LIB LICENSE \ README.md README.betatester README.developer SUBDIRS = macros include lib security \ $(BACKEND_LIST) \ $(RIG_BACKEND_LIST) \ $(ROT_BACKEND_LIST) \ $(AMP_BACKEND_LIST) \ security \ src \ $(BINDINGS) \ tests doc DIST_SUBDIRS = macros include lib src c++ bindings tests doc android scripts rotators/indi simulators\ security $(BACKEND_LIST) $(RIG_BACKEND_LIST) $(ROT_BACKEND_LIST) $(AMP_BACKEND_LIST) # Install any third party macros into our tree for distribution ACLOCAL_AMFLAGS = -I macros --install all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): include/hamlib/config.h: include/hamlib/stamp-h1 @test -f $@ || rm -f include/hamlib/stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) include/hamlib/stamp-h1 include/hamlib/stamp-h1: $(top_srcdir)/include/hamlib/config.h.in $(top_builddir)/config.status @rm -f include/hamlib/stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status include/hamlib/config.h $(top_srcdir)/include/hamlib/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f include/hamlib/stamp-h1 touch $@ distclean-hdr: -rm -f include/hamlib/config.h include/hamlib/stamp-h1 hamlib.pc: $(top_builddir)/config.status $(srcdir)/hamlib.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt install-aclocalDATA: $(aclocal_DATA) @$(NORMAL_INSTALL) @list='$(aclocal_DATA)'; test -n "$(aclocaldir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(aclocaldir)'"; \ $(MKDIR_P) "$(DESTDIR)$(aclocaldir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(aclocaldir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(aclocaldir)" || exit $$?; \ done uninstall-aclocalDATA: @$(NORMAL_UNINSTALL) @list='$(aclocal_DATA)'; test -n "$(aclocaldir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(aclocaldir)'; $(am__uninstall_files_from_dir) install-docDATA: $(doc_DATA) @$(NORMAL_INSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-docDATA: @$(NORMAL_UNINSTALL) @list='$(doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(aclocaldir)" "$(DESTDIR)$(docdir)" "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-aclocalDATA install-docDATA \ install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-aclocalDATA uninstall-docDATA \ uninstall-pkgconfigDATA .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip dist-zstd distcheck distclean \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-aclocalDATA \ install-am install-data install-data-am install-docDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-pkgconfigDATA \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-aclocalDATA uninstall-am uninstall-docDATA \ uninstall-pkgconfigDATA .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/simulators/0000755000175000017500000000000014752216241012166 500000000000000hamlib-4.6.2/simulators/simatd578.c0000644000175000017500000000726014752216205014004 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simatd578 simatd578.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int ptt = 0; int curr_vfo = 0; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); // seems the anytone only gives 8-byte commands and 1-byte responses do { int bytes = read(fd, &c, 1); if (bytes > 0) { buf[i++] = c; } n++; } while (c != 0x0a); printf("n=%d \n", n); for (i = 0; i < n; ++i) { printf("%02x ", buf[i]); } printf("\n"); return n; } #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[]) { unsigned char buf[256], buf2[256]; int n; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 8) { printf("Not 8 bytes? bytes=%d\n", bytes); } switch (buf[0]) { case 0x41: if (buf[4] == 0x00) // set ptt { if (buf[1] == 1) { ptt = 1; printf("PTT ON\n"); } else { ptt = 0; printf("PTT OFF\n"); } buf[0] = 0x06; n = write(fd, buf, 1); } if (buf[4] == 0x20) // get vfo { printf("Get VFO curr_vfo=%d\n", curr_vfo); if (curr_vfo == 1) { curr_vfo = 0; } else { curr_vfo = 1; } printf("Get VFO curr_vfo=%d\n", curr_vfo); buf2[0] = 0xaa; buf2[1] = 0x53; buf2[2] = 0x00; buf2[3] = 0x00; buf2[4] = 0x00; buf2[5] = 0x01; buf2[6] = 0x01; buf2[7] = 0x00; buf2[8] = curr_vfo; buf2[9] = 0x00; buf2[10] = 0x10; buf2[11] = 0x00; buf2[12] = 0x00; buf2[13] = 0x00; buf2[14] = 0x00; buf2[15] = 0x00; buf2[16] = 0x06; n = write(fd, buf2, 17); } break; case 0x06: buf[0] = 0x06; n = write(fd, buf, 1); break; default: printf("Unknown cmd=%02x\n", buf[0]); continue; } printf("%d bytes returned\n", n); } return 0; } hamlib-4.6.2/simulators/simts890.c0000644000175000017500000013536514752216205013667 00000000000000//#define TRACE /* Full traffic trace if enabled */ // can run this using rigctl/rigctld and socat pty devices // gcc -o simts890 -l hamlib simts890.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include "config.h" #include #include #include #include #include #include #include #include //#include /* Definitions */ /* The TS-890S has some undocumented commands, left over from older * Kenwood models. They have newer counterparts with more functionality, * but are still around for legacy software. If you want to see if your * app is only using the latest-and-greatest, comment out the next define. */ #define LEGACY // Size of command buffer #define BUFSIZE 256 // Number of selectable bands #define NBANDS 11 /* Type we're emulating - K=The Americas(default), E=Europe */ #if !defined(TYPE) #define TYPE K #endif /* Define a macro for sending response back to the app * This will allow us to reroute output to a buffering routine * Needed to handle multiple commands in a single message * Also makes it easy to trace */ #if defined(TRACE) #define OUTPUT(s) {printf("Resp:\"%s\"\n", s); write(fd, s, strlen(s)); } #else #define OUTPUT(s) write(fd, s, strlen(s)) #endif int mysleep = 20; int filternum1 = 7; int filternum2 = 8; int ptt, ptt_data, ptt_mic, ptt_tune; int keyspd = 20; int sl = 3, sh = 3; int nr = 0; int pa = 0; int pc = 25; int sm = 35; int nt = 0; int ag = 100; int ac = 0; int nb[2] = {0, 0}; // NB1/NB2 OFF/ON int sq = 0; int rg = 0; int mg = 0; int ra = 0; int rl = 0; int is = 0; int sp = 0; // Split OFF/ON int split_op = 0; // Split frequency setting operation in progress int rit = 0, xit = 0, rxit = 0; // RIT off/on, XIT off/on, Offset freq(-9999<=rxit<=+9999) int fine = 0; // Fine tuning - step size off=10hz, on=1hz // Clock data int autoset = 1; int tzs[2] = {36, 56}; // 0=primary(EST), 1=auxiliary(UTC) char auxtzc = 'U'; // Auxiliary clock identifier (UTC) // Antenna connections char antnum = '1', recant = '0', driveout = '0', antout = '0'; // Multiple meter functions struct meter_data { int enabled; int value; // # of pips lit, range 0-70 }; struct meter_data meter[6] = { { 0, 5}, // ALC { 0, 1}, // SWR { 0, 10}, // COMP { 0, 30}, // ID (amps) { 0, 60}, // Vd (Volts) { 0, 20} // Temp (Unknown units) }; int tfset = 0; typedef struct kvfo { int freq; int mode; short band, vfo; // Redundant, but useful for relative movement } *kvfop_t; int nummems = 3; // Default - values = 1, 3, 5 int bandslot[2][NBANDS]; // 0-based band memory: ((bandslot[i] + 1) % nummems) (+1 for display) /* Storage and default data for band memories * vfoA freq and mode initialized here, vfoB and other items set at startup * 1, 3(default), or 5 memories per band can be used. One is always active on * each band. Manually they are selected by multiple band button pushes; CAT * selection is by BD/BU command */ struct kvfo band_mem[2][NBANDS][5] = { { #if TYPE==K /* 160M */ { { 1800000, 3}, { 1810000, 3}, { 1820000, 3}, { 1830000, 3}, { 1840000, 3} }, /* 80M */ { { 3500000, 1}, { 3600000, 1}, { 3700000, 1}, { 3800000, 1}, { 3900000, 1} }, /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, /* 30M */ { {10100000, 3}, {10110000, 3}, {10120000, 3}, {10130000, 3}, {10140000, 3} }, /* 20M */ { {14000000, 2}, {14100000, 2}, {14150000, 2}, {14200000, 2}, {14250000, 2} }, /* 17M */ { {18068000, 2}, {18100000, 2}, {18110000, 2}, {18150000, 2}, {18160000, 2} }, /* 15M */ { {21000000, 2}, {21100000, 2}, {21150000, 2}, {21200000, 2}, {21300000, 2} }, /* 12M */ { {24890000, 2}, {24920000, 2}, {24940000, 2}, {24960000, 2}, {24980000, 2} }, /* 10M */ { {28000000, 2}, {28300000, 2}, {28500000, 2}, {29000000, 4}, {29300000, 4} }, /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, /* GENE */ { { 135700, 3}, { 472000, 3}, { 1000000, 5}, { 5305500, 2}, { 5403500, 2} } #else // TYPE==E /* 160M */ { { 1830000, 3}, { 1840000, 3}, { 1850000, 3}, { 1810000, 3}, { 1820000, 3} }, /* 80M */ { { 3500000, 1}, { 3550000, 1}, { 3600000, 1}, { 3650000, 1}, { 3700000, 1} }, /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, /* 30M */ { {10100000, 3}, {10110000, 3}, {10120000, 3}, {10130000, 3}, {10140000, 3} }, /* 20M */ { {14000000, 2}, {14100000, 2}, {14150000, 2}, {14200000, 2}, {14250000, 2} }, /* 17M */ { {18068000, 2}, {18100000, 2}, {18110000, 2}, {18150000, 2}, {18160000, 2} }, /* 15M */ { {21000000, 2}, {21100000, 2}, {21150000, 2}, {21200000, 2}, {21300000, 2} }, /* 12M */ { {24890000, 2}, {24920000, 2}, {24940000, 2}, {24960000, 2}, {24980000, 2} }, /* 10M */ { {28000000, 2}, {28300000, 2}, {28500000, 2}, {29000000, 4}, {29300000, 4} }, /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, /* GENE */ { {70100000, 2}, { 135700, 3}, { 472000, 5}, { 999000, 5}, { 5258500, 2} } #endif } }; /* Band definitions * differ by model */ struct band_def { int low; int high; }; const struct band_def band_limits[NBANDS] = { #if TYPE == K { 1800000, 2000000}, { 3500000, 4000000}, { 7000000, 7300000}, {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, {21000000, 21450000}, {24890000, 24990000}, {28000000, 29700000}, {50000000, 54000000}, { 30000, 60000000} #else { 1810000, 2000000}, { 3500000, 3800000}, { 7000000, 7200000}, {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, {21000000, 21450000}, {24890000, 24990000}, {28000000, 29700000}, {50000000, 52000000}, { 30000, 74800000} #endif }; /* Table for mode<->emission class conversion * Claas 0 = SSB * 1 = CW/FSK/PSK * 2 = FM * 3 = AM */ const int mode2classtab[16] = { -1, 0, 0, 1, 2, 3, 1, 1, -1, 1, 1, 1, 0, 0, 2, 3}; const int stepvalues[4][10] = // Step sizes in Hz { /* SSB */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, /* CW/FSK/PSK */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, /* FM */ { 5000, 6250, 10000, 12500, 15000, 20000, 25000, 30000, 50000, 100000}, /* AM */ { 5000, 6250, 10000, 12500, 15000, 20000, 25000, 30000, 50000, 100000} }; int stepsize[4] = { 1000, 500, 10000, 5000}; // Defaults by modeclass /* Function prototypes */ int freq2band(int freq); kvfop_t newvfo(kvfop_t ovfo, int band); void swapvfos(kvfop_t *vfoset[]); // Extracted from rig.h int hl_usleep(unsigned long usec); // Until it's replaced #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 getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); int retval; while ((retval = read(fd, &c, 1)) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (retval != 0) { perror("read failed:"); close(fd); fd = openPort(""); } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); int cmd_err = 0; char *err_txt[] = { "?;", "E;", "O;" }; struct kvfo *vfoA = &band_mem[0][4][0], *vfoB = &band_mem[1][6][0]; kvfop_t *const vfoAB[2] = {&vfoA, &vfoB}; // 0=A, 1=B, fixed kvfop_t *vfoLR[2] = {&vfoA, &vfoB}; // 0=Left, 1=Right, can change #if defined(LEGACY) /* The IF command is not documented for the TS-890S, and is supposed * to be supplanted by SF. However, it is still there for legacy S/W. * This description is taken from the TS-590S/SG manual, with values * reflecting a real TS-890S. */ const char IFformat[] = "IF" // Output only "%011d" // P1 freq(Hz) " " // P2 ?? "% 05d" // P3 RIT/XIT freq(Hz) "%1d" // P4 RIT on/off "%1d" // P5 XIT on/off "000" // P6,P7 mem channel "%1d" // P8 RX/TX "%1X" // P9 Operating mode (See OM command) "0" // P10 Function? "0" // P11 Scan status? "%1d" // P12 Simplex=0/Split=1 "0" // P13 Tone/CTCSS (not on TS-890S) "00" // P14 Tone/CTCSS freq (not on TS-890S) "0;"; // P15 Always zero #endif const char SFformat[] = "SF" // Input/Output "%1d" // P1 VFOA/VFOB "%011d" // P2 Freq(Hz) "%1X;"; // P3 Mode /* Initialization */ for (int i = 0; i < NBANDS; i++) { for (int j = 0; j < 5; j++) { band_mem[1][i][j] = band_mem[0][i][j]; band_mem[1][i][j].vfo = 1; band_mem[0][i][j].band = band_mem[1][i][j].band = i; } } while (1) { hl_usleep(10); buf[0] = 0; /* Clean up from last continue - pass along any errors found */ if (cmd_err != 0) { OUTPUT(err_txt[cmd_err - 1]); cmd_err = 0; } if (getmyline(fd, buf) > 0) { #if defined(TRACE) printf("Cmd:\"%s\"\n", buf); #endif } // else { return 0; } buf[0] = toupper(buf[0]); buf[1] = toupper(buf[1]); if (strcmp(buf, "IF;") == 0) { // Reads the transceiver status #if defined(LEGACY) char ifbuf[256]; hl_usleep(mysleep * 1000); sprintf(ifbuf, IFformat, (*vfoLR[0])->freq, rxit, rit, xit, (ptt + ptt_mic + ptt_data + ptt_tune) > 0 ? 1 : 0, (*vfoLR[0])->mode, sp); OUTPUT(ifbuf); #else cmd_err = 1; #endif } else if (strncmp(buf, "AN", 2) == 0) { // Antenna connection handling hl_usleep(mysleep * 1000); if (buf[2] == ';') { buf[2] = antnum; buf[3] = recant; buf[4] = driveout; buf[5] = antout; buf[6] = ';'; buf[7] = '\0'; OUTPUT(buf); } else { if (buf[2] != '9') { antnum = buf[2]; } if (buf[3] != '9') { recant = buf[3]; } if (buf[4] != '9') { driveout = buf[4]; } if (buf[5] != '9') { antout = buf[5]; } } } else if (strncmp(buf, "NB", 2) == 0) { // Noise Blanker settings int idx; switch (toupper(buf[2])) { case '1': // Noise Blanker 1 case '2': // Noise Blanker 2 idx = buf[2] - '1'; if (buf[3] == ';') { // Read hl_usleep(mysleep * 20); sprintf(buf, "NB%d%d;", idx + 1, nb[idx]); OUTPUT(buf); } else { // Set nb[idx] = buf[3] - '0'; } break; case 'D': // Noise Blanker 2, type B Depth case 'T': // Noise Blanker 2 Type case 'W': // Noise Blanker 2, type B Width break; default: cmd_err = 1; } } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 200); sprintf(buf, "RA%d;", ra); OUTPUT(buf); } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d", &ra); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 000); pbuf = "RG255;"; OUTPUT(pbuf); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; OUTPUT(pbuf); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; OUTPUT(pbuf); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.05;"; OUTPUT(pbuf); } else if (strncmp(buf, "IS;", 3) == 0) { snprintf(buf, sizeof(buf), "IS%+04d;", is); OUTPUT(buf); } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS%d", &is); } else if (strncmp(buf, "SM;", 3) == 0) { pbuf = "SM0035;"; OUTPUT(pbuf); } else if (strncmp(buf, "PC;", 3) == 0) { snprintf(buf, sizeof(buf), "PC%03d;", pc); OUTPUT(buf); } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "ID;") == 0) { hl_usleep(mysleep * 1000); int id = 24; snprintf(buf, sizeof(buf), "ID%03d;", id); OUTPUT(buf); } else if (strncmp(buf, "EX", 2) == 0) { // Menu Setting if (strcmp(buf + 2, "00011;") == 0) { // S-Meter Scale pbuf = "EX00011 001;"; OUTPUT(pbuf); } else if (strncmp(buf + 2, "00311", 5) == 0) { // Number of Band Memories if (buf[7] == ';') { snprintf(buf, sizeof buf, "EX00311 %03d;", nummems / 2); // Rounds down OUTPUT(buf); } else { int temp = -1; sscanf(buf + 8, "%3d", &temp); if (temp <= 2 && temp >= 0) { nummems = temp * 2 + 1; } else { cmd_err = 1; } } } else if (strncmp(buf + 2, "00301", 5) >= 0 && strncmp(buf + 2, "00304", 5) <= 0) { // [SSB|CW/FSK/PSK|FM|AM] Mode Frequency Step Size (Multi/Channel Control) int class = buf[6] - '1'; int i, tmpstep = -1; if (buf[7] == ';') { // Read for (i = 0; i < 10 && stepvalues[class][i] != 0; i++) { if (stepsize[class] == stepvalues[class][i]) { tmpstep = i; break; } } if (tmpstep < 0) {cmd_err = 3; continue;} // Shouldn't happen snprintf(buf + 7, sizeof(buf) - 7, " %03d;", tmpstep); OUTPUT(buf); } else { // Set tmpstep = atoi(buf + 8); if (tmpstep < 0 || tmpstep > 9 || stepvalues[class][tmpstep] == 0) {cmd_err = 1; continue;} stepsize[class] = stepvalues[class][tmpstep]; } } } else if (buf[0] == 'F' && (buf[1] == 'A' || buf[1] == 'B')) // FA/FB { // VFO {A|B} Frequency int idx = buf[1] - 'A'; if (buf[2] == ';') { snprintf(buf + 2, sizeof(buf) - 2, "%011d;", (*vfoAB[idx])->freq); OUTPUT(buf); } else { int tmpfreq, newband; kvfop_t ovfo, nvfo; sscanf(buf + 2, "%d", &tmpfreq); newband = freq2band(tmpfreq); if (newband < 0) {cmd_err = 1; continue; } ovfo = *vfoAB[idx]; nvfo = newvfo(ovfo, newband); nvfo->freq = tmpfreq; *vfoAB[idx] = nvfo; } } else if (strncmp(buf, "AI;", 3) == 0) { pbuf = "AI0;"; OUTPUT(pbuf); } else if (strncmp(buf, "PS;", 3) == 0) { snprintf(buf, sizeof(buf), "PS1;"); OUTPUT(buf); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { int tmpvfo = buf[2] - '0'; if (tmpvfo < 0 || tmpvfo > 1) { cmd_err = 1; continue; } snprintf(buf, sizeof(buf), SFformat, tmpvfo, (*vfoAB[tmpvfo])->freq, (*vfoAB[tmpvfo])->mode); //printf("SF buf=%s\n", buf); OUTPUT(buf); } else if (strncmp(buf, "SF", 2) == 0) { // Sets and Reads the VFO (Frequency and Mode) int tmpvfo, tmpfreq, tmpmode, newband; kvfop_t ovfo, nvfo; if (sscanf(buf, SFformat, &tmpvfo, &tmpfreq, &tmpmode) != 3 || tmpvfo < 0 || tmpvfo > 1) { printf("Error decoding SF:%s\n", buf); cmd_err = 1; continue; } //printf("tmpvfo=%d, tmpfreq=%d, tmpmode=%d\n", tmpvfo, tmpfreq, tmpmode); ovfo = *vfoAB[tmpvfo]; newband = freq2band(tmpfreq); if (newband < 0) {cmd_err = 1; continue; } nvfo = newvfo(ovfo, newband); nvfo->mode = tmpmode; nvfo->freq = tmpfreq; *vfoAB[tmpvfo] = nvfo; printf("modeA=%X, modeB=%X\n", vfoA->mode, vfoB->mode); } else if (strncmp(buf, "FR", 2) == 0) { // Receiver Function (VFO A / VFO B / Memory channel) int idx; if (buf[2] == ';') { // Read idx = sp && tfset; snprintf(buf, sizeof(buf), "FR%d;", (*vfoLR[idx])->vfo); OUTPUT(buf); } else { // Set idx = buf[2] - '0'; if (idx == 3) { //TODO: Memory channels are a long way off puts("Memory channels not implemented.\n"); cmd_err = 3; continue; } if (idx < 0 || idx > 1) {cmd_err = 1; continue; } sp = 0; // Turn off split if ((*vfoLR[0])->vfo != idx) // If the selected vfo is not the operational one { swapvfos(vfoLR); // Make it so } } } else if (strncmp(buf, "FT", 2) == 0) { // Transmitter Function ( VFO A / VFO B ) int idx; if (buf[2] == ';') { // Read idx = sp && !tfset; snprintf(buf, sizeof(buf), "FT%d;", (*vfoLR[idx])->vfo); OUTPUT(buf); } else { // Set idx = buf[2] - '0'; if (idx < 0 || idx > 1) {cmd_err = 1; continue; } sp = idx != (*vfoLR[0])->vfo; // Turn split on if vfos differ, else off } } else if (buf[0] == 'B' && (buf[1] == 'D' || buf[1] == 'U')) // BU/BD { // Frequency Band Selection(Setting 1)/[UP}/{DOWN] Operating(Setting 2) int band, idx, newfreq; int dir = buf[1] == 'D' ? -1 : +1; kvfop_t ovfo = *vfoLR[0]; // Current operating VFO if (buf[2] == ';') { // Setting 2 /* The TS-890S doesn't have a real BAND_UP/BAND_DOWN command * This one just does a simple UP/DOWN. As the manual says, just * like pushing the UP/DOWN button on the mic */ int class = mode2classtab[ovfo->mode]; if (class < 0 || class > 3) {cmd_err = 3; continue;} // Shouldn't happen newfreq = ovfo->freq + (dir * stepsize[class]); //TODO: Checking for band edges needs to go here ovfo->freq = newfreq; } else if (buf[3] == ';') { // Read idx = buf[2] - '0'; if (idx < 0 || idx > 1) {cmd_err = 1; continue;} snprintf(buf + 3, sizeof(buf) - 3, "%d;", bandslot[idx][ovfo->band] + 1); OUTPUT(buf); } else if (buf[5] == ';') { // Setting 1 band = atoi(buf + 3); if (band < 0 || band >= NBANDS) {cmd_err = 1; continue;} if (band == ovfo->band) { // Same band, cycle the band memory # bandslot[ovfo->vfo][band] = (bandslot[ovfo->vfo][band] + 1) % nummems; } *vfoLR[0] = newvfo(ovfo, band); } else { cmd_err = 1; } } else if ((strncmp(buf, "DN", 2) == 0) || (strncmp(buf, "UP", 2) == 0)) { // Microphone UP/DOWN Switch Operation int dir = buf[0] == 'D' ? -1 : +1; int steps = -1; kvfop_t ovfo = *vfoLR[0]; // Modify the current operational VFO if (buf[2] == ';') { steps = 1; } else if (buf[4] == ';') { steps = atoi(buf + 2); } if (steps < 0 || steps > 99) {cmd_err = 1; continue;} ovfo->freq += dir * steps * stepsize[mode2classtab[ovfo->mode]]; } else if (strncmp(buf, "FC", 2) == 0) { // Change the Frequency (Tuning Control) static const int fc_steps[6] = { 1, 2, 5, 10, 50, 100}; int dir = buf[2] == '0' ? +1 : -1; int stepidx = buf[3] - '0'; int delta; kvfop_t ovfo = *vfoLR[0]; if (stepidx < 0 || stepidx > 5) {cmd_err = 1; continue;} delta = dir * fc_steps[stepidx] * stepsize[mode2classtab[ovfo->mode]]; //TODO: This really needs a sanity check here ovfo->freq += delta; } else if (strncmp(buf, "UD", 2) == 0) { // VFO Frequency UP/DOWN int idx = buf[2] - '0'; int dir = buf[3] == '0' ? +1 : -1; int steps = -1; kvfop_t nvfo; if (idx < 0 || idx > 1 || tfset != 0) {cmd_err = 1; continue;} nvfo = *vfoAB[idx]; if (buf[4] == ';') { steps = 1; } else if (buf[6] == ';') { steps = atoi(buf + 4); } if (steps < 0 || steps > 99) {cmd_err = 1; continue; } nvfo->freq += dir * steps * stepsize[mode2classtab[nvfo->mode]]; } else if (strcmp(buf, "RX;") == 0) { // Receive Function State ptt = ptt_mic = ptt_data = ptt_tune = 0; } else if (strncmp(buf, "TX", 2) == 0) { // Transmission Mode ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) { case ';': case '0': ptt = ptt_mic = 1; break; case '1': ptt_data = 1; break; case '2': ptt_tune = 1; break; } } else if (strncmp(buf, "SP", 2) == 0) { // Split Operation Frequency Setting if (buf[2] == ';') { // Read snprintf(buf + 2, sizeof(buf) - 2, "%1d;", split_op); OUTPUT(buf); } else if (buf[3] == ';') { // Set 1 /* This section needs a lot of work, and a lot * of cooperation from other commands. * AFAICT the split freq can be set by spinning * the big knob, or by other means. When oper=0 * is sent, the current freq is used as the split * value. See page 5-1 of the IM, blinking SPLIT */ switch (buf[2]) { case '0': // Operation complete if (split_op) // If a split setup was in progress, { sp = 1; // split operation is enabled } //TODO: Set split freq VFO split_op = 0; break; case '1': // Start split frequency setup split_op = 1; break; case '2': // Cancel op split_op = 0; break; default: cmd_err = 1; } } else { // Set 2 int dir, split, spfreq, band; kvfop_t ovfo, svfo; sscanf(buf, "SP%1d%1d%1d", &sp, &dir, &split); dir = dir == 0 ? +1 : -1; split = dir * 1000 * split; // Convert kHz to +/- Hz ovfo = *vfoLR[0]; // Operational VFO spfreq = ovfo->freq + split; band = freq2band(spfreq); svfo = newvfo(*vfoLR[1], band); // Other VFO svfo->freq = spfreq; *vfoLR[1] = svfo; sp = 1; // Turn On Split } } else if (strncmp(buf, "TB;", 3) == 0) { // Split sprintf(buf, "TB%d;", sp); OUTPUT(buf); } else if (strncmp(buf, "TB", 2) == 0) { sscanf(buf, "TB%d", &sp); } else if (strncmp(buf, "TS", 2) == 0) { // TF-SET if (buf[2] == ';') { snprintf(buf, sizeof buf, "TS%d;", tfset); OUTPUT(buf); } else if (buf[2] >= '0' && buf[2] < '2') { if (sp && (tfset != buf[2] - '0')) { // Split is set and we're changing state of TF-SET swapvfos(vfoLR); // Reverse vfo functions } tfset = buf[2] - '0'; } else { cmd_err = 1; } } else if (strcmp(buf, "EC;") == 0) { // VFO A and VFO B Frequency Information Exchange /* No matter what the title says above, the TS-890S does not * have a frequency swap command. It does, however, have a VFO * function exchange - just by swapping the left and right displays. * This command is the same as the "A/B" button on the front panel. */ swapvfos(vfoLR); } else if (strcmp(buf, "VV;") == 0) { // VFO A to VFO B Copy ([A=B] Operation) /* Akin to the EC command above, this isn't really a "VFO A to VFO B" * copy, but an "Operational VFO to Secondary VFO" copy. It also * mimics the front panel [A=B] action. */ kvfop_t ovfo, svfo; ovfo = *vfoLR[0]; svfo = newvfo(*vfoLR[1], ovfo->band); // Get appropriate vfo for new freq svfo->freq = ovfo->freq; svfo->mode = ovfo->mode; *vfoLR[1] = svfo; } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); OUTPUT(buf); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "KY", 2) == 0) { // CW Keying if (buf[2] == ';') { // Checking status - we always have room OUTPUT("KY0;"); } else if (buf[3] == ';') { // Stop sending(?) if (buf[2] != '0') {cmd_err = 1; } } else { // Send the message //printf("CW mesg: %s\n", buf + 2); } } else if (strncmp(buf, "OM", 2) == 0) { // Operating Mode /* The TS-890S displays two frequencies and modes - left and right, * along with arrows that show which is VFO A and which is VFO B. * In almost all cases, the left VFO is the receive freq. The right * VFO is only used in split operation, as the transmit frequency. */ if (buf[3] == ';') { int tmpvfo = buf[2] - '0'; if (tmpvfo < 0 || tmpvfo > 1) { cmd_err = 1; } else { sprintf(buf, "OM%d%X;", tmpvfo, (*vfoLR[tmpvfo])->mode); OUTPUT(buf); } } else { /* Setting - Only sets the active function(RX/TX), * which is always the left VFO unless split is active and * we are transmitting. */ int idx = sp && ((ptt + ptt_mic + ptt_data + ptt_tune) > 0); sscanf(&buf[3], "%1X", &(*vfoLR[idx])->mode); } } else if (strncmp(buf, "MD", 2) == 0) { // Sets and reads the operating mode status #if defined(LEGACY) if (buf[2] == ';') { snprintf(buf, sizeof(buf), "MD%X;", (*vfoLR[0])->mode); OUTPUT(buf); } else { sscanf(buf, "MD%1X", &(*vfoLR[0])->mode); } #else cmd_err = 1; #endif } else if (strncmp(buf, "RM", 2) == 0) { // Meter if (buf[2] == ';') { // Read all enabled meters char tbuf[8]; buf[0] = '\0'; pbuf = buf; for (int i = 0; i < 6; i++) { if (meter[i].enabled) { snprintf(tbuf, sizeof tbuf, "RM%d%03d;", i + 1, meter[i].value); pbuf = stpcpy(pbuf, tbuf); } } if (buf[0] != '\0') { OUTPUT(buf); } } else { // Enable/disable one meter int target = buf[2] - '1'; int status = buf[3] - '0'; if (target < 0 || target > 5 || status < 0 || status > 1) { cmd_err = 2; continue; } meter[target].enabled = status; } } else if (strcmp(buf, "SL0;") == 0) { sprintf(buf, "SL0%02d;", sl); printf("R: %s\n", buf); OUTPUT(buf); } else if (strcmp(buf, "SH0;") == 0) { sprintf(buf, "SH0%03d;", sh); printf("R: %s\n", buf); OUTPUT(buf); } else if (strncmp(buf, "SL0", 3) == 0) { printf("Cmd: %s\n", buf); sscanf(buf, "SL0%3d", &sl); } else if (strncmp(buf, "SH0", 3) == 0) { printf("Cmd: %s\n", buf); sscanf("SH0%3d", "%d", &sh); } else if (strcmp(buf, "NR;") == 0) { sprintf(buf, "NR%d;", nr); OUTPUT(buf); } else if (strncmp(buf, "NR", 2) == 0) { puts(buf); sscanf(buf, "NR%d", &nr); } else if (strcmp(buf, "PA;") == 0) { sprintf(buf, "PA%d;", pa); OUTPUT(buf); } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d", &pa); } else if (strcmp(buf, "SM;") == 0) { sprintf(buf, "SM%04d;", sm); OUTPUT(buf); } else if (strcmp(buf, "PC;") == 0) { sprintf(buf, "PC%03d;", sm); OUTPUT(buf); } else if (strcmp(buf, "NT;") == 0) { sprintf(buf, "NT%d;", nt); OUTPUT(buf); } else if (strncmp(buf, "NT", 2) == 0) { sscanf(buf, "NT%d", &nt); } else if (strcmp(buf, "AG;") == 0) { sprintf(buf, "AG%03d;", ag); OUTPUT(buf); } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &ag); } else if (strcmp(buf, "AC;") == 0) { sprintf(buf, "AC%03d;", ac); OUTPUT(buf); } else if (strncmp(buf, "AC", 2) == 0) { sscanf(buf, "AC%d", &ac); } else if (strcmp(buf, "SQ;") == 0) { sprintf(buf, "SQ%03d;", sq); OUTPUT(buf); } else if (strncmp(buf, "SQ", 2) == 0) { sscanf(buf, "SQ%d", &sq); } else if (strcmp(buf, "RG;") == 0) { sprintf(buf, "RG%03d;", rg); OUTPUT(buf); } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG%d", &rg); } else if (strcmp(buf, "MG;") == 0) { sprintf(buf, "MG%03d;", mg); OUTPUT(buf); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &mg); } else if (strncmp(buf, "RL1;", 3) == 0) { snprintf(buf, sizeof(buf), "RL%02d;", rl); OUTPUT(buf); } else if (strncmp(buf, "RL1", 2) == 0) { puts(buf); sscanf(buf, "RL1%d", &rl); } else if (strncmp(buf, "FS", 2) == 0) { // FINE Function if (buf[2] == ';') { snprintf(buf, sizeof buf, "FS%d%d;", fine, fine); // For now OUTPUT(buf); } else { if (buf[2] == '0' || buf[2] == '1') { fine = buf[2] - '0'; } else { cmd_err = 1; } } } else if (strcmp(buf, "RC;") == 0) { // RIT/XIT Frequency Clear rxit = 0; } else if (buf[0] == 'R' && (buf[1] == 'D' || buf[1] == 'U')) // RD/RU { // RIT/XIT Frequency Up/Down int dir = buf[1] == 'D' ? -1 : +1; int tempit; if (buf[2] == ';') { tempit = rxit + (dir * (fine ? 1 : 10)); } else { tempit = rxit + dir * atoi(buf + 2); } if (abs(tempit) > 9999) {cmd_err = 1; continue;} /* Some weird rounding going on here - TBD */ rxit = tempit; } else if (strcmp(buf, "RF;") == 0) { // RIT/XIT Frequency snprintf(buf, sizeof buf, "RF%1d%04d;", rxit < 0 ? 1 : 0, abs(rxit)); OUTPUT(buf); } else if (strncmp(buf, "RT", 2) == 0) { // RIT Function State, RIT Shift switch (buf[2]) { case ';': // Read snprintf(buf, sizeof buf, "RT%d;", rit); OUTPUT(buf); break; case '0': // Set case '1': rit = buf[2] - '0'; break; case '2': // Shift //TODO: set recv freq to vfo+rxit, clear rxit and rit break; default: cmd_err = 1; } } else if (strncmp(buf, "XT", 2) == 0) { // XIT Function State, XIT Shift switch (buf[2]) { case '0': // Set case '1': xit = buf[2] - '0'; break; case '2': // Shift //TODO: set xmit freq to vfo+rxit(Which vfo?), set split, clear rxit and xit break; default: cmd_err = 1; } } else if (strncmp(buf, "CK", 2) == 0) { // All the clock functions switch (buf[2]) { case '0': // Get/Set Local clock { time_t t; struct tm *localtm; if (buf[3] == ';') { t = time(NULL); localtm = localtime(&t); strftime(&buf[3], BUFSIZ - 3, "%y%m%d%H%M%S;", localtm); OUTPUT(buf); } else { printf("Clock not set. cmd = %s\n", buf); } break; } case '1': // Setting status buf[3] = '1'; buf[4] = ';'; buf[5] = '\0'; OUTPUT(buf); break; case '2': // Local clock time zone case '3': // Auxiliary clock time zone { int idx = buf[2] - '2'; if (buf[3] == ';') { sprintf(&buf[3], "%03d;", tzs[idx]); OUTPUT(buf); } else { sscanf(&buf[3], "%3d;", &tzs[idx]); } break; } case '4': // ID character for auxiliary clock if (buf[3] == ';') { buf[3] = auxtzc; buf[4] = ';'; buf[5] = '\0'; OUTPUT(buf); } else { auxtzc = buf[3]; } break; case '5': // Date display format break; case '6': // Automatic date/time retrieval (NTP) //TODO: Fix this when we can set the clock if (buf[3] == ';') { buf[3] = autoset + '0'; buf[4] = ';'; buf[5] = '\0'; OUTPUT(buf); } else { autoset = buf[3] - '0'; } break; case '7': // NTP server address case '8': // Force time update via NTP case '9': // Clock display (primary/secondary/both) default: printf("Bad clock command - %s\n", buf); } } else if (strncmp(buf, "BS", 2) == 0) { // All the Bandscope commands switch (toupper(buf[2])) { case '0': // Scope Display ON/OFF case '1': // Scope Display Type case '2': // Bandscpoe Operation Mode case '3': // Bandscope Span case '4': // Bandscope Span case '5': // Bandscope Scope Range (Fixed Mode) case '6': // Bandscope Display Pause case '7': // Bandscope Marker case '8': // Bandscope Attenuator case '9': // Bandscope Max Hold case 'A': // Bandscope Averaging case 'B': // Bandscope Waterfall Display Speed case 'C': // Bandscope Reference Level case 'D': // Bandscope Waterfall Display Clear case 'E': // Bandscope Marker Shift / Marker Center case 'G': // Audio Scope Attenuator case 'H': // Audio Scope Span case 'I': // Oscilloscope Level case 'J': // Oscilloscpoe Sweep Time case 'K': // Bandscope Shift Position case 'L': // Bandscope Receive Circuit State case 'M': // Bandscope Scope Range Lower/Upper Frequency Limit case 'N': // Audio Scope Display Pause case 'O': // Expands Spectrum Analysis Range break; default: // Unknown cmd_err = 1; } } else if (strncmp(buf, "CD", 2) == 0) { // CW Communications switch (buf[2]) { case '0': // CW Communication Screen Display case '1': // CW Morse Decoding Threshold Level case '2': // Decoded CW Morse Character Output case '3': // CW Communication Screen (Decode Filter) case '4': // CW Communication Screen (Quick Mode) case '5': // CW Decode break; default: cmd_err = 1; } } else if (strncmp(buf, "CM", 2) == 0) { // CW Message Memory switch (buf[2]) { case '0': // Registration of CW Message (Paddle Input) case '1': // Play/Stop the CW Message case '2': // Register State of CW Message (Paddle Input) case '3': // Clear the CW Message (Paddle Input) case '4': // CW Message Memory Name (Paddle Input) case '5': // Registering the CW Message Memory (Text Input) case '6': // CW Message Channel Repeat case '7': // Contest Number break; default: cmd_err = 1; // Unknown command } } else if (strncmp(buf, "FL", 2) == 0) { switch (buf[2]) { case '0': // Select the Receive Filter case '1': // Roofing Filter case '2': // IF Filter Shape case '3': // AF Filter Type continue; // For now default: cmd_err = 1; } } else if (strncmp(buf, "FM", 2) == 0) { // Frequency Markers switch (buf[2]) { case '0': // Frequency Marker Function case '1': // Frequency Marker List Regiatration case '2': // Total Number Registered of Frequency Marker List case '3': // Frequency Marker List Readout case '4': // Frequency Marker List Delete break; default: cmd_err = 1; } } else if (strncmp(buf, "IP", 2) == 0) { // Network Config switch (buf[2]) { case '0': // DHCP case '1': // IP Address (Manual Configuration) case '2': // MAC Address break; default: cmd_err = 1; } } else if (strncmp(buf, "LA", 2) == 0) { // Linear Amplifier Configuration switch (buf[2]) { case '0': // Target Band of Linear Amplifier Menu case '1': // Linear Amplifier ON/OFF case '2': // Linear Amplifier Transmission Control case '3': // Linear Amplifier Transmission Delay ON/OFF case '4': // Linear Amplifier Transmission Delay Time case '5': // Linear Amplifier Relay Control case '6': // Linear Amplifier External ALC Voltage break; default: cmd_err = 1; } } else if (strncmp(buf, "MA", 2) == 0) { // Memory Channel Functions switch (buf[2]) { case '0': // Memory Channel Configuration case '1': // Memort Channel (Direct Write) case '2': // Memory Channel (Channel Name) case '3': // Memory Channel (Scan Lockout) case '4': // Memory Channel (Channel Copy) case '5': // Memory Channel (Channel Deletion) case '6': // Programmable VFO End Frequency case '7': // Memory Channel (Temporary Change Frequency) break; default: cmd_err = 1; } } else if (strncmp(buf, "PB", 2) == 0) { // Voice Messages switch (buf[2]) { case '0': // Voice Message List Display case '1': // Voice Message Playback, etc. case '2': // Voice Message Channel Registration State case '3': // Voice Message Channel Repeat case '4': // Voice Message Channel Name case '5': // Voice Message Recording Sound Source case '6': // Voice Message Recording Total Remaining Time break; default: cmd_err = 1; } } else if (strncmp(buf, "SC", 2) == 0) { // Scan functions switch (buf[2]) { case '0': // Scan case '1': // Scan Speed case '2': // Tone Scan/CTCSS Scan case '3': // Program Scan/VFO Scan Selection break; default: cmd_err = 1; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } /* Convert freq to TS-890S band # * * Input freq in Hz * * Returns band # or negative if invalid input */ int freq2band(int freq) { int i, retval = -1; // Assume the worst for (i = 0; i < NBANDS; i++) { if (freq >= band_limits[i].low && freq <= band_limits[i].high) { retval = i; break; } } //printf("%dHz is in band # %d\n", freq, retval); return retval; } /* Get appropriate vfo for new frequency * * Input: current vfo * new band * Return: new vfo pointer */ kvfop_t newvfo(kvfop_t ovfo, int band) { int vfonum, slot; vfonum = ovfo->vfo; slot = bandslot[vfonum][band]; return &band_mem[vfonum][band][slot]; } /* Reverse the function of vfoA and vfoB * No status returned */ void swapvfos(kvfop_t *vfoset[]) { kvfop_t *temp; temp = vfoset[0]; vfoset[0] = vfoset[1]; vfoset[1] = temp; return; } hamlib-4.6.2/simulators/simic7700.c0000644000175000017500000004551014752216205013701 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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; int keyspd = 85; // 85=20WPM int band = 8; int filter = 1; // 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 = 1; pbwidth_t widthB = 2; 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 keyertype = 0; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } 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) { dump_hex(frame, 11); n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: printf("cmd=0x14\n"); 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x02: frame[6] = 00; frame[7] = 00; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x01: // band if (frame[6] == 0xfd) { frame[6] = band; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { band = frame[6]; printf("Band select=%d\n", band); frame[4] = 0xfb; frame[5] = 0xfe; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x05: { int item = frame[6] * 256 + frame[7]; printf("0x05 *************************** item=%04x\n", item); if (frame[8] != 0xfd) // then we're setting it { switch (item) { case 164: keyertype = frame[8]; break; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else // we're reading it { switch (item) case 164: frame[8] = keyertype; frame[9] = 0xfb; break; } n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #if 0 // 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } 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] = filter; frame[9] = 0xfd; n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0) { modeA = frame[7]; datamodeA = frame[8]; filter = frame[9]; } else { modeB = frame[7]; datamodeB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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; } hamlib-4.6.2/simulators/simrotorez.c0000644000175000017500000001025114752216205014466 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simspid simspid.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 static void *rotorez_thread(void *arg); int getmyline(int fd, char *buf) { unsigned char c = 0; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); //printf("fd=%d\n", fd); while (read(fd, &c, 1) > 0 && c != ';') { buf[i++] = c; n++; for (int j = 0; j < strlen(buf); ++j) { printf("%02x ", buf[j]); } printf("\n"); } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return n; } #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 thread_args[2]; int main(int argc, char *argv[]) { int fd = openPort(argv[1]); int fd2 = openPort(argv[2]); pthread_t threads[2]; thread_args[0] = fd; thread_args[1] = fd2; pthread_create(&threads[0], NULL, rotorez_thread, (void *)&thread_args[0]); pthread_create(&threads[1], NULL, rotorez_thread, (void *)&thread_args[1]); pthread_exit(NULL); return 0; /* again: int flag = 0; while (1) { int bytes; if (!flag) bytes = getmyline(fd, buf); else bytes = getmyline(fd2, buf); flag = !flag; if (bytes == 0) { //close(fd); printf("again\n"); goto again; } printf("line=%s\n", buf); if (strncmp(buf,"BI1",3) == 0) { sprintf(buf,"%3.1f;", az); n = write(flag?fd:fd2, buf, strlen(buf)); printf("n=%d\n", n); } else if (strncmp(buf,"AP1",3) == 0) { sscanf(buf,"AP1%f", &az); } else { printf("Unknown cmd=%s\n", buf); } #if 0 switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } #endif } return 0; */ } static void *rotorez_thread(void *arg) { int n = 0; char buf[256]; int fd = *(int *)arg; float az = 123; float el = 45; again: while (1) { int bytes; bytes = getmyline(fd, buf); if (bytes == 0) { //close(fd); hl_usleep(100 * 1000); //printf("again\n"); goto again; } printf("line[%d]=%s\n", fd, buf); if (strncmp(buf, "BI1", 3) == 0) { if (fd == thread_args[0]) { sprintf(buf, "%3.1f;", az); printf("az=%f\n", az); } else { sprintf(buf, "%3.1f;", el); printf("el=%f\n", el); } n = write(fd, buf, strlen(buf)); printf("n=%d fd=%d\n", n, fd); } else if (strncmp(buf, "AP1", 3) == 0) { if (fd == thread_args[0]) { sscanf(buf, "AP1%f", &az); } else { sscanf(buf, "AP1%f", &el); } } else { printf("Unknown cmd=%s\n", buf); } #if 0 switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } #endif } pthread_exit(NULL); } hamlib-4.6.2/simulators/simic7300.c0000644000175000017500000004715214752216205013701 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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; int keyspd = 85; // 85=20WPM int band = 8; // 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 = 1; pbwidth_t widthB = 2; 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 keyertype = 0; void dumphex(const 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) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); printf("\n"); // echo //n = write(fd, buf, i); //if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: if (frame[5] == 0xfd) { //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) { dump_hex(frame, 11); n = write(fd, frame, 11); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } } else { if (current_vfo == RIG_VFO_A) { freqA = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } else { freqB = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: printf("cmd=0x14\n"); 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x02: frame[6] = 00; frame[7] = 00; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x1a: // miscellaneous things switch (frame[5]) { case 0x01: // band if (frame[6] == 0xfd) { frame[6] = band; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { band = frame[6]; printf("Band select=%d\n", band); frame[4] = 0xfb; frame[5] = 0xfe; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x05: { int item = frame[6] * 256 + frame[7]; printf("0x05 *************************** item=%04x\n", item); if (frame[8] != 0xfd) // then we're setting it { switch (item) { case 164: keyertype = frame[8]; break; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else // we're reading it { switch (item) case 164: frame[8] = keyertype; frame[9] = 0xfb; break; } n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #if 0 // 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } 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] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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) { unsigned char tmp = buf[2]; buf[2] = buf[3]; buf[3] = tmp; frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.2/simulators/simyaesu.c0000644000175000017500000002771614752216205014126 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; vfo_t curr_vfo = RIG_VFO_A; char modeA = '1'; char modeB = '1'; int ptt; int power = 1; int roofing_filter_main = 1; int roofing_filter_sub = 6; int width_main = 0; int width_sub = 0; int ex039 = 0; int lk = 0; // 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_FTDX3000DM = 462, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; 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); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 resp[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } //else { return 0; } if (buf[0] == 0x0a) { continue; } if (power == 0 && strcmp(buf, "PS1;") != 0) { continue; } if (strcmp(buf, "PS;") == 0) { sprintf(resp, "PS%d;", power); n = write(fd, resp, strlen(resp)); if (n <= 0) { perror("PS"); } } else if (strncmp(buf, "PS", 2) == 0) { sscanf(buf, "PS%d", &power); } else if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "RM8;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM8197000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("RM8"); } } else if (strcmp(buf, "RM9;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM9089000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("RM9"); } } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "FA;") == 0) { //SNPRINTF(resp, sizeof(resp), "FA%010.0f;", freqA); SNPRINTF(resp, sizeof(resp), "FA%08.0f;", freqA); freqA += 10; n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { //SNPRINTF(resp, sizeof(resp), "FB%0010.0f;", freqB); SNPRINTF(resp, sizeof(resp), "FB%08.0f;", freqB); n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF00107041000+000000200000;"; n = write(fd, pbuf, strlen(pbuf)); //printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FT991; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); //printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); //printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "AB;") == 0) { freqB = freqA; modeB = modeA; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS") == 0 && strlen(buf) > 3) { curr_vfo = buf[3] == '1' ? RIG_VFO_B : RIG_VFO_A; hl_usleep(50 * 1000); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; if (curr_vfo == RIG_VFO_B || curr_vfo == RIG_VFO_SUB) { pbuf = "VS1"; } n = write(fd, pbuf, strlen(pbuf)); printf("%s\n", pbuf); if (n < 0) { perror("VS"); } } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "FT%c;", tx_vfo); printf(" FT response#1=%s, tx_vfo=%c\n", resp, tx_vfo); n = write(fd, resp, strlen(resp)); printf(" FT response#2=%s\n", resp); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; if (tx_vfo == '3') { tx_vfo = '1'; } else if (tx_vfo == '2') { tx_vfo = '0'; } else { perror("Expected 2 or 3"); } } else if (strcmp(buf, "MD0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD0%c;", modeA); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD1%c;", modeB); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } else if (strcmp(buf, "SM0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "SM0111;"); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("SM"); } } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "TX%d;", ptt); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { hl_usleep(50 * 1000); ptt = buf[2] == '0' ? 0 : 1; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); //printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA00;"); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); //printf("%s n=%d\n", buf, n); } else if (strcmp(buf, "RF0;") == 0) { SNPRINTF(buf, sizeof(buf), "RF0%d;", roofing_filter_main); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "RF1;") == 0) { SNPRINTF(buf, sizeof(buf), "RF1%d;", roofing_filter_sub); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "RF%c%d;", buf[2], buf[2] == 0 ? roofing_filter_main : roofing_filter_sub); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH%c%02d;", buf[2], width_main); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "SH1;") == 0) { SNPRINTF(buf, sizeof(buf), "SH%c%02d;", buf[2], width_sub); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH", 2) == 0 && strlen(buf) > 4) { int vfo, twidth; sscanf(buf, "SH%1d%d", &vfo, &twidth); if (vfo == 0) { width_main = twidth; } else { width_sub = twidth; } printf("width_main=%d, width_sub=%d\n", width_main, width_sub); } else if (strncmp(buf, "SH", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SH%c%02d;", buf[2], buf[2] == 0 ? width_main : width_sub); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "LK;") == 0) { SNPRINTF(buf, sizeof(buf), "LK%d;", lk); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "LK", 3) == 0) { sscanf(buf, "LK%d", &lk); } else if (strncmp(buf, "DT0;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "DT020221022;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT1;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "DT1222100;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT2;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "DT2+0500;"); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: '%s'\n", buf); } } return 0; } hamlib-4.6.2/simulators/simft1000.c0000644000175000017500000000541714752216205013704 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simft1000 simft1000.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #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[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); continue; } switch (buf[4]) { case 0x01: printf("Split\n"); break; case 0x05: printf("Select VFO\n"); break; case 0x0a: printf("Set Main freq\n"); break; case 0x10: printf("Info\n"); break; case 0x0c: printf("Set mode\n"); break; case 0x0e: printf("Pacing\n"); break; case 0x0f: printf("Tx\n"); break; case 0x83: printf("Full Duplex Rx Mode\n"); break; case 0x8a: printf("Set Sub freq\n"); break; case 0x8b: printf("Bandwidth\n"); break; case 0xf7: printf("Read meter\n"); break; default: printf("Unknown cmd=%02x\n", buf[4]); } fflush(stdout); } return 0; } hamlib-4.6.2/simulators/simic705.c0000644000175000017500000003524214752216205013620 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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; int keyspd = 85; // 85=20WPM // 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_FM; mode_t modeB = RIG_MODE_FM; 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; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } printf("Here#1\n"); 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", split); 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: printf("cmd=0x14\n"); 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; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x02: frame[6] = 00; frame[7] = 00; frame[8] = 0xfd; n = write(fd, frame, 9); break; 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 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 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] = 0x00; frame2[6] = 0x35; frame2[7] = 0x57; frame2[8] = 0x03; frame2[9] = 0x00; frame2[10] = 0xfd; n = write(fd, frame2, 11); #else n = write(fd, frame, 12); #endif } 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); #if 0 // 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); #endif } 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] = 0x01; 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) { unsigned char tmp = buf[2]; buf[2] = buf[3]; buf[3] = tmp; frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.2/simulators/simflex.c0000644000175000017500000001762714752216205013736 00000000000000#include #include #include #include #if defined(WIN32) || defined(_WIN32) #include #include #else #include #endif #define PORT 4992 #define BUFFER_SIZE 1024 /* S67319A86|slice 0 in_use=1 sample_rate=24000 RF_frequency=10.137000 client_handle=0x76AF7C73 index_letter=A rit_on=0 rit_freq=0 xit_on=0 xit_freq=0 rxant=ANT2 mode=DIGU wide=0 filter_lo=0 filter_hi=3510 step=10 step_list=1,5,10,20,100,250,500,1000 agc_mode=fast agc_threshold=65 agc_off_level=10 pan=0x40000000 txant=ANT2 loopa=0 loopb=0 qsk=0 dax=1 dax_clients=1 lock=0 tx=1 active=1 audio_level=100 audio_pan=51 audio_mute=1 record=0 play=disabled record_time=0.0 anf=0 anf_level=0 nr=0 nr_level=0 nb=0 nb_level=50 wnb=0 wnb_level=100 apf=0 apf_level=0 squelch=1 squelch_level=20 diversity=0 diversity_parent=0 diversity_child=0 diversity_index=1342177293 ant_list=ANT1,ANT2,RX_A,RX_B,XVTA,XVTB mode_list=LSB,USB,AM,CW,DIGL,DIGU,SAM,FM,NFM,DFM,RTTY fm_tone_mode=OFF fm_tone_value=67.0 fm_repeater_offset_freq=0.000000 tx_offset_freq=0.000000 repeater_offset_dir=SIMPLEX fm_tone_burst=0 fm_deviation=5000 dfm_pre_de_emphasis=0 post_demod_low=300 post_demod_high=3300 rtty_mark=2125 rtty_shift=170 digl_offset=2210 digu_offset=1500 post_demod_bypass=0 rfgain=24 tx_ant_list=ANT1,ANT2,XVTA,XVTB */ char *msg1 = "V1.4.0.0\n"; char *msg2 = "H2FFEDF06.M10000001|Client connected from IP 10.1.10.102\n"; char *msg3 = "S2FFEDF06|radio slices=0 panadapters=0 lineout_gain=54 lineout_mute=0 headphone_gain=56 headphone_mute=0 remote_on_enabled=0 pll_done=0 freq_error_ppb=0 cal_freq=15.000000 tnf_enabled=0 nickname=FaradayII callsign=WQ6Q binaural_rx=1 full_duplex_enabled=0 band_persistence_enabled=1 rtty_mark_default=2125 enforce_private_ip_connections=1 backlight=50 mute_local_audio_when_remote=1 daxiq_capacity=16 daxiq_available=16 alpha=1 low_latency_digital_modes=1 mf_enable=1.S2FFEDF06|radio filter_sharpness VOICE level=2 auto_level=1\n"; char *msg4 = "S2FFEDF06|radio filter_sharpness CW level=2 auto_level=1\n"; char *msg5 = "S2FFEDF06|radio filter_sharpness DIGITAL level=2 auto_level=1\n"; char *msg6 = "S2FFEDF06|radio static_net_params ip= gateway= netmask=\n"; char *msg7 = "S2FFEDF06|radio front_speaker_mute=1\n"; char *msg8 = "S2FFEDF06|radio oscillator state=gpsdo setting=auto locked=1 ext_present=0 gpsdo_present=1 tcxo_present=1\n"; char *msg9 = "S2FFEDF06|interlock acc_txreq_enable=0 rca_txreq_enable=0 acc_tx_enabled=0 tx1_enabled=1 tx2_enabled=0 tx3_enabled=0 tx_delay=40 acc_tx_delay=0 tx1_delay=0 tx2_delay=0 tx3_delay=0 acc_txreq_polarity=0 rca_txreq_polarity=0 time out=0\n"; char *msg10 = "S2FFEDF06|eq rx mode=0 63Hz=10 125Hz=10 250Hz=10 500Hz=10 1000Hz=10 2000Hz=10 4000Hz=10 8000Hz=10\n"; char *msg11 = "S2FFEDF06|eq rxsc mode=0 63Hz=0 125Hz=0 250Hz=0 500Hz=0 1000Hz=0 2000Hz=0 4000Hz=0 8000Hz=0\n"; char *slicetxt = "S67319A86|slice 0 in_use=1 sample_rate=24000 RF_frequency=10.137000 client_handle=0x76AF7C73 index_letter=A rit_on=0 rit_freq=0 xit_on=0 xit_freq=0 rxant=ANT2 mode=DIGU wide=0 filter_lo=0 filter_hi=3510 step=10 step_list=1,5,10,20,100,250,500,1000 agc_mode=fast agc_threshold=65 agc_off_level=10 pan=0x40000000 txant=ANT2 loopa=0 loopb=0 qsk=0 dax=1 dax_clients=1 lock=0 tx=1 active=1 audio_level=100 audio_pan=51 audio_mute=1 record=0 play=disabled record_time=0.0 anf=0 anf_level=0 nr=0 nr_level=0 nb=0 nb_level=50 wnb=0 wnb_level=100 apf=0 apf_level=0 squelch=1 squelch_level=20 diversity=0 diversity_parent=0 diversity_child=0 diversity_index=1342177293 ant_list=ANT1,ANT2,RX_A,RX_B,XVTA,XVTB mode_list=LSB,USB,AM,CW,DIGL,DIGU,SAM,FM,NFM,DFM,RTTY fm_tone_mode=OFF fm_tone_value=67.0 fm_repeater_offset_freq=0.000000 tx_offset_freq=0.000000 repeater_offset_dir=SIMPLEX fm_tone_burst=0 fm_deviation=5000 dfm_pre_de_emphasis=0 post_demod_low=300 post_demod_high=3300 rtty_mark=2125 rtty_shift=170 digl_offset=2210 digu_offset=1500 post_demod_bypass=0 rfgain=24 tx_ant_list=ANT1,ANT2,XVTA,XVTB"; int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); #if defined(WIN32) || defined(_WIN32) WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); exit(EXIT_FAILURE); } #endif // Create socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } // Set socket options #if defined(WIN32) || defined(_WIN32) if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))) { #else if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { #endif perror("setsockopt"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // Bind the socket to the network address and port if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } // Start listening for incoming connections if (listen(server_fd, 3) < 0) { perror("listen"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } printf("Server is listening on port %d\n", PORT); while (1) { // Accept incoming connection if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { perror("accept"); close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif exit(EXIT_FAILURE); } printf("Connection accepted\n"); send(new_socket, msg1, strlen(msg1), 0); send(new_socket, msg2, strlen(msg2), 0); send(new_socket, msg3, strlen(msg3), 0); send(new_socket, msg4, strlen(msg4), 0); send(new_socket, msg5, strlen(msg5), 0); send(new_socket, msg6, strlen(msg6), 0); send(new_socket, msg7, strlen(msg7), 0); send(new_socket, msg8, strlen(msg8), 0); send(new_socket, msg9, strlen(msg9), 0); send(new_socket, msg10, strlen(msg10), 0); send(new_socket, msg11, strlen(msg11), 0); while (1) { char buffer[BUFFER_SIZE] = {0}; char reply[BUFFER_SIZE] = {0}; int seqnum = -1; int valread = read(new_socket, buffer, BUFFER_SIZE); if (valread < 0) { perror("read"); break; } if (valread == 0) { // Connection closed printf("Connection closed by client\n"); break; } buffer[valread] = '\0'; printf("Received: %s", buffer); sscanf(buffer, "C%d", &seqnum); sprintf(reply, "R%d|0%c", seqnum, 0x0a); if (strstr(buffer, "sub slice")) { char buf[8192]; sprintf(buf, "%s%c", slicetxt, 0x0a); if (send(new_socket, buf, strlen(buf), 0) != strlen(buf)) { perror("send"); break; } } // Echo back the received message if (send(new_socket, reply, valread, 0) != valread) { perror("send"); break; } } close(new_socket); } close(server_fd); #if defined(WIN32) || defined(_WIN32) WSACleanup(); #endif return 0; } hamlib-4.6.2/simulators/simicgeneric.c0000644000175000017500000002475614752216205014731 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #include "sim.h" #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_CW; mode_t modeB = RIG_MODE_USB; 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; void dumphex(const 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; 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; } } printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } 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; 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; 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; 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; 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; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; 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("n=WRITE 8 bytes\n"); dump_hex(frame, 8); WRITE(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; WRITE(fd, frame, 9); 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; WRITE(fd, frame, 9); break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; 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; WRITE(fd, frame, 9); break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; 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; WRITE(fd, frame, 8); break; case 0x04: // IC7200 data mode frame[6] = 0; frame[7] = 0; frame[8] = 0xfd; WRITE(fd, frame, 9); break; case 0x07: // satmode frame[6] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; 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("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; 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; WRITE(fd, frame, 6); } 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; WRITE(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.2/simulators/Makefile.am0000644000175000017500000000410714752216205014144 00000000000000# Current Autotools documentation suggests that DejaGNU is obsolete # and replaced by Autotest. TODO: implement Autotest # AUTOMAKE_OPTIONS = dejagnu # DEJATOOL = testfreq testbcd testloc rigctl DISTCLEANFILES = bin_PROGRAMS = check_PROGRAMS = simelecraft simicgeneric simkenwood simyaesu simic9100 simic9700 simft991 simftdx1200 simftdx3000 simjupiter simpowersdr simid5100 simft736 simftdx5000 simtmd700 simrotorez simspid simft817 simts590 simft847 simic7300 simic7000 simic7100 simic7200 simatd578 simic905 simts450 simic7600 simic7610 simic705 simts950 simts990 simic7851 simftdx101 simxiegug90 simqrplabs simft818 simic275 simtrusdx simft1000 simtmd710 simts890 simxiegux108g simxiegux6100 simic910 simft450 simelecraftk4 simmicom simflex simft710 simic2730 simorion simpmr171 simic7700 simft990 simpstrotator simelecraft_SOURCES = simelecraft.c simkenwood_SOURCES = simkenwood.c simyaesu_SOURCES = simyaesu.c simid5100_SOURCES = simid5100.c # include generated include files ahead of any in sources #rigctl_CPPFLAGS = -I$(top_builddir)/tests -I$(top_builddir)/src -I$(srcdir) $(AM_CPPFLAGS) # all the programs need this LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) simelecraft_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS) -I$(top_builddir)/src simkenwood_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simyaesu_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simid5100_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simelecraft_LDADD = $(PTHREAD_LIBS) $(READLINE_LIBS) $(LDADD) simkenwood_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simyaesu_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simid5100_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) # Linker options simelecraft_LDFLAGS = $(WINEXELDFLAGS) simkenwood_LDFLAGS = $(WINEXELDFLAGS) simyaesu_LDFLAGS = $(WINEXELDFLAGS) simid5100_LDFLAGS = $(WINEXELDFLAGS) EXTRA_DIST = # Support 'make check' target for simple tests #check_SCRIPTS = #TESTS = $(check_SCRIPTS) CLEANFILES = simelelecraft simicgeneric simkenwood simyaesu hamlib-4.6.2/simulators/simjupiter.c0000644000175000017500000000403714752216205014451 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simft897 simft897.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #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[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.2/simulators/Makefile.in0000644000175000017500000020753114752216217014166 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Current Autotools documentation suggests that DejaGNU is obsolete # and replaced by Autotest. TODO: implement Autotest # AUTOMAKE_OPTIONS = dejagnu # DEJATOOL = testfreq testbcd testloc rigctl VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = check_PROGRAMS = simelecraft$(EXEEXT) simicgeneric$(EXEEXT) \ simkenwood$(EXEEXT) simyaesu$(EXEEXT) simic9100$(EXEEXT) \ simic9700$(EXEEXT) simft991$(EXEEXT) simftdx1200$(EXEEXT) \ simftdx3000$(EXEEXT) simjupiter$(EXEEXT) simpowersdr$(EXEEXT) \ simid5100$(EXEEXT) simft736$(EXEEXT) simftdx5000$(EXEEXT) \ simtmd700$(EXEEXT) simrotorez$(EXEEXT) simspid$(EXEEXT) \ simft817$(EXEEXT) simts590$(EXEEXT) simft847$(EXEEXT) \ simic7300$(EXEEXT) simic7000$(EXEEXT) simic7100$(EXEEXT) \ simic7200$(EXEEXT) simatd578$(EXEEXT) simic905$(EXEEXT) \ simts450$(EXEEXT) simic7600$(EXEEXT) simic7610$(EXEEXT) \ simic705$(EXEEXT) simts950$(EXEEXT) simts990$(EXEEXT) \ simic7851$(EXEEXT) simftdx101$(EXEEXT) simxiegug90$(EXEEXT) \ simqrplabs$(EXEEXT) simft818$(EXEEXT) simic275$(EXEEXT) \ simtrusdx$(EXEEXT) simft1000$(EXEEXT) simtmd710$(EXEEXT) \ simts890$(EXEEXT) simxiegux108g$(EXEEXT) \ simxiegux6100$(EXEEXT) simic910$(EXEEXT) simft450$(EXEEXT) \ simelecraftk4$(EXEEXT) simmicom$(EXEEXT) simflex$(EXEEXT) \ simft710$(EXEEXT) simic2730$(EXEEXT) simorion$(EXEEXT) \ simpmr171$(EXEEXT) simic7700$(EXEEXT) simft990$(EXEEXT) \ simpstrotator$(EXEEXT) subdir = simulators ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) simatd578_SOURCES = simatd578.c simatd578_OBJECTS = simatd578.$(OBJEXT) simatd578_LDADD = $(LDADD) am__DEPENDENCIES_1 = simatd578_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = am_simelecraft_OBJECTS = simelecraft-simelecraft.$(OBJEXT) simelecraft_OBJECTS = $(am_simelecraft_OBJECTS) am__DEPENDENCIES_2 = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simelecraft_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) simelecraft_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simelecraft_CFLAGS) \ $(CFLAGS) $(simelecraft_LDFLAGS) $(LDFLAGS) -o $@ simelecraftk4_SOURCES = simelecraftk4.c simelecraftk4_OBJECTS = simelecraftk4.$(OBJEXT) simelecraftk4_LDADD = $(LDADD) simelecraftk4_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simflex_SOURCES = simflex.c simflex_OBJECTS = simflex.$(OBJEXT) simflex_LDADD = $(LDADD) simflex_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft1000_SOURCES = simft1000.c simft1000_OBJECTS = simft1000.$(OBJEXT) simft1000_LDADD = $(LDADD) simft1000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft450_SOURCES = simft450.c simft450_OBJECTS = simft450.$(OBJEXT) simft450_LDADD = $(LDADD) simft450_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft710_SOURCES = simft710.c simft710_OBJECTS = simft710.$(OBJEXT) simft710_LDADD = $(LDADD) simft710_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft736_SOURCES = simft736.c simft736_OBJECTS = simft736.$(OBJEXT) simft736_LDADD = $(LDADD) simft736_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft817_SOURCES = simft817.c simft817_OBJECTS = simft817.$(OBJEXT) simft817_LDADD = $(LDADD) simft817_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft818_SOURCES = simft818.c simft818_OBJECTS = simft818.$(OBJEXT) simft818_LDADD = $(LDADD) simft818_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft847_SOURCES = simft847.c simft847_OBJECTS = simft847.$(OBJEXT) simft847_LDADD = $(LDADD) simft847_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft990_SOURCES = simft990.c simft990_OBJECTS = simft990.$(OBJEXT) simft990_LDADD = $(LDADD) simft990_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simft991_SOURCES = simft991.c simft991_OBJECTS = simft991.$(OBJEXT) simft991_LDADD = $(LDADD) simft991_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx101_SOURCES = simftdx101.c simftdx101_OBJECTS = simftdx101.$(OBJEXT) simftdx101_LDADD = $(LDADD) simftdx101_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx1200_SOURCES = simftdx1200.c simftdx1200_OBJECTS = simftdx1200.$(OBJEXT) simftdx1200_LDADD = $(LDADD) simftdx1200_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx3000_SOURCES = simftdx3000.c simftdx3000_OBJECTS = simftdx3000.$(OBJEXT) simftdx3000_LDADD = $(LDADD) simftdx3000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simftdx5000_SOURCES = simftdx5000.c simftdx5000_OBJECTS = simftdx5000.$(OBJEXT) simftdx5000_LDADD = $(LDADD) simftdx5000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic2730_SOURCES = simic2730.c simic2730_OBJECTS = simic2730.$(OBJEXT) simic2730_LDADD = $(LDADD) simic2730_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic275_SOURCES = simic275.c simic275_OBJECTS = simic275.$(OBJEXT) simic275_LDADD = $(LDADD) simic275_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7000_SOURCES = simic7000.c simic7000_OBJECTS = simic7000.$(OBJEXT) simic7000_LDADD = $(LDADD) simic7000_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic705_SOURCES = simic705.c simic705_OBJECTS = simic705.$(OBJEXT) simic705_LDADD = $(LDADD) simic705_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7100_SOURCES = simic7100.c simic7100_OBJECTS = simic7100.$(OBJEXT) simic7100_LDADD = $(LDADD) simic7100_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7200_SOURCES = simic7200.c simic7200_OBJECTS = simic7200.$(OBJEXT) simic7200_LDADD = $(LDADD) simic7200_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7300_SOURCES = simic7300.c simic7300_OBJECTS = simic7300.$(OBJEXT) simic7300_LDADD = $(LDADD) simic7300_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7600_SOURCES = simic7600.c simic7600_OBJECTS = simic7600.$(OBJEXT) simic7600_LDADD = $(LDADD) simic7600_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7610_SOURCES = simic7610.c simic7610_OBJECTS = simic7610.$(OBJEXT) simic7610_LDADD = $(LDADD) simic7610_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7700_SOURCES = simic7700.c simic7700_OBJECTS = simic7700.$(OBJEXT) simic7700_LDADD = $(LDADD) simic7700_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic7851_SOURCES = simic7851.c simic7851_OBJECTS = simic7851.$(OBJEXT) simic7851_LDADD = $(LDADD) simic7851_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic905_SOURCES = simic905.c simic905_OBJECTS = simic905.$(OBJEXT) simic905_LDADD = $(LDADD) simic905_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic910_SOURCES = simic910.c simic910_OBJECTS = simic910.$(OBJEXT) simic910_LDADD = $(LDADD) simic910_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic9100_SOURCES = simic9100.c simic9100_OBJECTS = simic9100.$(OBJEXT) simic9100_LDADD = $(LDADD) simic9100_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simic9700_SOURCES = simic9700.c simic9700_OBJECTS = simic9700.$(OBJEXT) simic9700_LDADD = $(LDADD) simic9700_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simicgeneric_SOURCES = simicgeneric.c simicgeneric_OBJECTS = simicgeneric.$(OBJEXT) simicgeneric_LDADD = $(LDADD) simicgeneric_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am_simid5100_OBJECTS = simid5100-simid5100.$(OBJEXT) simid5100_OBJECTS = $(am_simid5100_OBJECTS) simid5100_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) simid5100_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simid5100_CFLAGS) \ $(CFLAGS) $(simid5100_LDFLAGS) $(LDFLAGS) -o $@ simjupiter_SOURCES = simjupiter.c simjupiter_OBJECTS = simjupiter.$(OBJEXT) simjupiter_LDADD = $(LDADD) simjupiter_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am_simkenwood_OBJECTS = simkenwood-simkenwood.$(OBJEXT) simkenwood_OBJECTS = $(am_simkenwood_OBJECTS) simkenwood_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_1) simkenwood_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simkenwood_CFLAGS) \ $(CFLAGS) $(simkenwood_LDFLAGS) $(LDFLAGS) -o $@ simmicom_SOURCES = simmicom.c simmicom_OBJECTS = simmicom.$(OBJEXT) simmicom_LDADD = $(LDADD) simmicom_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simorion_SOURCES = simorion.c simorion_OBJECTS = simorion.$(OBJEXT) simorion_LDADD = $(LDADD) simorion_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simpmr171_SOURCES = simpmr171.c simpmr171_OBJECTS = simpmr171.$(OBJEXT) simpmr171_LDADD = $(LDADD) simpmr171_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simpowersdr_SOURCES = simpowersdr.c simpowersdr_OBJECTS = simpowersdr.$(OBJEXT) simpowersdr_LDADD = $(LDADD) simpowersdr_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simpstrotator_SOURCES = simpstrotator.c simpstrotator_OBJECTS = simpstrotator.$(OBJEXT) simpstrotator_LDADD = $(LDADD) simpstrotator_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simqrplabs_SOURCES = simqrplabs.c simqrplabs_OBJECTS = simqrplabs.$(OBJEXT) simqrplabs_LDADD = $(LDADD) simqrplabs_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simrotorez_SOURCES = simrotorez.c simrotorez_OBJECTS = simrotorez.$(OBJEXT) simrotorez_LDADD = $(LDADD) simrotorez_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simspid_SOURCES = simspid.c simspid_OBJECTS = simspid.$(OBJEXT) simspid_LDADD = $(LDADD) simspid_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simtmd700_SOURCES = simtmd700.c simtmd700_OBJECTS = simtmd700.$(OBJEXT) simtmd700_LDADD = $(LDADD) simtmd700_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simtmd710_SOURCES = simtmd710.c simtmd710_OBJECTS = simtmd710.$(OBJEXT) simtmd710_LDADD = $(LDADD) simtmd710_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simtrusdx_SOURCES = simtrusdx.c simtrusdx_OBJECTS = simtrusdx.$(OBJEXT) simtrusdx_LDADD = $(LDADD) simtrusdx_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts450_SOURCES = simts450.c simts450_OBJECTS = simts450.$(OBJEXT) simts450_LDADD = $(LDADD) simts450_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts590_SOURCES = simts590.c simts590_OBJECTS = simts590.$(OBJEXT) simts590_LDADD = $(LDADD) simts590_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts890_SOURCES = simts890.c simts890_OBJECTS = simts890.$(OBJEXT) simts890_LDADD = $(LDADD) simts890_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts950_SOURCES = simts950.c simts950_OBJECTS = simts950.$(OBJEXT) simts950_LDADD = $(LDADD) simts950_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simts990_SOURCES = simts990.c simts990_OBJECTS = simts990.$(OBJEXT) simts990_LDADD = $(LDADD) simts990_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simxiegug90_SOURCES = simxiegug90.c simxiegug90_OBJECTS = simxiegug90.$(OBJEXT) simxiegug90_LDADD = $(LDADD) simxiegug90_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simxiegux108g_SOURCES = simxiegux108g.c simxiegux108g_OBJECTS = simxiegux108g.$(OBJEXT) simxiegux108g_LDADD = $(LDADD) simxiegux108g_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) simxiegux6100_SOURCES = simxiegux6100.c simxiegux6100_OBJECTS = simxiegux6100.$(OBJEXT) simxiegux6100_LDADD = $(LDADD) simxiegux6100_DEPENDENCIES = $(top_builddir)/src/libhamlib.la \ $(top_builddir)/lib/libmisc.la $(am__DEPENDENCIES_1) am_simyaesu_OBJECTS = simyaesu-simyaesu.$(OBJEXT) simyaesu_OBJECTS = $(am_simyaesu_OBJECTS) simyaesu_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) simyaesu_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(simyaesu_CFLAGS) \ $(CFLAGS) $(simyaesu_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/hamlib depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/simatd578.Po \ ./$(DEPDIR)/simelecraft-simelecraft.Po \ ./$(DEPDIR)/simelecraftk4.Po ./$(DEPDIR)/simflex.Po \ ./$(DEPDIR)/simft1000.Po ./$(DEPDIR)/simft450.Po \ ./$(DEPDIR)/simft710.Po ./$(DEPDIR)/simft736.Po \ ./$(DEPDIR)/simft817.Po ./$(DEPDIR)/simft818.Po \ ./$(DEPDIR)/simft847.Po ./$(DEPDIR)/simft990.Po \ ./$(DEPDIR)/simft991.Po ./$(DEPDIR)/simftdx101.Po \ ./$(DEPDIR)/simftdx1200.Po ./$(DEPDIR)/simftdx3000.Po \ ./$(DEPDIR)/simftdx5000.Po ./$(DEPDIR)/simic2730.Po \ ./$(DEPDIR)/simic275.Po ./$(DEPDIR)/simic7000.Po \ ./$(DEPDIR)/simic705.Po ./$(DEPDIR)/simic7100.Po \ ./$(DEPDIR)/simic7200.Po ./$(DEPDIR)/simic7300.Po \ ./$(DEPDIR)/simic7600.Po ./$(DEPDIR)/simic7610.Po \ ./$(DEPDIR)/simic7700.Po ./$(DEPDIR)/simic7851.Po \ ./$(DEPDIR)/simic905.Po ./$(DEPDIR)/simic910.Po \ ./$(DEPDIR)/simic9100.Po ./$(DEPDIR)/simic9700.Po \ ./$(DEPDIR)/simicgeneric.Po ./$(DEPDIR)/simid5100-simid5100.Po \ ./$(DEPDIR)/simjupiter.Po ./$(DEPDIR)/simkenwood-simkenwood.Po \ ./$(DEPDIR)/simmicom.Po ./$(DEPDIR)/simorion.Po \ ./$(DEPDIR)/simpmr171.Po ./$(DEPDIR)/simpowersdr.Po \ ./$(DEPDIR)/simpstrotator.Po ./$(DEPDIR)/simqrplabs.Po \ ./$(DEPDIR)/simrotorez.Po ./$(DEPDIR)/simspid.Po \ ./$(DEPDIR)/simtmd700.Po ./$(DEPDIR)/simtmd710.Po \ ./$(DEPDIR)/simtrusdx.Po ./$(DEPDIR)/simts450.Po \ ./$(DEPDIR)/simts590.Po ./$(DEPDIR)/simts890.Po \ ./$(DEPDIR)/simts950.Po ./$(DEPDIR)/simts990.Po \ ./$(DEPDIR)/simxiegug90.Po ./$(DEPDIR)/simxiegux108g.Po \ ./$(DEPDIR)/simxiegux6100.Po ./$(DEPDIR)/simyaesu-simyaesu.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = simatd578.c $(simelecraft_SOURCES) simelecraftk4.c simflex.c \ simft1000.c simft450.c simft710.c simft736.c simft817.c \ simft818.c simft847.c simft990.c simft991.c simftdx101.c \ simftdx1200.c simftdx3000.c simftdx5000.c simic2730.c \ simic275.c simic7000.c simic705.c simic7100.c simic7200.c \ simic7300.c simic7600.c simic7610.c simic7700.c simic7851.c \ simic905.c simic910.c simic9100.c simic9700.c simicgeneric.c \ $(simid5100_SOURCES) simjupiter.c $(simkenwood_SOURCES) \ simmicom.c simorion.c simpmr171.c simpowersdr.c \ simpstrotator.c simqrplabs.c simrotorez.c simspid.c \ simtmd700.c simtmd710.c simtrusdx.c simts450.c simts590.c \ simts890.c simts950.c simts990.c simxiegug90.c simxiegux108g.c \ simxiegux6100.c $(simyaesu_SOURCES) DIST_SOURCES = simatd578.c $(simelecraft_SOURCES) simelecraftk4.c \ simflex.c simft1000.c simft450.c simft710.c simft736.c \ simft817.c simft818.c simft847.c simft990.c simft991.c \ simftdx101.c simftdx1200.c simftdx3000.c simftdx5000.c \ simic2730.c simic275.c simic7000.c simic705.c simic7100.c \ simic7200.c simic7300.c simic7600.c simic7610.c simic7700.c \ simic7851.c simic905.c simic910.c simic9100.c simic9700.c \ simicgeneric.c $(simid5100_SOURCES) simjupiter.c \ $(simkenwood_SOURCES) simmicom.c simorion.c simpmr171.c \ simpowersdr.c simpstrotator.c simqrplabs.c simrotorez.c \ simspid.c simtmd700.c simtmd710.c simtrusdx.c simts450.c \ simts590.c simts890.c simts950.c simts990.c simxiegug90.c \ simxiegux108g.c simxiegux6100.c $(simyaesu_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build-aux/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DISTCLEANFILES = simelecraft_SOURCES = simelecraft.c simkenwood_SOURCES = simkenwood.c simyaesu_SOURCES = simyaesu.c simid5100_SOURCES = simid5100.c # include generated include files ahead of any in sources #rigctl_CPPFLAGS = -I$(top_builddir)/tests -I$(top_builddir)/src -I$(srcdir) $(AM_CPPFLAGS) # all the programs need this LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/lib/libmisc.la $(DL_LIBS) simelecraft_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS) -I$(top_builddir)/src simkenwood_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simyaesu_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simid5100_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -I$(top_builddir)/src simelecraft_LDADD = $(PTHREAD_LIBS) $(READLINE_LIBS) $(LDADD) simkenwood_LDADD = $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simyaesu_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) simid5100_LDADD = $(NET_LIBS) $(PTHREAD_LIBS) $(LDADD) $(READLINE_LIBS) # Linker options simelecraft_LDFLAGS = $(WINEXELDFLAGS) simkenwood_LDFLAGS = $(WINEXELDFLAGS) simyaesu_LDFLAGS = $(WINEXELDFLAGS) simid5100_LDFLAGS = $(WINEXELDFLAGS) EXTRA_DIST = # Support 'make check' target for simple tests #check_SCRIPTS = #TESTS = $(check_SCRIPTS) CLEANFILES = simelelecraft simicgeneric simkenwood simyaesu all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu simulators/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu simulators/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list simatd578$(EXEEXT): $(simatd578_OBJECTS) $(simatd578_DEPENDENCIES) $(EXTRA_simatd578_DEPENDENCIES) @rm -f simatd578$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simatd578_OBJECTS) $(simatd578_LDADD) $(LIBS) simelecraft$(EXEEXT): $(simelecraft_OBJECTS) $(simelecraft_DEPENDENCIES) $(EXTRA_simelecraft_DEPENDENCIES) @rm -f simelecraft$(EXEEXT) $(AM_V_CCLD)$(simelecraft_LINK) $(simelecraft_OBJECTS) $(simelecraft_LDADD) $(LIBS) simelecraftk4$(EXEEXT): $(simelecraftk4_OBJECTS) $(simelecraftk4_DEPENDENCIES) $(EXTRA_simelecraftk4_DEPENDENCIES) @rm -f simelecraftk4$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simelecraftk4_OBJECTS) $(simelecraftk4_LDADD) $(LIBS) simflex$(EXEEXT): $(simflex_OBJECTS) $(simflex_DEPENDENCIES) $(EXTRA_simflex_DEPENDENCIES) @rm -f simflex$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simflex_OBJECTS) $(simflex_LDADD) $(LIBS) simft1000$(EXEEXT): $(simft1000_OBJECTS) $(simft1000_DEPENDENCIES) $(EXTRA_simft1000_DEPENDENCIES) @rm -f simft1000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft1000_OBJECTS) $(simft1000_LDADD) $(LIBS) simft450$(EXEEXT): $(simft450_OBJECTS) $(simft450_DEPENDENCIES) $(EXTRA_simft450_DEPENDENCIES) @rm -f simft450$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft450_OBJECTS) $(simft450_LDADD) $(LIBS) simft710$(EXEEXT): $(simft710_OBJECTS) $(simft710_DEPENDENCIES) $(EXTRA_simft710_DEPENDENCIES) @rm -f simft710$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft710_OBJECTS) $(simft710_LDADD) $(LIBS) simft736$(EXEEXT): $(simft736_OBJECTS) $(simft736_DEPENDENCIES) $(EXTRA_simft736_DEPENDENCIES) @rm -f simft736$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft736_OBJECTS) $(simft736_LDADD) $(LIBS) simft817$(EXEEXT): $(simft817_OBJECTS) $(simft817_DEPENDENCIES) $(EXTRA_simft817_DEPENDENCIES) @rm -f simft817$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft817_OBJECTS) $(simft817_LDADD) $(LIBS) simft818$(EXEEXT): $(simft818_OBJECTS) $(simft818_DEPENDENCIES) $(EXTRA_simft818_DEPENDENCIES) @rm -f simft818$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft818_OBJECTS) $(simft818_LDADD) $(LIBS) simft847$(EXEEXT): $(simft847_OBJECTS) $(simft847_DEPENDENCIES) $(EXTRA_simft847_DEPENDENCIES) @rm -f simft847$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft847_OBJECTS) $(simft847_LDADD) $(LIBS) simft990$(EXEEXT): $(simft990_OBJECTS) $(simft990_DEPENDENCIES) $(EXTRA_simft990_DEPENDENCIES) @rm -f simft990$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft990_OBJECTS) $(simft990_LDADD) $(LIBS) simft991$(EXEEXT): $(simft991_OBJECTS) $(simft991_DEPENDENCIES) $(EXTRA_simft991_DEPENDENCIES) @rm -f simft991$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simft991_OBJECTS) $(simft991_LDADD) $(LIBS) simftdx101$(EXEEXT): $(simftdx101_OBJECTS) $(simftdx101_DEPENDENCIES) $(EXTRA_simftdx101_DEPENDENCIES) @rm -f simftdx101$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx101_OBJECTS) $(simftdx101_LDADD) $(LIBS) simftdx1200$(EXEEXT): $(simftdx1200_OBJECTS) $(simftdx1200_DEPENDENCIES) $(EXTRA_simftdx1200_DEPENDENCIES) @rm -f simftdx1200$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx1200_OBJECTS) $(simftdx1200_LDADD) $(LIBS) simftdx3000$(EXEEXT): $(simftdx3000_OBJECTS) $(simftdx3000_DEPENDENCIES) $(EXTRA_simftdx3000_DEPENDENCIES) @rm -f simftdx3000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx3000_OBJECTS) $(simftdx3000_LDADD) $(LIBS) simftdx5000$(EXEEXT): $(simftdx5000_OBJECTS) $(simftdx5000_DEPENDENCIES) $(EXTRA_simftdx5000_DEPENDENCIES) @rm -f simftdx5000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simftdx5000_OBJECTS) $(simftdx5000_LDADD) $(LIBS) simic2730$(EXEEXT): $(simic2730_OBJECTS) $(simic2730_DEPENDENCIES) $(EXTRA_simic2730_DEPENDENCIES) @rm -f simic2730$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic2730_OBJECTS) $(simic2730_LDADD) $(LIBS) simic275$(EXEEXT): $(simic275_OBJECTS) $(simic275_DEPENDENCIES) $(EXTRA_simic275_DEPENDENCIES) @rm -f simic275$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic275_OBJECTS) $(simic275_LDADD) $(LIBS) simic7000$(EXEEXT): $(simic7000_OBJECTS) $(simic7000_DEPENDENCIES) $(EXTRA_simic7000_DEPENDENCIES) @rm -f simic7000$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7000_OBJECTS) $(simic7000_LDADD) $(LIBS) simic705$(EXEEXT): $(simic705_OBJECTS) $(simic705_DEPENDENCIES) $(EXTRA_simic705_DEPENDENCIES) @rm -f simic705$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic705_OBJECTS) $(simic705_LDADD) $(LIBS) simic7100$(EXEEXT): $(simic7100_OBJECTS) $(simic7100_DEPENDENCIES) $(EXTRA_simic7100_DEPENDENCIES) @rm -f simic7100$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7100_OBJECTS) $(simic7100_LDADD) $(LIBS) simic7200$(EXEEXT): $(simic7200_OBJECTS) $(simic7200_DEPENDENCIES) $(EXTRA_simic7200_DEPENDENCIES) @rm -f simic7200$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7200_OBJECTS) $(simic7200_LDADD) $(LIBS) simic7300$(EXEEXT): $(simic7300_OBJECTS) $(simic7300_DEPENDENCIES) $(EXTRA_simic7300_DEPENDENCIES) @rm -f simic7300$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7300_OBJECTS) $(simic7300_LDADD) $(LIBS) simic7600$(EXEEXT): $(simic7600_OBJECTS) $(simic7600_DEPENDENCIES) $(EXTRA_simic7600_DEPENDENCIES) @rm -f simic7600$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7600_OBJECTS) $(simic7600_LDADD) $(LIBS) simic7610$(EXEEXT): $(simic7610_OBJECTS) $(simic7610_DEPENDENCIES) $(EXTRA_simic7610_DEPENDENCIES) @rm -f simic7610$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7610_OBJECTS) $(simic7610_LDADD) $(LIBS) simic7700$(EXEEXT): $(simic7700_OBJECTS) $(simic7700_DEPENDENCIES) $(EXTRA_simic7700_DEPENDENCIES) @rm -f simic7700$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7700_OBJECTS) $(simic7700_LDADD) $(LIBS) simic7851$(EXEEXT): $(simic7851_OBJECTS) $(simic7851_DEPENDENCIES) $(EXTRA_simic7851_DEPENDENCIES) @rm -f simic7851$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic7851_OBJECTS) $(simic7851_LDADD) $(LIBS) simic905$(EXEEXT): $(simic905_OBJECTS) $(simic905_DEPENDENCIES) $(EXTRA_simic905_DEPENDENCIES) @rm -f simic905$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic905_OBJECTS) $(simic905_LDADD) $(LIBS) simic910$(EXEEXT): $(simic910_OBJECTS) $(simic910_DEPENDENCIES) $(EXTRA_simic910_DEPENDENCIES) @rm -f simic910$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic910_OBJECTS) $(simic910_LDADD) $(LIBS) simic9100$(EXEEXT): $(simic9100_OBJECTS) $(simic9100_DEPENDENCIES) $(EXTRA_simic9100_DEPENDENCIES) @rm -f simic9100$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic9100_OBJECTS) $(simic9100_LDADD) $(LIBS) simic9700$(EXEEXT): $(simic9700_OBJECTS) $(simic9700_DEPENDENCIES) $(EXTRA_simic9700_DEPENDENCIES) @rm -f simic9700$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simic9700_OBJECTS) $(simic9700_LDADD) $(LIBS) simicgeneric$(EXEEXT): $(simicgeneric_OBJECTS) $(simicgeneric_DEPENDENCIES) $(EXTRA_simicgeneric_DEPENDENCIES) @rm -f simicgeneric$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simicgeneric_OBJECTS) $(simicgeneric_LDADD) $(LIBS) simid5100$(EXEEXT): $(simid5100_OBJECTS) $(simid5100_DEPENDENCIES) $(EXTRA_simid5100_DEPENDENCIES) @rm -f simid5100$(EXEEXT) $(AM_V_CCLD)$(simid5100_LINK) $(simid5100_OBJECTS) $(simid5100_LDADD) $(LIBS) simjupiter$(EXEEXT): $(simjupiter_OBJECTS) $(simjupiter_DEPENDENCIES) $(EXTRA_simjupiter_DEPENDENCIES) @rm -f simjupiter$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simjupiter_OBJECTS) $(simjupiter_LDADD) $(LIBS) simkenwood$(EXEEXT): $(simkenwood_OBJECTS) $(simkenwood_DEPENDENCIES) $(EXTRA_simkenwood_DEPENDENCIES) @rm -f simkenwood$(EXEEXT) $(AM_V_CCLD)$(simkenwood_LINK) $(simkenwood_OBJECTS) $(simkenwood_LDADD) $(LIBS) simmicom$(EXEEXT): $(simmicom_OBJECTS) $(simmicom_DEPENDENCIES) $(EXTRA_simmicom_DEPENDENCIES) @rm -f simmicom$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simmicom_OBJECTS) $(simmicom_LDADD) $(LIBS) simorion$(EXEEXT): $(simorion_OBJECTS) $(simorion_DEPENDENCIES) $(EXTRA_simorion_DEPENDENCIES) @rm -f simorion$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simorion_OBJECTS) $(simorion_LDADD) $(LIBS) simpmr171$(EXEEXT): $(simpmr171_OBJECTS) $(simpmr171_DEPENDENCIES) $(EXTRA_simpmr171_DEPENDENCIES) @rm -f simpmr171$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simpmr171_OBJECTS) $(simpmr171_LDADD) $(LIBS) simpowersdr$(EXEEXT): $(simpowersdr_OBJECTS) $(simpowersdr_DEPENDENCIES) $(EXTRA_simpowersdr_DEPENDENCIES) @rm -f simpowersdr$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simpowersdr_OBJECTS) $(simpowersdr_LDADD) $(LIBS) simpstrotator$(EXEEXT): $(simpstrotator_OBJECTS) $(simpstrotator_DEPENDENCIES) $(EXTRA_simpstrotator_DEPENDENCIES) @rm -f simpstrotator$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simpstrotator_OBJECTS) $(simpstrotator_LDADD) $(LIBS) simqrplabs$(EXEEXT): $(simqrplabs_OBJECTS) $(simqrplabs_DEPENDENCIES) $(EXTRA_simqrplabs_DEPENDENCIES) @rm -f simqrplabs$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simqrplabs_OBJECTS) $(simqrplabs_LDADD) $(LIBS) simrotorez$(EXEEXT): $(simrotorez_OBJECTS) $(simrotorez_DEPENDENCIES) $(EXTRA_simrotorez_DEPENDENCIES) @rm -f simrotorez$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simrotorez_OBJECTS) $(simrotorez_LDADD) $(LIBS) simspid$(EXEEXT): $(simspid_OBJECTS) $(simspid_DEPENDENCIES) $(EXTRA_simspid_DEPENDENCIES) @rm -f simspid$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simspid_OBJECTS) $(simspid_LDADD) $(LIBS) simtmd700$(EXEEXT): $(simtmd700_OBJECTS) $(simtmd700_DEPENDENCIES) $(EXTRA_simtmd700_DEPENDENCIES) @rm -f simtmd700$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simtmd700_OBJECTS) $(simtmd700_LDADD) $(LIBS) simtmd710$(EXEEXT): $(simtmd710_OBJECTS) $(simtmd710_DEPENDENCIES) $(EXTRA_simtmd710_DEPENDENCIES) @rm -f simtmd710$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simtmd710_OBJECTS) $(simtmd710_LDADD) $(LIBS) simtrusdx$(EXEEXT): $(simtrusdx_OBJECTS) $(simtrusdx_DEPENDENCIES) $(EXTRA_simtrusdx_DEPENDENCIES) @rm -f simtrusdx$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simtrusdx_OBJECTS) $(simtrusdx_LDADD) $(LIBS) simts450$(EXEEXT): $(simts450_OBJECTS) $(simts450_DEPENDENCIES) $(EXTRA_simts450_DEPENDENCIES) @rm -f simts450$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts450_OBJECTS) $(simts450_LDADD) $(LIBS) simts590$(EXEEXT): $(simts590_OBJECTS) $(simts590_DEPENDENCIES) $(EXTRA_simts590_DEPENDENCIES) @rm -f simts590$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts590_OBJECTS) $(simts590_LDADD) $(LIBS) simts890$(EXEEXT): $(simts890_OBJECTS) $(simts890_DEPENDENCIES) $(EXTRA_simts890_DEPENDENCIES) @rm -f simts890$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts890_OBJECTS) $(simts890_LDADD) $(LIBS) simts950$(EXEEXT): $(simts950_OBJECTS) $(simts950_DEPENDENCIES) $(EXTRA_simts950_DEPENDENCIES) @rm -f simts950$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts950_OBJECTS) $(simts950_LDADD) $(LIBS) simts990$(EXEEXT): $(simts990_OBJECTS) $(simts990_DEPENDENCIES) $(EXTRA_simts990_DEPENDENCIES) @rm -f simts990$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simts990_OBJECTS) $(simts990_LDADD) $(LIBS) simxiegug90$(EXEEXT): $(simxiegug90_OBJECTS) $(simxiegug90_DEPENDENCIES) $(EXTRA_simxiegug90_DEPENDENCIES) @rm -f simxiegug90$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simxiegug90_OBJECTS) $(simxiegug90_LDADD) $(LIBS) simxiegux108g$(EXEEXT): $(simxiegux108g_OBJECTS) $(simxiegux108g_DEPENDENCIES) $(EXTRA_simxiegux108g_DEPENDENCIES) @rm -f simxiegux108g$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simxiegux108g_OBJECTS) $(simxiegux108g_LDADD) $(LIBS) simxiegux6100$(EXEEXT): $(simxiegux6100_OBJECTS) $(simxiegux6100_DEPENDENCIES) $(EXTRA_simxiegux6100_DEPENDENCIES) @rm -f simxiegux6100$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simxiegux6100_OBJECTS) $(simxiegux6100_LDADD) $(LIBS) simyaesu$(EXEEXT): $(simyaesu_OBJECTS) $(simyaesu_DEPENDENCIES) $(EXTRA_simyaesu_DEPENDENCIES) @rm -f simyaesu$(EXEEXT) $(AM_V_CCLD)$(simyaesu_LINK) $(simyaesu_OBJECTS) $(simyaesu_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simatd578.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simelecraft-simelecraft.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simelecraftk4.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simflex.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft1000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft450.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft710.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft736.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft817.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft818.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft847.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft990.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simft991.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx101.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx1200.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx3000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simftdx5000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic2730.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic275.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7000.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic705.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7200.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7300.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7600.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7610.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7700.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic7851.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic905.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic910.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic9100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simic9700.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simicgeneric.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simid5100-simid5100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simjupiter.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simkenwood-simkenwood.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simmicom.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simorion.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpmr171.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpowersdr.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simpstrotator.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simqrplabs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simrotorez.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simspid.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simtmd700.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simtmd710.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simtrusdx.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts450.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts590.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts890.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts950.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simts990.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simxiegug90.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simxiegux108g.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simxiegux6100.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simyaesu-simyaesu.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< simelecraft-simelecraft.o: simelecraft.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -MT simelecraft-simelecraft.o -MD -MP -MF $(DEPDIR)/simelecraft-simelecraft.Tpo -c -o simelecraft-simelecraft.o `test -f 'simelecraft.c' || echo '$(srcdir)/'`simelecraft.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simelecraft-simelecraft.Tpo $(DEPDIR)/simelecraft-simelecraft.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simelecraft.c' object='simelecraft-simelecraft.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -c -o simelecraft-simelecraft.o `test -f 'simelecraft.c' || echo '$(srcdir)/'`simelecraft.c simelecraft-simelecraft.obj: simelecraft.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -MT simelecraft-simelecraft.obj -MD -MP -MF $(DEPDIR)/simelecraft-simelecraft.Tpo -c -o simelecraft-simelecraft.obj `if test -f 'simelecraft.c'; then $(CYGPATH_W) 'simelecraft.c'; else $(CYGPATH_W) '$(srcdir)/simelecraft.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simelecraft-simelecraft.Tpo $(DEPDIR)/simelecraft-simelecraft.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simelecraft.c' object='simelecraft-simelecraft.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simelecraft_CFLAGS) $(CFLAGS) -c -o simelecraft-simelecraft.obj `if test -f 'simelecraft.c'; then $(CYGPATH_W) 'simelecraft.c'; else $(CYGPATH_W) '$(srcdir)/simelecraft.c'; fi` simid5100-simid5100.o: simid5100.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -MT simid5100-simid5100.o -MD -MP -MF $(DEPDIR)/simid5100-simid5100.Tpo -c -o simid5100-simid5100.o `test -f 'simid5100.c' || echo '$(srcdir)/'`simid5100.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simid5100-simid5100.Tpo $(DEPDIR)/simid5100-simid5100.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simid5100.c' object='simid5100-simid5100.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -c -o simid5100-simid5100.o `test -f 'simid5100.c' || echo '$(srcdir)/'`simid5100.c simid5100-simid5100.obj: simid5100.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -MT simid5100-simid5100.obj -MD -MP -MF $(DEPDIR)/simid5100-simid5100.Tpo -c -o simid5100-simid5100.obj `if test -f 'simid5100.c'; then $(CYGPATH_W) 'simid5100.c'; else $(CYGPATH_W) '$(srcdir)/simid5100.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simid5100-simid5100.Tpo $(DEPDIR)/simid5100-simid5100.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simid5100.c' object='simid5100-simid5100.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simid5100_CFLAGS) $(CFLAGS) -c -o simid5100-simid5100.obj `if test -f 'simid5100.c'; then $(CYGPATH_W) 'simid5100.c'; else $(CYGPATH_W) '$(srcdir)/simid5100.c'; fi` simkenwood-simkenwood.o: simkenwood.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -MT simkenwood-simkenwood.o -MD -MP -MF $(DEPDIR)/simkenwood-simkenwood.Tpo -c -o simkenwood-simkenwood.o `test -f 'simkenwood.c' || echo '$(srcdir)/'`simkenwood.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simkenwood-simkenwood.Tpo $(DEPDIR)/simkenwood-simkenwood.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simkenwood.c' object='simkenwood-simkenwood.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -c -o simkenwood-simkenwood.o `test -f 'simkenwood.c' || echo '$(srcdir)/'`simkenwood.c simkenwood-simkenwood.obj: simkenwood.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -MT simkenwood-simkenwood.obj -MD -MP -MF $(DEPDIR)/simkenwood-simkenwood.Tpo -c -o simkenwood-simkenwood.obj `if test -f 'simkenwood.c'; then $(CYGPATH_W) 'simkenwood.c'; else $(CYGPATH_W) '$(srcdir)/simkenwood.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simkenwood-simkenwood.Tpo $(DEPDIR)/simkenwood-simkenwood.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simkenwood.c' object='simkenwood-simkenwood.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simkenwood_CFLAGS) $(CFLAGS) -c -o simkenwood-simkenwood.obj `if test -f 'simkenwood.c'; then $(CYGPATH_W) 'simkenwood.c'; else $(CYGPATH_W) '$(srcdir)/simkenwood.c'; fi` simyaesu-simyaesu.o: simyaesu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -MT simyaesu-simyaesu.o -MD -MP -MF $(DEPDIR)/simyaesu-simyaesu.Tpo -c -o simyaesu-simyaesu.o `test -f 'simyaesu.c' || echo '$(srcdir)/'`simyaesu.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simyaesu-simyaesu.Tpo $(DEPDIR)/simyaesu-simyaesu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simyaesu.c' object='simyaesu-simyaesu.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -c -o simyaesu-simyaesu.o `test -f 'simyaesu.c' || echo '$(srcdir)/'`simyaesu.c simyaesu-simyaesu.obj: simyaesu.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -MT simyaesu-simyaesu.obj -MD -MP -MF $(DEPDIR)/simyaesu-simyaesu.Tpo -c -o simyaesu-simyaesu.obj `if test -f 'simyaesu.c'; then $(CYGPATH_W) 'simyaesu.c'; else $(CYGPATH_W) '$(srcdir)/simyaesu.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simyaesu-simyaesu.Tpo $(DEPDIR)/simyaesu-simyaesu.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='simyaesu.c' object='simyaesu-simyaesu.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simyaesu_CFLAGS) $(CFLAGS) -c -o simyaesu-simyaesu.obj `if test -f 'simyaesu.c'; then $(CYGPATH_W) 'simyaesu.c'; else $(CYGPATH_W) '$(srcdir)/simyaesu.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) check: check-am all-am: Makefile $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool mostlyclean-am distclean: distclean-am -rm -f ./$(DEPDIR)/simatd578.Po -rm -f ./$(DEPDIR)/simelecraft-simelecraft.Po -rm -f ./$(DEPDIR)/simelecraftk4.Po -rm -f ./$(DEPDIR)/simflex.Po -rm -f ./$(DEPDIR)/simft1000.Po -rm -f ./$(DEPDIR)/simft450.Po -rm -f ./$(DEPDIR)/simft710.Po -rm -f ./$(DEPDIR)/simft736.Po -rm -f ./$(DEPDIR)/simft817.Po -rm -f ./$(DEPDIR)/simft818.Po -rm -f ./$(DEPDIR)/simft847.Po -rm -f ./$(DEPDIR)/simft990.Po -rm -f ./$(DEPDIR)/simft991.Po -rm -f ./$(DEPDIR)/simftdx101.Po -rm -f ./$(DEPDIR)/simftdx1200.Po -rm -f ./$(DEPDIR)/simftdx3000.Po -rm -f ./$(DEPDIR)/simftdx5000.Po -rm -f ./$(DEPDIR)/simic2730.Po -rm -f ./$(DEPDIR)/simic275.Po -rm -f ./$(DEPDIR)/simic7000.Po -rm -f ./$(DEPDIR)/simic705.Po -rm -f ./$(DEPDIR)/simic7100.Po -rm -f ./$(DEPDIR)/simic7200.Po -rm -f ./$(DEPDIR)/simic7300.Po -rm -f ./$(DEPDIR)/simic7600.Po -rm -f ./$(DEPDIR)/simic7610.Po -rm -f ./$(DEPDIR)/simic7700.Po -rm -f ./$(DEPDIR)/simic7851.Po -rm -f ./$(DEPDIR)/simic905.Po -rm -f ./$(DEPDIR)/simic910.Po -rm -f ./$(DEPDIR)/simic9100.Po -rm -f ./$(DEPDIR)/simic9700.Po -rm -f ./$(DEPDIR)/simicgeneric.Po -rm -f ./$(DEPDIR)/simid5100-simid5100.Po -rm -f ./$(DEPDIR)/simjupiter.Po -rm -f ./$(DEPDIR)/simkenwood-simkenwood.Po -rm -f ./$(DEPDIR)/simmicom.Po -rm -f ./$(DEPDIR)/simorion.Po -rm -f ./$(DEPDIR)/simpmr171.Po -rm -f ./$(DEPDIR)/simpowersdr.Po -rm -f ./$(DEPDIR)/simpstrotator.Po -rm -f ./$(DEPDIR)/simqrplabs.Po -rm -f ./$(DEPDIR)/simrotorez.Po -rm -f ./$(DEPDIR)/simspid.Po -rm -f ./$(DEPDIR)/simtmd700.Po -rm -f ./$(DEPDIR)/simtmd710.Po -rm -f ./$(DEPDIR)/simtrusdx.Po -rm -f ./$(DEPDIR)/simts450.Po -rm -f ./$(DEPDIR)/simts590.Po -rm -f ./$(DEPDIR)/simts890.Po -rm -f ./$(DEPDIR)/simts950.Po -rm -f ./$(DEPDIR)/simts990.Po -rm -f ./$(DEPDIR)/simxiegug90.Po -rm -f ./$(DEPDIR)/simxiegux108g.Po -rm -f ./$(DEPDIR)/simxiegux6100.Po -rm -f ./$(DEPDIR)/simyaesu-simyaesu.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/simatd578.Po -rm -f ./$(DEPDIR)/simelecraft-simelecraft.Po -rm -f ./$(DEPDIR)/simelecraftk4.Po -rm -f ./$(DEPDIR)/simflex.Po -rm -f ./$(DEPDIR)/simft1000.Po -rm -f ./$(DEPDIR)/simft450.Po -rm -f ./$(DEPDIR)/simft710.Po -rm -f ./$(DEPDIR)/simft736.Po -rm -f ./$(DEPDIR)/simft817.Po -rm -f ./$(DEPDIR)/simft818.Po -rm -f ./$(DEPDIR)/simft847.Po -rm -f ./$(DEPDIR)/simft990.Po -rm -f ./$(DEPDIR)/simft991.Po -rm -f ./$(DEPDIR)/simftdx101.Po -rm -f ./$(DEPDIR)/simftdx1200.Po -rm -f ./$(DEPDIR)/simftdx3000.Po -rm -f ./$(DEPDIR)/simftdx5000.Po -rm -f ./$(DEPDIR)/simic2730.Po -rm -f ./$(DEPDIR)/simic275.Po -rm -f ./$(DEPDIR)/simic7000.Po -rm -f ./$(DEPDIR)/simic705.Po -rm -f ./$(DEPDIR)/simic7100.Po -rm -f ./$(DEPDIR)/simic7200.Po -rm -f ./$(DEPDIR)/simic7300.Po -rm -f ./$(DEPDIR)/simic7600.Po -rm -f ./$(DEPDIR)/simic7610.Po -rm -f ./$(DEPDIR)/simic7700.Po -rm -f ./$(DEPDIR)/simic7851.Po -rm -f ./$(DEPDIR)/simic905.Po -rm -f ./$(DEPDIR)/simic910.Po -rm -f ./$(DEPDIR)/simic9100.Po -rm -f ./$(DEPDIR)/simic9700.Po -rm -f ./$(DEPDIR)/simicgeneric.Po -rm -f ./$(DEPDIR)/simid5100-simid5100.Po -rm -f ./$(DEPDIR)/simjupiter.Po -rm -f ./$(DEPDIR)/simkenwood-simkenwood.Po -rm -f ./$(DEPDIR)/simmicom.Po -rm -f ./$(DEPDIR)/simorion.Po -rm -f ./$(DEPDIR)/simpmr171.Po -rm -f ./$(DEPDIR)/simpowersdr.Po -rm -f ./$(DEPDIR)/simpstrotator.Po -rm -f ./$(DEPDIR)/simqrplabs.Po -rm -f ./$(DEPDIR)/simrotorez.Po -rm -f ./$(DEPDIR)/simspid.Po -rm -f ./$(DEPDIR)/simtmd700.Po -rm -f ./$(DEPDIR)/simtmd710.Po -rm -f ./$(DEPDIR)/simtrusdx.Po -rm -f ./$(DEPDIR)/simts450.Po -rm -f ./$(DEPDIR)/simts590.Po -rm -f ./$(DEPDIR)/simts890.Po -rm -f ./$(DEPDIR)/simts950.Po -rm -f ./$(DEPDIR)/simts990.Po -rm -f ./$(DEPDIR)/simxiegug90.Po -rm -f ./$(DEPDIR)/simxiegux108g.Po -rm -f ./$(DEPDIR)/simxiegux6100.Po -rm -f ./$(DEPDIR)/simyaesu-simyaesu.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/simulators/simic9700.c0000644000175000017500000003454614752216205013712 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include "sim.h" #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 dualwatch = 0; int satmode = 0; int agc_time = 1; int ovf_status = 0; int powerstat = 1; int keyspd = 90; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; 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) { 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; 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; 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; 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; 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; WRITE(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; 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); 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); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); 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; WRITE(fd, frame, 9); break; } case 0x0c: if (frame[6] != 0xfd) { frame[6] = 0xfb; dumphex(frame, 7); WRITE(fd, frame, 7); printf("ACK x14 x0c\n"); } else { frame[6] = 0; frame[7] = keyspd; frame[8] = 0xfd; dumphex(frame, 9); WRITE(fd, frame, 9); printf("SEND x14 x0c\n"); } break; case 0x15: switch (frame[5]) { static int meter_level = 0; case 0x07: frame[6] = ovf_status; frame[7] = 0xfd; 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; WRITE(fd, frame, 9); break; } case 0x16: switch (frame[5]) { case 0x59: if (frame[6] == 0xfe) { dualwatch = frame[6]; } else { frame[6] = dualwatch; frame[7] = 0xfd; WRITE(fd, frame, 8); } break; case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; WRITE(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; 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; 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; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; 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("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; 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; WRITE(fd, frame2, 11); 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; 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; 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; 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; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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; } hamlib-4.6.2/simulators/simic7610.c0000644000175000017500000005072014752216205013700 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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; int keyspd = 130; // 130=20WPM int ipp = 0; int tx_inhibit = 0; int dpp = 0; int dualwatch = 0; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: switch (frame[5]) { case 0xd0: current_vfo = RIG_VFO_A; break; case 0xd1: current_vfo = RIG_VFO_B; break; case 0xc2: if (frame[6] == 0xfd) { frame[6] = dualwatch; frame[7] = 0xfd; n = write(fd,frame,8); } else { dualwatch = frame[6]; frame[4]=0xfb; frame[5]=0xfd; n = write(fd,frame,6); } } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: printf("******** 0x14 received frame[5]=0x%02x\n", frame[5]); 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: if (frame[6] != 0xfd) { keyspd = frame[5]; } else { frame[6] = keyspd; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; default: printf("*********** NAK\n"); frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; default: frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x5a: if (frame[6] == 0xfd) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x65: if (frame[6] == 0xfd) { ipp = frame[6]; } else { frame[6] = ipp; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x66: if (frame[6] == 0xfd) { tx_inhibit = frame[6]; } else { frame[6] = tx_inhibit; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x67: if (frame[6] == 0xfd) { dpp = frame[6]; } else { frame[6] = dpp; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // satmode if (frame[6] == 0xfd) // then we are reading { frame[6] = datamode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamode = frame[6]; frame[4] = 0xfd; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } // 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); printf("#1 ========================================\n"); if (len <= 0) { printf("#2 ========================================"); close(fd); fd = openPort(argv[1]); } if (powerstat) { frameParse(fd, buf, len); } else { hl_usleep(100 * 1000); } printf("#3 ========================================"); rigStatus(); printf("#3 ========================================"); } return 0; } hamlib-4.6.2/simulators/simft450.c0000644000175000017500000003630214752216205013631 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int ks = 20; int bandselect = 5; int width = 21; int narrow = 0; int vd = 0; int sm0 = 0; int sm1 = 0; int vs = 0; int vx = 0; int pa = 0; int ra = 0; int ag = 0; int pc = 100; int is = 0; int bp_on = 0; int bp_pos = 0; int rl = 0; int nb = 0; int nr = 0; int tx = 0; int mg = 0; int rg = 100; int vg = 0; int kr = 0; int bi = 0; int gt = 0; int ex016 = 0; int ex020 = 0; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { if (getmyline(fd, buf)) { // printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, ";") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RM4;") == 0) { hl_usleep(50 * 1000); pbuf = "RM4100;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("RM4"); } } else if (strcmp(buf, "RM5;") == 0) { hl_usleep(50 * 1000); pbuf = "RM4100000;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "RM6;") == 0) { hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "ID;") == 0) { hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "AI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "FT%c;", tx_vfo); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; } else if (strcmp(buf, "MD0;") == 0) { printf("MD=%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD0%c;", modeA); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD1%c;", modeB); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VS"); } } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "KR;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "KR%d;", kr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("KR"); } } else if (strncmp(buf, "KR", 2) == 0) { sscanf(buf, "KR%d", &kr); } else if (strcmp(buf, "BI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BI%d;", bi); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BI"); } } else if (strncmp(buf, "BI", 2) == 0) { sscanf(buf, "BI%d", &bi); } else if (strcmp(buf, "VX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VX%d;", vx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VX"); } } else if (strncmp(buf, "VX", 2) == 0) { sscanf(buf, "VX%d", &vx); } else if (strcmp(buf, "PA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PA%d;", pa); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PA"); } } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d", &vs); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RA%d;", ra); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RA"); } } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d", &ra); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AG%d;", ag); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("AG"); } } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &ag); } else if (strcmp(buf, "PC;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PC%03d;", pc); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PC"); } } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "VG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VG%03d;", vg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VG"); } } else if (strncmp(buf, "VG", 2) == 0) { sscanf(buf, "VG%d", &vg); } else if (strcmp(buf, "RG0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RG0%03d;", rg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RG"); } } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG0%d", &rg); } else if (strcmp(buf, "GT0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "GT0%0d;", gt); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("GT"); } } else if (strncmp(buf, "GT", 2) == 0) { sscanf(buf, "GT0%d", >); } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "IS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "IS+%04d;", is); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("IS"); } } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS%d", &is); } else if (strcmp(buf, "RL0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RL0%d;", rl); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RL"); } } else if (strncmp(buf, "RL", 2) == 0) { sscanf(buf, "RL0%02d", &rl); } else if (strcmp(buf, "BP00;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_on); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP00", 4) == 0) { sscanf(buf, "BP00%d", &bp_on); } else if (strcmp(buf, "BP01;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_pos); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP01", 4) == 0) { sscanf(buf, "BP01%d", &bp_pos); } else if (strcmp(buf, "NB0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NB0%d;", nb); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NB"); } } else if (strncmp(buf, "NB0", 3) == 0) { sscanf(buf, "NB0%d", &nb); } else if (strcmp(buf, "NR0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NR0%d;", nr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NR"); } } else if (strncmp(buf, "NR0", 3) == 0) { sscanf(buf, "NR0%d", &nr); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "EX016;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX016%04d;", ex016); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strcmp(buf, "EX020;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX020%04d;", ex020); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strncmp(buf, "EX020", 5) == 0) { sscanf(buf, "EX020%d\n", &ex020); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", ks); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &ks); } else if (strncmp(buf, "MG;", 3) == 0) { sprintf(buf, "MG%03d;", mg); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%03d", &mg); } else if (strncmp(buf, "BS;", 3) == 0) // cannot query BS { sprintf(buf, "BS%02d;", bandselect); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0;", 4) == 0) { sprintf(buf, "SH0%02d;", width); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%02d", &width); } else if (strncmp(buf, "NA0;", 4) == 0) { sprintf(buf, "NA0%d;", narrow); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &narrow); } else if (strncmp(buf, "VD;", 3) == 0) { sprintf(buf, "VD%d;", vd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VD", 2) == 0) { sscanf(buf, "VD%d", &vd); } else if (strncmp(buf, "SM0;", 4) == 0) { sprintf(buf, "SM0%d;", sm0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM0", 3) == 0) { sscanf(buf, "SM0%3d", &sm0); } else if (strncmp(buf, "SM1;", 4) == 0) { sprintf(buf, "SM1%d;", sm1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM1", 3) == 0) { sscanf(buf, "SM1%3d", &sm1); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simmicom.c0000644000175000017500000000471714752216205014100 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simspid simspid.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #include "../src/misc.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { int i = 0; int n = 0; memset(buf, 0, BUFSIZE); n = read(fd, buf, 4); if (n <= 0) { sleep(1); return 0;} int bytesToRead = buf[1] + 2; //; len does not include cksum, or eom n += read(fd, &buf[4], bytesToRead); printf("n=%d:", n); for (i = 0; i < n; ++i) { printf(" %02x", buf[i]); } printf("\n"); return n; } #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[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } switch (buf[3]) { case 0x06: printf("Report receiver freq\n"); unsigned char cmd[11] = { 0x24, 0x06, 0x18, 0x05, 0x01, 0x00, 0x38, 0xea, 0x50, 0xba, 0x03}; dump_hex(cmd, 11); int n = write(fd, cmd, sizeof(cmd)); printf("%d bytes sent\n", n); break; case 0x13: printf("PTT On\n"); break; case 0x14: printf("PTT Off\n"); break; case 0x36: printf("Key request\n"); break; default: printf("Unknown cmd=%02x\n", buf[3]); } } return 0; } hamlib-4.6.2/simulators/simtrusdx.c0000644000175000017500000002172214752216205014320 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #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 keyspd = 25; 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); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 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;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } 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 ; WRITE(fd, ifbuf, strlen(ifbuf)); } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "IS", 2) == 0) { } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; WRITE(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "FW", 2) == 0) { } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "ID%03d;", 20); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } 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); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX", 2) == 0) { } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "AI", 2) == 0) { // nothing to do yet } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); 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'); WRITE(fd, buf, strlen(buf)); } 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); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", vfo_tx); WRITE(fd, buf, strlen(buf)); } 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); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); } else if (strncmp(buf, "TO;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TO%d;", tomode); } else if (strncmp(buf, "BD;", 3) == 0) { } else if (strncmp(buf, "BU;", 3) == 0) { } 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; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simftdx3000.c0000644000175000017500000001555014752216205014241 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int md = 1; int vs = 0; int tx = 0; int ai = 0; int sh = 25; int na = 0; int ex039 = 0; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 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) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { int val = ft; if (ft == 2) { val = 0; } else if (ft == 3) { val = 1; } SNPRINTF(buf, sizeof(buf), "FT%d;", val); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) { sscanf(buf, "FT%d", &ft); } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%d;", md); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD0", 3) == 0) { sscanf(buf, "MD0%d", &md); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simpowersdr.c0000644000175000017500000003176414752216205014643 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int filternum = 7; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int keyspd = 20; double alc = 0; int tx; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 = 0; // , modeB = 0; 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(50 * 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(50 * 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(50 * 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, "FV;") == 0) { hl_usleep(50 * 1000); pbuf = "FV1.2;"; n = write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FW;") == 0) { hl_usleep(50 * 1000); pbuf = "FW2400;"; n = write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); // printf("n=%d\n", n); if (n <= 0) { perror("ID"); } continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 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(50 * 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 (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; } 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 (strncmp(buf, "ZZMD;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZMD%d;", modeA); // not worried about modeB yet for simulator n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "ZZMD", 4) == 0) { sscanf(buf, "ZZMD%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, "ZZFL;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZFL+%04d;", 100); n = write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "ZZFH;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZFH+%04d;", 3500); 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, "BD;", 3) == 0) { continue; } else if (strncmp(buf, "BU;", 3) == 0) { continue; } else if (strncmp(buf, "ZZMN", 4) == 0) { SNPRINTF(buf, sizeof(buf), "ZZMN01 5.0k 5100 100 4.4k 4500 100 3.8k 3900 100 3.3k 3400 100 2.9k 3000 100 2.7k 2800 100 2.4k 2500 100 2.1k 2200 100 1.8k 1900 100 1.0k 1100 100Var 1 3150 100Var 2 2800 100;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZSQ000;", 5) == 0) { continue; } else if (strncmp(buf, "ZZAR;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZAR+068;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "NT;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "NT0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "AG0;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "AG0000;"); 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 (strncmp(buf, "ZZSQ;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZSQ000;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZMG;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZMG+00;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZNA;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZNA0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZNR;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZNR0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZNS;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZNS0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZSM0;", 6) == 0) { SNPRINTF(buf, sizeof(buf), "ZZSM0%d;", 140); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZSP;", 6) == 0) { SNPRINTF(buf, sizeof(buf), "ZZSP0;"); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZFI;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZFI%d;", 10); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZTU;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZTU%d;", 0); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZTX;", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZTX%d;", ptt); n = write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "ZZTX", 4) == 0) { printf("******** ZZTX[%c]\n", buf[4]); switch (buf[4]) { case '1': ptt = 1; break; case '0': ptt = 0; break; } continue; } else if (strncmp(buf, "KS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "KS%03d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%d", &keyspd); } else if (strncmp(buf, "ZZRM4", 5) == 0) { SNPRINTF(buf, sizeof(buf), "ZZRM4%2.0f dB;", alc); n = write(fd, buf, strlen(buf)); alc += 1; if (alc > 40) { alc = -20; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simic7851.c0000644000175000017500000005422114752216205013707 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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 = 1; mode_t modeB = 0; int datamodeA = 1; int datamodeB = 1; int filterA = 3; int filterB = 2; 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; int keyspd = 130; // 130=20WPM int attenuator; int notch = 0; int speechcompressor = 0; int vox = 0; void dumphex(const 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 = 0xff; again: while (read(fd, &c, 1) > 0) { buf[i++] = c; //printf("i=%d, c=0x%02x\n",i,c); if (c == 0xfd) { // printf("Read: "); // 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } //dumphex(frame, len); if (len == 0) { printf("%s: len==0\n", __func__); return; } if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int echo = 0; // cppcheck-suppress knownConditionTrueFalse if (echo) { n = write(fd, frame, len); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } frame[3] = frame[2]; frame[2] = 0xe0; 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: //printf("******* [5] = 0x07\n"); switch (frame[5]) { case 0xd2: //printf("******* [6] = 0x07\n"); switch (frame[6]) { case 0x00: current_vfo = RIG_VFO_MAIN; break; case 0x01: current_vfo = RIG_VFO_SUB; break; } } //printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; //printf("0x07 0xd2 answer: \n"); dump_hex(frame, 6); n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { //printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x11: if (frame[5] != 0xfd) { attenuator = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { frame[5] = attenuator; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: //printf("******** 0x14 received frame[5]=0x%02x\n", frame[5]); switch (frame[5]) { static int power_level = 0; case 0x07: case 0x08: if (frame[6] != 0xfd) { //printf("DEBUG#1\n"); frame[4] = 0xfb; frame[5] = 0xfd; dumphex(frame, 6); n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } //printf("ACK x14 x08\n"); } else { //printf("DEBUG#2\n"); to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; frame[9] = 0xfd; dumphex(frame, 10); n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } //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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x0c: if (frame[6] != 0xfd) { keyspd = frame[5]; } else { frame[6] = keyspd; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; default: //printf("*********** NAK\n"); frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; default: frame[5] = 0xfa; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x44: if (frame[6] == 0xfe) { frame[6] = speechcompressor; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { speechcompressor = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x46: if (frame[6] == 0xfe) { frame[6] = vox; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { vox = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x48: if (frame[6] == 0xfe) { frame[6] = notch; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { notch = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { //printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // satmode if (frame[6] == 0xfd) // then we are reading { frame[6] = datamode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamode = frame[6]; frame[4] = 0xfd; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } // 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x26: for (int i = 0; i < 7; ++i) { printf("%02x:", frame[i]); } if (frame[6] == 0xfd) // then a query { printf("GET MODE XXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"); // fe fe e0 8e 26 00 01 00 01 fd // 0 1 2 3 4 5 6 7 8 // AB MD DM FF frame[6] = frame[5] == 0 ? modeA : modeB; frame[7] = frame[5] == 0 ? datamodeA : datamodeB; frame[8] = frame[5] == 0 ? filterA : filterB; frame[9] = 0xfd; printf("x26 response: "); dumphex(frame, 10); n = write(fd, frame, 10); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("SET MODE YYYYYYYYYYYYYYYYYYYYYYYYYYYYY\n"); for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; filterA = frame[8]; } else { modeB = frame[6]; datamodeB = frame[7]; filterB = frame[8]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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; } hamlib-4.6.2/simulators/simxiegux6100.c0000644000175000017500000002574614752216205014621 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #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_CW; mode_t modeB = RIG_MODE_USB; 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 keyspd = 20; void dumphex(const 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; 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; } } //printf("Error %s\n", strerror(errno)); 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; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; 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; 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 0xb0: freq = freqA; freqA = freqB; freqB = freq; 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 { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); break; #if 0 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("n=n = write 8 bytes\n"); dump_hex(frame, 8); n = write(fd, frame, 8); break; #endif case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; n = write(fd, frame, 9); 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; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; 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; } break; #if 0 case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); break; #endif case 0x19: frame[6] = 0x61; frame[7] = 0x00; frame[8] = 0xfd; n = write(fd, frame, 9); 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; } 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("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; 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); } 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[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // don't care about the rig type yet if (n == 0) printf("write failed?\n"); } #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]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.2/simulators/simic7100.c0000644000175000017500000003075514752216205013700 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #undef ECHO #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 keyspd = 20; void dumphex(const 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) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); #ifdef ECHO // echo n = write(fd, buf, i); #endif 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } 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) { unsigned char frame2[11]; memcpy(frame2, frame, 11); frame2[2] = 0xe1; frame2[3] = 0x88; dump_hex(frame2, 11); n = write(fd, frame2, 11); dump_hex(frame, 11); 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 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; 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; hl_usleep(20 * 1000); 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[5] = split; frame[6] = 0xfd; n = write(fd, frame, 7); } 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; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 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 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: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } 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[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; 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; 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()); printf("x25/x26 command rejected\n"); #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; } hamlib-4.6.2/simulators/simic7000.c0000644000175000017500000003445714752216205013702 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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 transceive = 0; int keyspd = 20; int rigtime = 1230; void dumphex(const 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, n; 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) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); printf("\n"); // echo //n = write(fd, buf, i); //if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: if (frame[5] == 0xfd) { //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); dump_hex(frame, 11); } } else { if (current_vfo == RIG_VFO_A) { freqA = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } else { freqB = from_bcd(&frame[5], (civ_731_mode ? 4 : 5) * 2); } frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } 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 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; 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; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 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 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 0x05: // FE FE 70 E0 1A 05 00 92 00 FD printf("0x05 received\n"); if (frame[6] == 0x00 && frame[7] == 0x92) { if (frame[8] == 0x00) { printf("0x05 0x00 0x92 received\n"); transceive = frame[8]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = transceive; frame[9] = 0xfb; frame[10] = 0xfd; n = write(fd, frame, 11); } } // FE FE 70 E0 1A 05 00 41 00 FD else if (frame[6] == 0x00 && frame[7] == 0x41) { if (frame[8] != 0xfd) { printf("0x05 0x00 0x41 received\n"); rigtime = frame[8] * 100 + frame[9]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = rigtime / 100; frame[9] = rigtime % 100; frame[10] = 0xfd; n = write(fd, frame, 11); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } 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[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; 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; 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()); printf("x25/x26 command rejected\n"); #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) { unsigned char tmp = buf[2]; buf[2] = buf[3]; buf[3] = tmp; frameParse(fd, buf, len); } else { hl_usleep(1000 * 1000); } rigStatus(); } return 0; } hamlib-4.6.2/simulators/simspid.c0000644000175000017500000000403614752216205013725 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simspid simspid.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #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[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[0]) { case '?': printf("Query %c\n", buf[1]); break; case '*': printf("Set %c\n", buf[1]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.2/simulators/simft990.c0000644000175000017500000000631414752216205013642 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simft990 simft990.c // emulates 1.2 ROM FT990 which can only read 1492 bytes #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; // 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; void load_dat(const char *filename, unsigned char buf[1492]) { FILE *fp = fopen(filename, "r"); char line[4096]; int n = 0; while (fgets(line, sizeof(line), fp)) { char *s = strdup(line); unsigned int val; char *p = strtok(line, " \r\n"); do { sscanf(p, "%x", &val); buf[n++] = val; } while (p = strtok(NULL, " \r\n")); strtok(s, "\r\n"); //printf("n=%d, %s\n",n,s); free(s); } fclose(fp); printf("%d bytes read\n", n); } static unsigned char alldata[1492]; int getmyline(int fd, char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); #if 1 while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } #else n = read(fd, buf, 5); #endif printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #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]; int fd = openPort(argv[1]); load_dat("simft990.dat", alldata); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { continue; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } if (buf[4] == 0x10) { write(fd, alldata, 1492); } } return 0; } hamlib-4.6.2/simulators/simic905.c0000644000175000017500000003663714752216205013633 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include "sim.h" #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 double freqA = 145123456; double freqB = 1407450; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; int filterA = 1; int filterB = 2; 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 keyspd = 25; int datamode = 0; int filter = 0; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } 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); int freq_len = 5; if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { if (freqA > 5.85e9) { freq_len = 6; } printf("get_freqA len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqA, freq_len * 2); } else { if (freqB > 5.85e9) { freq_len = 6; } printf("get_freqB len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqB, freq_len * 2); } frame[5 + freq_len] = 0xfd; if (powerstat) { 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; 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; 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; 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 0xa0: freqB = freqA; modeB = modeA; break; case 0xb0: current_vfo = RIG_VFO_SUB; exit(1); break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; WRITE(fd, frame, 7); } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; 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); 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); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); 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; WRITE(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; WRITE(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; 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; 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; 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; WRITE(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; 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; 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; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x06: // datamode if (frame[5] == 0xfd) { frame[6] = datamode; frame[7] = filter; frame[8] = 0xfd; WRITE(fd, frame, 9); } else { datamode = frame[6]; filter = frame[7]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { freq_len = 5; if (frame[5] == 0x00) { if (freqA > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqA, freq_len * 2); printf("X25 get_freqA=%.0f\n", freqA); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } else { if (freqB > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqB, freq_len * 2); printf("X25 get_freqB=%.0f\n", freqB); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } //unsigned char frame2[12]; #if 0 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] = 0x00; frame2[11] = 0xfd; WRITE(fd, frame2, 12); #endif } else { freq_len = 5; if (frame[11] != 0xfd) { freq_len = 6; } freq = from_bcd(&frame[6], freq_len * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); #if 0 // 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; WRITE(fd, frame, 11); #endif } 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] = frame[5] == 0 ? filterA : filterB; frame[9] = 0xfd; 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; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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; } hamlib-4.6.2/simulators/simqrplabs.c0000644000175000017500000002420614752216205014433 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 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;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "IF000503130001000+0000000000030000000;"; // from QMX 1_09 firmware "IF00007074000 +0.0000000002000000 ;" sprintf(ifbuf, "IF%011d +0.0000000002000000 ;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); 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;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; 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); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AI0;"; write(fd, pbuf, strlen(pbuf)); } } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); 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); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); 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;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); 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'); 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 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); 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); 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); 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); 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; } hamlib-4.6.2/simulators/simft847.c0000644000175000017500000000623414752216205013644 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simft897 simft897.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #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[]) { unsigned char buf[256]; int n; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[4]) { case 0x00: printf("LOCK ON\n"); break; case 0x80: printf("LOCK OFF\n"); break; case 0x08: printf("PTT ON\n"); break; case 0x88: printf("PTT OFF\n"); break; case 0x07: printf("MODE\n"); break; case 0x05: printf("CLAR ON\n"); break; case 0x85: printf("CLAR OFF\n"); break; case 0xF5: printf("FREQ\n"); break; case 0x81: printf("VFO TOGGLE\n"); break; case 0x02: printf("SPLIT ON\n"); break; case 0x82: printf("SPLIT OFF\n"); break; case 0x09: printf("REPEATER SHIFT\n"); break; case 0xF9: printf("REPEATER FREQ\n"); break; case 0x0A: printf("CTCSS/DCS MODE\n"); break; case 0x0B: printf("CTCSS TONE\n"); break; case 0x0C: printf("DCS CODE\n"); break; case 0xE7: printf("READ RX STATUS\n"); break; case 0xF7: printf("READ TX STATUS\n"); break; case 0x03: printf("READ RX STATUS\n"); buf[0] = 0x01; buf[1] = 0x40; buf[2] = 0x74; buf[3] = 0x00; buf[4] = 0x03; n = write(fd, buf, 5); break; case 0xbb: buf[0] = buf[1] = 0; printf("READ EPROM\n"); n = write(fd, buf, 2); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.2/simulators/simorion.c0000644000175000017500000000672714752216205014125 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simorion simorion.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 int freqA = 14074000; int freqB = 14074500; int modeA = 0; int width = 3010; int ptt = 0; int keyspd = 20; int getmyline(int fd, char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { if (c == 0x0d) { break; } buf[i++] = c; n++; } return n; } #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], reply[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (strncmp(buf, "?V", 2) == 0) { char *s = "Version 3.032x7"; write(fd, s, strlen(s)); } else if (strncmp(buf, "?AF", 3) == 0) { sprintf(reply, "@AF%8d\r", freqA); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?BF", 3) == 0) { sprintf(reply, "@BF%8d\r", freqB); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "*AF", 3) == 0) { sscanf(buf, "*AF%d", &freqA); } else if (strncmp(buf, "*BF", 3) == 0) { sscanf(buf, "*BF%d", &freqB); } else if (strncmp(buf, "?KV", 3) == 0) { sprintf(reply, "@KVANA\r"); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?RMM", 4) == 0) { sprintf(reply, "@RMM%d\r", modeA); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?RMF", 4) == 0) { sprintf(reply, "@RMF%d\r", width); write(fd, reply, strlen(reply)); } else if (strncmp(buf, "?S", 2) == 0) { if (ptt) { sprintf(reply, "@STWF002R000S256\r"); } else { sprintf(reply, "@SRM055S000\r"); } write(fd, reply, strlen(reply)); } else if (strncmp(buf, "*TK", 3) == 0) { ptt = 1; } else if (strncmp(buf, "*TU", 3) == 0) { ptt = 0; } else if (strncmp(buf, "?CS", 3) == 0) { sprintf(reply, "@CS%d\r", keyspd); } else if (strncmp(buf, "*CS", 3) == 0) { sscanf(buf, "*CS%d\r", &keyspd); } else { printf("Unknown cmd=%s\n", buf); } } //flush(fd); return 0; } hamlib-4.6.2/simulators/simts990.c0000644000175000017500000004502014752216205013654 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #define BUFSIZE 256 int mysleep = 20; int freqA = 14074000; int freqB = 14074500; int filternum1 = 7; int filternum2 = 8; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; int operatingband; int split; int keyspd = 20; int rg0 = 50; int rg1 = 50; int sq0 = 0; int sq1 = 0; int mg = 0; int nt0 = 0; int nt1 = 0; int nr0 = 0; int nr1 = 0; int gc0 = 0; int gc1 = 0; int mv0 = 0; int mv1 = 0; int pa0 = 0; int pa1 = 0; int ra0 = 0; int ra1 = 0; int rl0 = 0; int rl1 = 0; int ml = 0; int ag0 = 0; int ag1 = 0; int sl0 = 0; int sl1 = 0; int sh0 = 0; int sh1 = 0; int mo0 = 0; int mo1 = 0; int pc = 50; #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 getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); int retval; while ((retval = read(fd, &c, 1)) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (retval != 0) { perror("read failed:"); close(fd); fd = openPort(""); } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } return strlen(buf); } int main(int argc, char *argv[]) { char buf[256]; char *pbuf; int fd = openPort(argv[1]); char modeA = '1', modeB = '2'; while (1) { hl_usleep(10); buf[0] = 0; //if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } getmyline(fd, buf); // else { return 0; } if (strncmp(buf, "AC000;", 3) == 0) { continue; } else if (strncmp(buf, "RMA2", 3) == 0) { pbuf = "RM20020;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RM51;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RM5100001;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; hl_usleep(mysleep * 1000); // pbuf = "IF000503130001000+0000000000030000000;" sprintf(ifbuf, "IF%011d1000+0000002000000000000;", freqA); //pbuf = "IF00010138698 +00000000002000000 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "IS", 2) == 0) { continue; } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC%03d;", pc); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "FW", 2) == 0) { continue; } else if (strcmp(buf, "ID;") == 0) { hl_usleep(mysleep * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); write(fd, buf, strlen(buf)); continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { hl_usleep(mysleep * 1000); n = fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqA); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqB); 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;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); write(fd, buf, strlen(buf)); } else if (buf[3] == ';' && strncmp(buf, "SF", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SF%c%011d%c;", buf[2], buf[2] == '0' ? freqA : freqB, buf[2] == '0' ? modeA : modeB); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SF", 2) == 0) { mode_t tmpmode = buf[14]; modeA = tmpmode; printf("modeA=%c, modeB=%c\n", modeA, modeB); continue; } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d%03d;", filternum1, filternum2); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%3d%3d", &filternum1, &filternum2); continue; } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); 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); 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); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); continue; } else if (strncmp(buf, "BD;", 3) == 0) { continue; } else if (strncmp(buf, "BU;", 3) == 0) { continue; } else if (strcmp(buf, "RX;") == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; } 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 (strncmp(buf, "CB;", 3) == 0) { sprintf(buf, "CB%d;", operatingband); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "CB", 2) == 0) { sscanf(buf, "CB%d", &operatingband); } else if (strncmp(buf, "TB;", 3) == 0) { sprintf(buf, "TB%d;", split); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TB", 2) == 0) { sscanf(buf, "TB%d", &split); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "OM0;", 4) == 0) { sprintf(buf, "OM0%c;", modeA); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "OM0", 3) == 0) { modeA = buf[3]; } else if (strncmp(buf, "OM1;", 4) == 0) { sprintf(buf, "OM1%c;", modeB); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "OM1", 3) == 0) { modeB = buf[3]; } else if (strcmp(buf, "RM;") == 0) { sprintf(buf, "RM2%04d;", 10); write(fd, buf, strlen(buf)); } else if (strcmp(buf, "RG0;") == 0) { sprintf(buf, "RG0%03d;", rg0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG0", 3) == 0) { sscanf(buf, "RG0%d", &rg0); } else if (strcmp(buf, "RG1;") == 0) { sprintf(buf, "RG1%03d;", rg1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG1", 3) == 0) { sscanf(buf, "RG0%d", &rg1); } else if (strcmp(buf, "SQ0;") == 0) { sprintf(buf, "SQ0%03d;", sq0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SQ0", 3) == 0) { sscanf(buf, "SQ0%d", &sq0); } else if (strcmp(buf, "SQ1;") == 0) { sprintf(buf, "SQ1%03d;", sq1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SQ1", 3) == 0) { sscanf(buf, "SQ1%d", &sq1); } else if (strcmp(buf, "MG;") == 0) { sprintf(buf, "MG%03d;", mg); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &mg); } else if (strcmp(buf, "ML;") == 0) { sprintf(buf, "ML%03d;", ml); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "ML", 2) == 0) { sscanf(buf, "ML%d", &ml); } else if (strcmp(buf, "NT0;") == 0) { sprintf(buf, "NT0%03d;", nt0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NT0", 3) == 0) { sscanf(buf, "NT0%d", &nt0); } else if (strcmp(buf, "NT1;") == 0) { sprintf(buf, "NT1%03d;", nt1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NT1", 3) == 0) { sscanf(buf, "NT1%d", &nt1); } else if (strcmp(buf, "NR0;") == 0) { sprintf(buf, "NR0%03d;", nr0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NR0", 3) == 0) { sscanf(buf, "NR0%d", &nr0); } else if (strcmp(buf, "NR1;") == 0) { sprintf(buf, "NR1%03d;", nr1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NR1", 3) == 0) { sscanf(buf, "NR1%d", &nr1); } else if (strcmp(buf, "GC0;") == 0) { sprintf(buf, "GC0%03d;", gc0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "GC0", 3) == 0) { sscanf(buf, "GC0%d", &gc0); } else if (strcmp(buf, "GC1;") == 0) { sprintf(buf, "GC1%03d;", gc1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "GC1", 3) == 0) { sscanf(buf, "GC1%d", &gc1); } else if (strcmp(buf, "MV0;") == 0) { sprintf(buf, "MV0%03d;", mv0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MV0", 3) == 0) { sscanf(buf, "MV0%d", &mv0); } else if (strcmp(buf, "MV1;") == 0) { sprintf(buf, "MV1%03d;", mv1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MV1", 3) == 0) { sscanf(buf, "MV1%d", &mv1); } else if (strcmp(buf, "PA0;") == 0) { sprintf(buf, "PA0%03d;", pa0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA0", 3) == 0) { sscanf(buf, "PA0%d", &pa0); } else if (strcmp(buf, "PA1;") == 0) { sprintf(buf, "PA1%03d;", pa1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA1", 3) == 0) { sscanf(buf, "PA1%d", &pa1); } else if (strcmp(buf, "RA0;") == 0) { sprintf(buf, "RA0%03d;", ra0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA0", 3) == 0) { sscanf(buf, "RA0%d", &ra0); } else if (strcmp(buf, "RA1;") == 0) { sprintf(buf, "RA1%03d;", ra1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA1", 3) == 0) { sscanf(buf, "RA1%d", &ra1); } else if (strcmp(buf, "RL10;") == 0) { sprintf(buf, "RL10%02d;", rl0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RL10", 3) == 0) { sscanf(buf, "RL10%d", &rl0); } else if (strcmp(buf, "RL11;") == 0) { sprintf(buf, "RL11%02d;", rl1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "RL1", 3) == 0) { sscanf(buf, "RL1%d", &rl1); } else if (strcmp(buf, "AG0;") == 0) { sprintf(buf, "AG0%03d;", ag0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG0", 3) == 0) { sscanf(buf, "AG0%d", &ag0); } else if (strcmp(buf, "AG1;") == 0) { sprintf(buf, "AG1%03d;", ag1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG1", 3) == 0) { sscanf(buf, "AG1%d", &ag1); } else if (strcmp(buf, "SL0;") == 0) { sprintf(buf, "SL0%03d;", sl0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SL0", 3) == 0) { sscanf(buf, "SL0%d", &sl0); } else if (strcmp(buf, "SL1;") == 0) { sprintf(buf, "SL1%03d;", sl1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SL1", 3) == 0) { sscanf(buf, "SL1%d", &sl1); } else if (strcmp(buf, "SH0;") == 0) { sprintf(buf, "SH0%03d;", sh0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh0); } else if (strcmp(buf, "SH1;") == 0) { sprintf(buf, "SH1%03d;", sh1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH1", 3) == 0) { sscanf(buf, "SH1%d", &sh1); } else if (strcmp(buf, "MO0;") == 0) { sprintf(buf, "MO0%d;", mo0); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MO0", 3) == 0) { sscanf(buf, "MO0%d", &mo0); } else if (strcmp(buf, "MO1;") == 0) { sprintf(buf, "MO1%d;", mo1); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MO1", 3) == 0) { sscanf(buf, "MO1%d", &mo1); } else if (strncmp(buf, "CK0", 3) == 0) { continue; // setting clock no action } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simft991.c0000644000175000017500000002203014752216205013634 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '1'; char rx_vfo = '1'; char modeA = '0'; char modeB = '0'; int keyspd = 20; int bandselect = 5; int width = 21; int narrow = 0; int vd = 0; int sm0 = 0; int sm1 = 0; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, ";") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); } else if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "MR118;") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("MR118"); } } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 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) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%09.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%09.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "AI;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "FT%c;", tx_vfo); printf(" FT response#1=%s, tx_vfo=%c\n", buf, tx_vfo); n = write(fd, buf, strlen(buf)); printf(" FT response#2=%s\n", buf); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; if (tx_vfo == '3') { tx_vfo = '1'; } else if (tx_vfo == '2') { tx_vfo = '0'; } else { perror("Expected 2 or 3"); } } else if (strcmp(buf, "MD0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD0%c;", modeA); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD1%c;", modeB); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n < 0) { perror("VS"); } } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "BS;", 3) == 0) // cannot query BS { sprintf(buf, "BS%02d;", bandselect); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0;", 4) == 0) { sprintf(buf, "SH0%02d;", width); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%02d", &width); } else if (strncmp(buf, "NA0;", 4) == 0) { sprintf(buf, "NA0%d;", narrow); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &narrow); } else if (strncmp(buf, "VD;", 3) == 0) { sprintf(buf, "VD%d;", vd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VD", 2) == 0) { sscanf(buf, "VD%d", &vd); } else if (strncmp(buf, "SM0;", 4) == 0) { sprintf(buf, "SM0%d;", sm0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM0", 3) == 0) { sscanf(buf, "SM0%3d", &sm0); } else if (strncmp(buf, "SM1;", 4) == 0) { sprintf(buf, "SM1%d;", sm1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM1", 3) == 0) { sscanf(buf, "SM1%3d", &sm1); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simts450.c0000644000175000017500000002172214752216205013646 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #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 keyspd = 25; 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); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 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;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } 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 ; WRITE(fd, ifbuf, strlen(ifbuf)); } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "IS", 2) == 0) { } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; WRITE(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "FW", 2) == 0) { } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "ID%03d;", 10); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } 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); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX", 2) == 0) { } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "AI", 2) == 0) { // nothing to do yet } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); 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'); WRITE(fd, buf, strlen(buf)); } 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); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { sscanf(buf, "FR%d", &vfo); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", vfo_tx); WRITE(fd, buf, strlen(buf)); } 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); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); printf("%s\n", buf); } else if (strncmp(buf, "TO;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TO%d;", tomode); } else if (strncmp(buf, "BD;", 3) == 0) { } else if (strncmp(buf, "BU;", 3) == 0) { } 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; } } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simelecraftk4.c0000644000175000017500000002723714752216205015022 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #define BUFSIZE 256 int freqA = 14074000; int freqB = 14074500; int afgain = 180; int rfgain = 190; int micgain = 30; int noiseblanker = 0; int bandwidthA = 200; int bandwidthB = 200; int ifshift = 0; int preampA = 0; int preampB = 0; int rxattenuatorA = 0; int rxattenuatorB = 0; int keyspd = 20; int ai = 0; int dt = 0; int modeA = 2; int modeB = 2; int ptt = 0; // int freqa = 14074000, freqb = 14073500; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { buf[0] = 0; if ((n = getmyline(fd, buf)) > 0) { if (strstr(buf, "BW0")) printf("Cmd:%s, len=%d\n", buf, n); } else {continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); //pbuf = "IF059014200000+000000700000;"; pbuf = "IF00007230000 -000000 0001000001 ;" ; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "BW$;") == 0) { fprintf(stderr, "***** %d\n", __LINE__); SNPRINTF(buf, sizeof(buf), "BW$%04d;", bandwidthB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW$", 3) == 0) { sscanf(buf, "BW$%d", &bandwidthB); } else if (strcmp(buf, "BW;") == 0) { SNPRINTF(buf, sizeof(buf), "BW%04d;", bandwidthA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW", 2) == 0) { sscanf(buf, "BW%d", &bandwidthA); } else if (strcmp(buf, "DT;") == 0) { SNPRINTF(buf, sizeof(buf), "DT%d;", dt); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT", 2) == 0) { sscanf(buf, "DT%d", &dt); } else if (strcmp(buf, "BN;") == 0) { SNPRINTF(buf, sizeof(buf), "BN03;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "SM;") == 0) { static int meter = 0; SNPRINTF(buf, sizeof(buf), "SM%04d;", meter++); if (meter > 15) { meter = 0; } WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "RG;") == 0) { SNPRINTF(buf, sizeof(buf), "RG%03d;", rfgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG%d", &rfgain); } else if (strcmp(buf, "MG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", micgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &micgain); } else if (strcmp(buf, "AG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", afgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &afgain); } else if (strcmp(buf, "NB;") == 0) { SNPRINTF(buf, sizeof(buf), "NB%d;", noiseblanker); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "NB", 2) == 0) { sscanf(buf, "NB%d", &noiseblanker); } else if (strcmp(buf, "IS;") == 0) { SNPRINTF(buf, sizeof(buf), "IS %04d;", ifshift); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS %d", &ifshift); } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "OM;") == 0) { // KPA3 SNPRINTF(buf, sizeof(buf), "OM AP----L-----;"); // K4+KPA3 SNPRINTF(buf, sizeof(buf), "OM AP-S----4---;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "K2;") == 0) { WRITE(fd, "K20;", 4); } else if (strcmp(buf, "K3;") == 0) { WRITE(fd, "K30;", 4); } else if (strncmp(buf, "RV", 2) == 0) { WRITE(fd, "RV02.37;", 8); } else if (strcmp(buf, "MD;") == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD$;") == 0) { SNPRINTF(buf, sizeof(buf), "MD$%d;", modeB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { if (buf[2] == '$') { sscanf(buf, "MD$%d;", &modeB); } else { sscanf(buf, "MD%d;", &modeA); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqA); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqA); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqB); } else if (strncmp(buf, "FR;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FR0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { // we ignore FR for the K3 } else if (strncmp(buf, "FT;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FT0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "KS%03d;", keyspd); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%d", &keyspd); } else if (strncmp(buf, "TQ;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TQ%d;", ptt); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC0980;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PA%d;", preampA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "PA$%d;", preampB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d;", &preampA); } else if (strncmp(buf, "PA$", 3) == 0) { sscanf(buf, "PA$%d;", &preampB); } else if (strncmp(buf, "RA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "RA%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "RA$%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d;", &rxattenuatorB); } else if (strncmp(buf, "RA$", 3) == 0) { sscanf(buf, "RA$%d;", &rxattenuatorB); } else if (strncmp(buf, "KY;", 3) == 0) { int status = 0; printf("KY query\n"); SNPRINTF(buf, sizeof(buf), "KY%d;", status); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KY", 2) == 0) { printf("Morse: %s\n", buf); } else if (strncmp(buf, "TM", 2) == 0) { SNPRINTF(buf, sizeof(buf), "TM001002003004;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { ptt = 1; } else if (strncmp(buf, "RX", 2) == 0) { ptt = 0; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simft817.c0000644000175000017500000000661714752216205013646 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simft897 simft897.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 int vfo = 0; // 0=A, !0=B float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #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[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); } switch (buf[4]) { case 0x00: printf("LOCK ON\n"); break; case 0x80: printf("LOCK OFF\n"); break; case 0x08: printf("PTT ON\n"); break; case 0x88: printf("PTT OFF\n"); break; case 0x07: printf("MODE %0xx\n", buf[0]); if (vfo == 0) { modeA = buf[0]; } else { modeB = buf[0]; } break; case 0x05: printf("CLAR ON\n"); break; case 0x85: printf("CLAR OFF\n"); break; case 0xF5: printf("FREQ\n"); break; case 0x81: vfo = !vfo; printf("VFO TOGGLE, %s active\n", vfo == 0 ? "VFOA" : "VFOB"); break; case 0x02: printf("SPLIT ON\n"); break; case 0x82: printf("SPLIT OFF\n"); break; case 0x09: printf("REPEATER SHIFT\n"); break; case 0xF9: printf("REPEATER FREQ\n"); break; case 0x0A: printf("CTCSS/DCS MODE\n"); break; case 0x0B: printf("CTCSS TONE\n"); break; case 0x0C: printf("DCS CODE\n"); break; case 0xE7: printf("READ RX STATUS\n"); break; case 0xF7: printf("READ TX STATUS\n"); break; case 0x03: printf("READ RX STATUS\n"); buf[0] = 0x01; buf[1] = 0x40; buf[2] = 0x74; buf[3] = 0x00; buf[4] = 0x03; write(fd, buf, 5); break; case 0xbb: buf[0] = 80; buf[1] = 0; printf("READ EPROM\n"); write(fd, buf, 2); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.2/simulators/simts950.c0000644000175000017500000002410714752216205013653 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 int mysleep = 20; float freqA = 14074000; float freqB = 14074500; int filternum1 = 7; int filternum2 = 8; int datamode = 0; int vfo, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; 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); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 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;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); // pbuf = "IF000503130001000+0000000000030000000;" sprintf(ifbuf, "IF%011d1000+0000002000000000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); 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;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; 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); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); write(fd, buf, strlen(buf)); continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); n = fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); 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); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); 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;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); 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'); 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 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%03d;", filternum1, filternum2); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%3d%3d", &filternum1, &filternum2); continue; } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); 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); 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); 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, "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 (strcmp(buf, "RX;") == 0) { ptt = ptt_mic = ptt_data = ptt_tune = 0; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simtmd710.c0000644000175000017500000000611014752216205013775 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == 0x0d) { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 0; // , modeB = 0; while (1) { buf[0] = 0; if (getmyline(fd, buf) > 0) { printf("Cmd:%s\n", buf); } if (strncmp(buf, "BC", 2) == 0) { SNPRINTF(buf, sizeof(buf), "BC %d %d%c", vfo, vfo_tx, 0x0d); printf("R:%s\n", buf); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "FO", 2) == 0) { if (buf[3] == '0') { SNPRINTF(buf, sizeof(buf), "FO 0 %d%c", freqA, 0x0d); } else { SNPRINTF(buf, sizeof(buf), "FO 1 %d%c", freqB, 0x0d); } printf("R:%s\n", buf); write(fd, buf, strlen(buf)); continue; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simelecraft.c0000644000175000017500000002725114752216205014557 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int afgain = 180; int rfgain = 190; int micgain = 30; int noiseblanker = 0; int bandwidthA = 2200; int bandwidthB = 2400; int ifshift = 0; int preampA = 0; int preampB = 0; int rxattenuatorA = 0; int rxattenuatorB = 0; int keyspd = 20; int ai = 0; int dt = 0; int modea = 2; int modeb = 2; int ptt = 0; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 = 14073500; while (1) { buf[0] = 0; if ((n = getmyline(fd, buf)) > 0) { if (strstr(buf, "BW")) printf("Cmd:%s, len=%d\n", buf, n); } else {continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); //pbuf = "IF059014200000+000000700000;"; pbuf = strdup("IF00007230000 -000000 00?1000001 ;") ; pbuf[28] = ptt == 0 ? '0' : '1'; WRITE(fd, pbuf, strlen(pbuf)); free(pbuf); } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "BW$;") == 0) { fprintf(stderr, "***** %d\n", __LINE__); SNPRINTF(buf, sizeof(buf), "BW$%04d;", bandwidthB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW$", 3) == 0) { sscanf(buf, "BW$%d", &bandwidthB); } else if (strcmp(buf, "BW;") == 0) { SNPRINTF(buf, sizeof(buf), "BW%04d;", bandwidthA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "BW", 2) == 0) { sscanf(buf, "BW%d", &bandwidthA); } else if (strcmp(buf, "DT;") == 0) { SNPRINTF(buf, sizeof(buf), "DT%d;", dt); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "DT", 2) == 0) { sscanf(buf, "DT%d", &dt); } else if (strcmp(buf, "BN;") == 0) { SNPRINTF(buf, sizeof(buf), "BN03;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "SM;") == 0) { static int meter = 0; SNPRINTF(buf, sizeof(buf), "SM%04d;", meter++); if (meter > 15) { meter = 0; } WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "RG;") == 0) { SNPRINTF(buf, sizeof(buf), "RG%03d;", rfgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG%d", &rfgain); } else if (strcmp(buf, "MG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", micgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &micgain); } else if (strcmp(buf, "AG;") == 0) { SNPRINTF(buf, sizeof(buf), "MG%03d;", afgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &afgain); } else if (strcmp(buf, "NB;") == 0) { SNPRINTF(buf, sizeof(buf), "NB%d;", noiseblanker); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "NB", 2) == 0) { sscanf(buf, "NB%d", &noiseblanker); } else if (strcmp(buf, "IS;") == 0) { SNPRINTF(buf, sizeof(buf), "IS %04d;", ifshift); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS %d", &ifshift); } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "OM;") == 0) { // KPA3 SNPRINTF(buf, sizeof(buf), "OM AP----L-----;"); // K4+KPA3 SNPRINTF(buf, sizeof(buf), "OM AP-S----4---;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "K2;") == 0) { WRITE(fd, "K20;", 4); } else if (strcmp(buf, "K3;") == 0) { WRITE(fd, "K30;", 4); } else if (strcmp(buf, "RVD;") == 0) { WRITE(fd, "RVD02.36;", 9); } else if (strcmp(buf, "RVM;") == 0) { WRITE(fd, "RVM02.37;", 9); } else if (strcmp(buf, "MD;") == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modea); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD$;") == 0) { SNPRINTF(buf, sizeof(buf), "MD$%d;", modeb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { if (buf[2] == '$') { sscanf(buf, "MD$%d;", &modeb); } else { sscanf(buf, "MD%d;", &modea); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "FR;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FR0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FR", 2) == 0) { // we ignore FR for the K3 } else if (strncmp(buf, "FT;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FT0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "KS%03d;", keyspd); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%d", &keyspd); } else if (strncmp(buf, "TQ;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "TQ0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC0980;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PA%d;", preampA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "PA$%d;", preampB); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d;", &preampA); } else if (strncmp(buf, "PA$", 3) == 0) { sscanf(buf, "PA$%d;", &preampB); } else if (strncmp(buf, "RA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "RA%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA$;", 4) == 0) { SNPRINTF(buf, sizeof(buf), "RA$%02d;", rxattenuatorA); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d;", &rxattenuatorB); } else if (strncmp(buf, "RA$", 3) == 0) { sscanf(buf, "RA$%d;", &rxattenuatorB); } else if (strncmp(buf, "KY;", 3) == 0) { int status = 0; printf("KY query\n"); SNPRINTF(buf, sizeof(buf), "KY%d;", status); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KY", 2) == 0) { printf("Morse: %s\n", buf); } else if (strncmp(buf, "TX", 2) == 0) { ptt = 1; } else if (strncmp(buf, "RX", 2) == 0) { ptt = 0; } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simpmr171.c0000644000175000017500000000431314752216205014013 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simprm171 simprm171.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n1=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); i = buf[4]; // length of packet n = read(fd, &buf[5], i); printf("read %d bytes\n", n); if (n == 0) { return 0; } n += 5; printf("n2=%d", n); for (i = 0; i < n; ++i) { printf(" x%02x", buf[i]); } printf("\n"); return n; } #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[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } switch (buf[5]) { case 0x07: printf("PTT=%d\n", buf[6]); write(fd, buf, 9); break; case 0x0c: printf("Power=%d\n", buf[6]); break; default: printf("Unknown cmd=%02x\n", buf[4]); } } return 0; } hamlib-4.6.2/simulators/simft818.c0000644000175000017500000002115114752216205013635 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; vfo_t curr_vfo = RIG_VFO_A; char modeA = '1'; char modeB = '1'; int width = 0; int ptt; // 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_FTDX3000DM = 462, NC_RIGID_FTDX101D = 681, NC_RIGID_FTDX101MP = 682 } nc_rigid_t; 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); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 resp[256]; char *pbuf; int n; int fd = openPort(argv[1]); while (1) { buf[0] = 0; if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } //else { return 0; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "FA;") == 0) { //SNPRINTF(resp, sizeof(resp), "FA%010.0f;", freqA); SNPRINTF(resp, sizeof(resp), "FA%08.0f;", freqA); freqA += 10; n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { //SNPRINTF(resp, sizeof(resp), "FB%0010.0f;", freqB); SNPRINTF(resp, sizeof(resp), "FB%08.0f;", freqB); n = write(fd, resp, strlen(resp)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); //pbuf = "IF00107041000+000000200000;"; pbuf = "IF00010138698 +00000000002000000 ;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000DM; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "AB;") == 0) { freqB = freqA; modeB = modeA; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS") == 0 && strlen(buf) > 3) { curr_vfo = buf[3] == '1' ? RIG_VFO_B : RIG_VFO_A; hl_usleep(50 * 1000); } else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = strdup("VS0;"); if (curr_vfo == RIG_VFO_B || curr_vfo == RIG_VFO_SUB) { pbuf[2] = '1'; } n = write(fd, pbuf, strlen(pbuf)); printf("%s\n", pbuf); free(pbuf); if (n < 0) { perror("VS"); } } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "FT%c;", tx_vfo); printf(" FT response#1=%s, tx_vfo=%c\n", resp, tx_vfo); n = write(fd, resp, strlen(resp)); printf(" FT response#2=%s\n", resp); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; if (tx_vfo == '3') { tx_vfo = '1'; } else if (tx_vfo == '2') { tx_vfo = '0'; } else { perror("Expected 2 or 3"); } } else if (strcmp(buf, "MD0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD0%c;", modeA); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "MD1%c;", modeB); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } else if (strcmp(buf, "SM0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "SM0111;"); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("SM"); } } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(resp, sizeof(resp), "TX%d;", ptt); n = write(fd, resp, strlen(resp)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { hl_usleep(50 * 1000); ptt = buf[2] == '0' ? 0 : 1; } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%02d;", width); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); printf("%s n=%d\n", buf, n); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA00;"); hl_usleep(50 * 1000); n = write(fd, buf, strlen(buf)); printf("%s n=%d\n", buf, n); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } if (n == 0) { fprintf(stderr, "Write error? n==0\n"); } } return 0; } hamlib-4.6.2/simulators/simxiegux108g.c0000644000175000017500000002521114752216205014675 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #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_CW; mode_t modeB = RIG_MODE_USB; 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 keyspd = 20; void dumphex(const 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; 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; } } //printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; 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; 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; 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; 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; 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 0xb0: freq = freqA; freqA = freqB; freqB = freq; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; #if 0 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("n=write 8 bytes\n"); dump_hex(frame, 8); write(fd, frame, 8); break; #endif case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; write(fd, frame, 9); 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; write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; 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; write(fd, frame, 9); break; } break; #if 0 case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; write(fd, frame, 7); break; #endif 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; write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; 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("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; 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; write(fd, frame, 6); } 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; write(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.2/simulators/simic2730.c0000644000175000017500000003341314752216205013676 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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 = 1; 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 transceive = 0; int keyspd = 20; int rigtime = 1230; void dumphex(const 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, n; 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) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); // echo n = write(fd, buf, i); if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x03: printf("Here#1\n"); //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; dump_hex(frame, 8); 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 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; 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; } if (frame[5] == 0xfd) { frame[5] = split; printf("get split %d\n", 1); frame[6] = 0xfd; dump_hex(frame, 7); n = write(fd, frame, 7); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; dump_hex(frame, 6); 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; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 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 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 0x05: // FE FE 70 E0 1A 05 00 92 00 FD printf("0x05 received\n"); if (frame[6] == 0x00 && frame[7] == 0x92) { if (frame[8] == 0x00) { printf("0x05 0x00 0x92 received\n"); transceive = frame[8]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = transceive; frame[9] = 0xfb; frame[10] = 0xfd; n = write(fd, frame, 11); } } // FE FE 70 E0 1A 05 00 41 00 FD else if (frame[6] == 0x00 && frame[7] == 0x41) { if (frame[8] != 0xfd) { printf("0x05 0x00 0x41 received\n"); rigtime = frame[8] * 100 + frame[9]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = rigtime / 100; frame[9] = rigtime % 100; frame[10] = 0xfd; n = write(fd, frame, 11); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } 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[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; 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; 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()); printf("x25/x26 command rejected\n"); #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; } hamlib-4.6.2/simulators/simid5100.c0000644000175000017500000002402414752216205013667 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #define BUFSIZE 256 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 = 145000000; float freqB = 14074500; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; int filterA = 0; 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; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } switch (frame[4]) { case 0x00: freq = from_bcd(&frame[5], 5 * 2); freqA = freq; printf("freq=%lf\n", freqA); break; 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 / 10000, 3 * 2); dump_hex(frame, 11); } else { printf("get_freqB\n"); to_bcd(&frame[5], (long long)freqB / 10000, 3 * 2); } frame[8] = 0xfd; dump_hex(frame, 9); write(fd, frame, 9); break; case 0x04: if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { printf("get_modeA\n"); frame[5] = modeA; frame[6] = filterA; } else { printf("get_modeB\n"); frame[5] = modeB; frame[6] = filterA; } frame[7] = 0xfd; 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; 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; 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; 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; write(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; 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); write(fd, frame, 8); break; case 0x14: switch (frame[5]) { static int power_level = 0; 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; 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; 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; 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; write(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; 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] = filterA; } frame[7] = 0xfd; 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; write(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; write(fd, frame, 9); } break; } break; case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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 filter=%d freq=%.0f\n", vfoa, modeA, filterA, freqA); printf("%cVFOB: mode=%d filter=%d freq=%.0f\n", vfob, modeB, filterA, freqB); } int main(int argc, char **argv) { unsigned char buf[256]; int fd = openPort(argv[1]); printf("%s: %s\n", argv[0], rig_version()); #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; } hamlib-4.6.2/simulators/simic7600.c0000644000175000017500000004326414752216205013704 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // satmode if (frame[6] == 0xfd) // then we are reading { frame[6] = datamode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamode = frame[6]; frame[4] = 0xfd; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #else n = write(fd, frame, 12); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } #endif } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } // 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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; } hamlib-4.6.2/simulators/simic9100.c0000644000175000017500000003361114752216205013674 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include #include #include "sim.h" #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 subband = 1; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; 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) { 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; 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; 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; 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; printf("+++++++++++++++ SETTING VFO +++++++++++++++++\n"); dump_hex(frame, 6); 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; WRITE(fd, frame, 8); } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; 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); 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); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); 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; 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; 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; 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; WRITE(fd, frame, 8); } break; case 0x59: frame[6] = subband; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; 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; 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; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; 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("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; 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; WRITE(fd, frame2, 11); 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; 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; 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; 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; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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; } hamlib-4.6.2/simulators/simic910.c0000644000175000017500000003671414752216205013623 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include #include "../src/misc.h" #include #include #include "sim.h" #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 double freqA = 145123456; double freqB = 1407450; mode_t modeA = RIG_MODE_PKTUSB; mode_t modeB = RIG_MODE_PKTUSB; int datamodeA = 0; int datamodeB = 0; int filterA = 1; int filterB = 2; 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 keyspd = 25; int datamode = 0; int filter = 0; void dumphex(const 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } frame[2] = 0xe0; frame[3] = 0x60; switch (frame[4]) { case 0x03: //from_bcd(frameackbuf[2], (civ_731_mode ? 4 : 5) * 2); int freq_len = 5; if (current_vfo == RIG_VFO_A || current_vfo == RIG_VFO_MAIN) { if (freqA > 5.85e9) { freq_len = 6; } printf("get_freqA len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqA, freq_len * 2); } else { if (freqB > 5.85e9) { freq_len = 6; } printf("get_freqB len=%d\n", freq_len); to_bcd(&frame[5], (long long)freqB, freq_len * 2); } frame[5 + freq_len] = 0xfd; if (powerstat) { 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; 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; 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; 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 0xa0: freqB = freqA; modeB = modeA; break; case 0xb0: current_vfo = RIG_VFO_SUB; exit(1); break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x0f: if (frame[5] == 0xfd) { printf("get split %d\n", split); frame[5] = split; frame[6] = 0xfd; WRITE(fd, frame, 7); } else { printf("set split %d\n", 1); split = frame[5]; frame[4] = 0xfb; frame[5] = 0xfd; 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); 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); WRITE(fd, frame, 7); printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfb; dumphex(frame, 9); 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; WRITE(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; WRITE(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; 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; 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; 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; WRITE(fd, frame, 8); } break; } break; case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; WRITE(fd, frame, 7); break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; 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; 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; WRITE(fd, frame, 8); } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; case 0x06: // datamode if (frame[5] == 0xfd) { frame[6] = datamode; frame[7] = filter; frame[8] = 0xfd; WRITE(fd, frame, 9); } else { datamode = frame[6]; filter = frame[7]; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } case 0x07: // satmode frame[4] = 0; frame[7] = 0xfd; WRITE(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[6] = ptt; frame[7] = 0xfd; WRITE(fd, frame, 8); } else { ptt = frame[6]; int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); } break; } break; #ifdef X25 case 0x25: if (frame[6] == 0xfd) { freq_len = 5; if (frame[5] == 0x00) { if (freqA > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqA, freq_len * 2); printf("X25 get_freqA=%.0f\n", freqA); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } else { if (freqB > 5.85e9) { freq_len = 6; } to_bcd(&frame[6], (long long)freqB, freq_len * 2); printf("X25 get_freqB=%.0f\n", freqB); frame[6 + freq_len] = 0xfd; WRITE(fd, frame, 7 + freq_len); } //unsigned char frame2[12]; #if 0 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] = 0x00; frame2[11] = 0xfd; WRITE(fd, frame2, 12); #endif } else { freq_len = 5; if (frame[11] != 0xfd) { freq_len = 6; } freq = from_bcd(&frame[6], freq_len * 2); printf("set_freq to %.0f\n", freq); if (frame[5] == 0x00) { freqA = freq; } else { freqB = freq; } int tmp = frame[2]; frame[2] = frame[3]; frame[3] = tmp; frame[4] = 0xfb; frame[5] = 0xfd; WRITE(fd, frame, 6); #if 0 // 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; WRITE(fd, frame, 11); #endif } 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] = frame[5] == 0 ? filterA : filterB; frame[9] = 0xfd; 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; WRITE(fd, frame, 6); } printf("\n"); break; #else case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; WRITE(fd, frame, 6); break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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; } hamlib-4.6.2/simulators/simic7200.c0000644000175000017500000005565514752216205013707 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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 keyspd = 85; int filter_width = 38; int preamp = 0; int attenuator = 0; int autonotch = 0; int aflevel = 128; int noiseblanker = 0; int manualnotch = 0; int mnf = 0; int noisereduction = 0; int speechcompressor = 0; int agc = 0; int vox = 0; void dumphex(const 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) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s: %s ", mytime, __func__); dumphex(buf, i); #if 0 // echo n = write(fd, buf, i); if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } #endif 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } dumphex(frame, len); if (frame[0] != 0xfe && frame[1] != 0xfe) { printf("expected fe fe, got "); dumphex(frame, len); return; } // reverse the addressing frame[3] = frame[2]; frame[2] = 0xe0; 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x07: switch (frame[5]) { case 0x00: current_vfo = RIG_VFO_A; break; case 0x01: current_vfo = RIG_VFO_B; break; case 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x11: if (frame[6] == 0xfd) { frame[6] = attenuator; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { attenuator = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x14: switch (frame[5]) { static int power_level = 0; case 0x01: if (frame[6] == 0xfd) { frame[6] = aflevel; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { aflevel = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x07: case 0x08: if (frame[6] != 0xfd) { frame[4] = 0xfb; frame[5] = 0xfd; dumphex(frame, 6); hl_usleep(10 * 1000); n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("ACK x14 x08\n"); } else { to_bcd(&frame[6], (long long)128, 2); frame[8] = 0xfd; dumphex(frame, 9); n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } printf("SEND x14 x08\n"); } break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; n = write(fd, frame, 9); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x0d: if (frame[6] == 0xfd) { frame[6] = mnf; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { mnf = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; } case 0x16: switch (frame[5]) { case 0x02: if (frame[6] == 0xfd) { frame[6] = preamp; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { preamp = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x12: if (frame[6] == 0xfd) { frame[6] = agc; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { agc = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x22: if (frame[6] == 0xfd) { frame[6] = noiseblanker; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { noiseblanker = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x40: if (frame[6] == 0xfd) { frame[6] = noisereduction; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { noisereduction = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x41: if (frame[6] == 0xfd) { frame[6] = autonotch; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { autonotch = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x44: if (frame[6] == 0xfd) { frame[6] = speechcompressor; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { speechcompressor = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x46: if (frame[6] == 0xfd) { frame[6] = vox; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { vox = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x48: if (frame[6] == 0xfd) { frame[6] = manualnotch; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { manualnotch = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x5a: if (frame[6] == 0xfe) { satmode = frame[6]; } else { frame[6] = satmode; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x19: // miscellaneous things frame[5] = 0x94; frame[6] = 0xfd; n = write(fd, frame, 7); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x02: // filter width printf("frame[6]==x%02x, frame[7]=0%02x\n", frame[6], frame[7]); if (frame[6] == 0xfd) // the we are reading { frame[6] = filter_width; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("FILTER_WIDTH RESPONSE******************************"); filter_width = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } 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); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { printf("AGC_TIME RESPONSE******************************"); agc_time = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; n = write(fd, frame, 8); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } else { ptt = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } } break; } break; case 0x25: printf("x25 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; case 0x26: printf("x26 send nak\n"); frame[4] = 0xfa; frame[5] = 0xfd; n = write(fd, frame, 6); if (n <= 0) { fprintf(stderr, "%s(%d) write error %s\n", __func__, __LINE__, strerror(errno)); } break; 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()); printf("x25/x26 command rejected\n"); #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; } hamlib-4.6.2/simulators/simpstrotator.c0000644000175000017500000000645214752216205015213 00000000000000#include #include #include #include #include #define SERVER_PORT 12001 #define REPLY_PORT 12002 #define BUFFER_SIZE 1024 void handle_receive(int recv_sockfd, struct sockaddr_in *client_addr, socklen_t addr_len, char *buffer) { ssize_t recv_len; recv_len = recvfrom(recv_sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)client_addr, &addr_len); if (recv_len < 0) { perror("recvfrom"); close(recv_sockfd); exit(EXIT_FAILURE); } buffer[recv_len] = '\0'; // Null-terminate the received string printf("Received packet from %s:%d\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port)); printf("Data: %s\n", buffer); } void handle_send(int send_sockfd, struct sockaddr_in *client_addr, socklen_t addr_len, const char *message) { ssize_t sent_len; sent_len = sendto(send_sockfd, message, strlen(message), 0, (struct sockaddr *)client_addr, addr_len); if (sent_len < 0) { perror("sendto"); close(send_sockfd); exit(EXIT_FAILURE); } printf("Sent reply to %s:%d from port %d\n", inet_ntoa(client_addr->sin_addr), ntohs(client_addr->sin_port), REPLY_PORT); } int main() { int recv_sockfd, reply_sockfd; struct sockaddr_in server_addr, reply_addr, client_addr; char buffer[BUFFER_SIZE]; socklen_t addr_len = sizeof(client_addr); // Create a UDP socket for receiving on SERVER_PORT if ((recv_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(EXIT_FAILURE); } // Configure the server address for receiving memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(SERVER_PORT); // Bind the receiving socket to the server address if (bind(recv_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind"); close(recv_sockfd); exit(EXIT_FAILURE); } // Create a UDP socket for replying on REPLY_PORT if ((reply_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); close(recv_sockfd); exit(EXIT_FAILURE); } // Configure the reply address for sending memset(&reply_addr, 0, sizeof(reply_addr)); reply_addr.sin_family = AF_INET; reply_addr.sin_addr.s_addr = INADDR_ANY; reply_addr.sin_port = htons(REPLY_PORT); // Bind the reply socket to the reply address if (bind(reply_sockfd, (struct sockaddr *)&reply_addr, sizeof(reply_addr)) < 0) { perror("bind"); close(recv_sockfd); close(reply_sockfd); exit(EXIT_FAILURE); } printf("UDP server is listening on port %d for incoming packets and on port %d for replies\n", SERVER_PORT, REPLY_PORT); while (1) { // Handle incoming packets on SERVER_PORT handle_receive(recv_sockfd, &client_addr, addr_len, buffer); // Send "OK" reply to the client from REPLY_PORT handle_send(reply_sockfd, &client_addr, addr_len, "OK"); } // Close the sockets close(recv_sockfd); close(reply_sockfd); return 0; } hamlib-4.6.2/simulators/simftdx101.c0000644000175000017500000002157114752216205014160 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int modeA = 0xc; int modeB = 0xc; int vs = 0; int tx = 0; int ai = 0; int sh = 19; int na = 0; int ex039 = 0; int keyspd = 20; int split = 0; int power = 50; int rport_gain_ssb = 50; int rport_gain_am = 50; int rport_gain_fm = 50; int rport_gain_psk = 50; int syncvfo = 0; int ant = 1; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AN0%d;", ant); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("AN"); } } else if (strncmp(buf, "AN", 2) == 0) { sscanf(buf,"AN%d",&ant); printf("Ant set to %d\n", ant); } else if (strcmp(buf, "IF;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "EX032;") == 0) { ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", ft); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%X;", modeA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD0", 3) == 0) { sscanf(buf, "MD0%d", &modeA); } else if (strcmp(buf, "MD1;") == 0) { SNPRINTF(buf, sizeof(buf), "MD1%X;", modeB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD1", 3) == 0) { sscanf(buf, "MD1%d", &modeB); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "PC;") == 0) { SNPRINTF(buf, sizeof(buf), "PC%d;", power); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &power); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "ST;", 3) == 0) { sprintf(buf, "ST%d;", split); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "ST", 2) == 0) { sscanf(buf, "ST%d", &split); } else if (strcmp(buf, "EX010415;") == 0) { sprintf(buf, "EX010415%03d;", rport_gain_psk); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX010415", 8) == 0) { printf("Here#1"); sscanf(buf, "EX010415%d", &rport_gain_psk); } else if (strcmp(buf, "SY;") == 0) { sprintf(buf, "SY%d;", syncvfo); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SY", 2) == 0) { sscanf(buf, "SY%d", &syncvfo); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simftdx1200.c0000644000175000017500000001626214752216205014242 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int md = 1; int vs = 0; int tx = 0; int ai = 0; int sh = 25; int na = 0; int ex039 = 0; int keyspd = 20; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 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) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); printf("n=%d\n", n); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", ft); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%d;", md); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%c;", vfo == 0 ? '0' : '1'); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", keyspd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simft710.c0000644000175000017500000003716414752216205013637 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int ks = 20; int bandselect = 5; int width = 21; int narrow = 0; int vd = 0; int sm0 = 0; int sm1 = 0; int vs = 0; int vx = 0; int pa = 0; int ra = 0; int ag = 0; int pc = 100; int is = 0; int bp_on = 0; int bp_pos = 0; int rl = 0; int nb = 0; int nr = 0; int tx = 0; int mg = 0; int rg = 100; int vg = 0; int kr = 0; int bi = 0; int gt = 0; int ex016 = 0; int ex020 = 0; int st = 0; // 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_FT710 = 800 } nc_rigid_t; 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); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { if (getmyline(fd, buf)) { // printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, ";") == 0) { pbuf = "?;"; n = write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RM4;") == 0) { hl_usleep(50 * 1000); pbuf = "RM4100;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("RM4"); } } else if (strcmp(buf, "RM5;") == 0) { static int power = 0; power += 5; if (power > 255) { power = 0; } hl_usleep(50 * 1000); snprintf(buf, sizeof(buf), "RM5%03d000;", power); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("RM5"); } } else if (strcmp(buf, "RM6;") == 0) { hl_usleep(50 * 1000); pbuf = "AN030;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("AN"); } } else if (strcmp(buf, "IF;") == 0) { hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "ID;") == 0) { hl_usleep(50 * 1000); int id = NC_RIGID_FT710; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strcmp(buf, "AI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AI0;"); n = write(fd, buf, strlen(buf)); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "AI0;") == 0) { hl_usleep(50 * 1000); } else if (strcmp(buf, "FT;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "FT%c;", tx_vfo); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("FT"); } } else if (strncmp(buf, "FT", 2) == 0) { tx_vfo = buf[2]; } else if (strcmp(buf, "MD0;") == 0) { printf("MD=%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD0%c;", modeA); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD0", 3) == 0) { modeA = buf[3]; } else if (strcmp(buf, "MD1;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "MD1%c;", modeB); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("MD0;"); } } else if (strncmp(buf, "MD1", 3) == 0) { modeB = buf[3]; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { hl_usleep(50 * 1000); n = fprintf(fp, "%s", "AI0;"); if (n <= 0) { perror("AI"); } } } #endif else if (strcmp(buf, "VS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VS"); } } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "KR;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "KR%d;", kr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("KR"); } } else if (strncmp(buf, "KR", 2) == 0) { sscanf(buf, "KR%d", &kr); } else if (strcmp(buf, "BI;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BI%d;", bi); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BI"); } } else if (strncmp(buf, "BI", 2) == 0) { sscanf(buf, "BI%d", &bi); } else if (strcmp(buf, "VX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VX%d;", vx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VX"); } } else if (strncmp(buf, "VX", 2) == 0) { sscanf(buf, "VX%d", &vx); } else if (strcmp(buf, "PA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PA%d;", pa); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PA"); } } else if (strncmp(buf, "PA", 2) == 0) { sscanf(buf, "PA%d", &vs); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RA%d;", ra); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RA"); } } else if (strncmp(buf, "RA", 2) == 0) { sscanf(buf, "RA%d", &ra); } else if (strcmp(buf, "AG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "AG%d;", ag); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("AG"); } } else if (strncmp(buf, "AG", 2) == 0) { sscanf(buf, "AG%d", &ag); } else if (strcmp(buf, "PC;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "PC%03d;", pc); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("PC"); } } else if (strncmp(buf, "PC", 2) == 0) { sscanf(buf, "PC%d", &pc); } else if (strcmp(buf, "VG;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "VG%03d;", vg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("VG"); } } else if (strncmp(buf, "VG", 2) == 0) { sscanf(buf, "VG%d", &vg); } else if (strcmp(buf, "RG0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RG0%03d;", rg); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RG"); } } else if (strncmp(buf, "RG", 2) == 0) { sscanf(buf, "RG0%d", &rg); } else if (strcmp(buf, "GT0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "GT0%0d;", gt); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("GT"); } } else if (strncmp(buf, "GT", 2) == 0) { sscanf(buf, "GT0%d", >); } else if (strcmp(buf, "TX;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "TX+%04d;", tx); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("TX"); } } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "IS;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "IS+%04d;", is); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("IS"); } } else if (strncmp(buf, "IS", 2) == 0) { sscanf(buf, "IS%d", &is); } else if (strcmp(buf, "RL0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "RL0%d;", rl); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("RL"); } } else if (strncmp(buf, "RL", 2) == 0) { sscanf(buf, "RL0%02d", &rl); } else if (strcmp(buf, "BP00;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_on); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP00", 4) == 0) { sscanf(buf, "BP00%d", &bp_on); } else if (strcmp(buf, "BP01;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "BP0%d;", bp_pos); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("BP"); } } else if (strncmp(buf, "BP01", 4) == 0) { sscanf(buf, "BP01%d", &bp_pos); } else if (strcmp(buf, "NB0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NB0%d;", nb); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NB"); } } else if (strncmp(buf, "NB0", 3) == 0) { sscanf(buf, "NB0%d", &nb); } else if (strcmp(buf, "NR0;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "NR0%d;", nr); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("NR"); } } else if (strncmp(buf, "NR0", 3) == 0) { sscanf(buf, "NR0%d", &nr); } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "EX016;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX016%04d;", ex016); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strcmp(buf, "EX020;") == 0) { hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX020%04d;", ex020); n = write(fd, buf, strlen(buf)); if (n < 0) { perror("EX016"); } } else if (strncmp(buf, "EX020", 5) == 0) { sscanf(buf, "EX020%d\n", &ex020); } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%d;", ks); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &ks); } else if (strncmp(buf, "MG;", 3) == 0) { sprintf(buf, "MG%03d;", mg); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%03d", &mg); } else if (strncmp(buf, "BS;", 3) == 0) // cannot query BS { sprintf(buf, "BS%02d;", bandselect); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0;", 4) == 0) { sprintf(buf, "SH0%02d;", width); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%02d", &width); } else if (strncmp(buf, "NA0;", 4) == 0) { sprintf(buf, "NA0%d;", narrow); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &narrow); } else if (strncmp(buf, "VD;", 3) == 0) { sprintf(buf, "VD%d;", vd); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VD", 2) == 0) { sscanf(buf, "VD%d", &vd); } else if (strncmp(buf, "SM0;", 4) == 0) { sprintf(buf, "SM0%d;", sm0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM0", 3) == 0) { sscanf(buf, "SM0%3d", &sm0); } else if (strncmp(buf, "SM1;", 4) == 0) { sprintf(buf, "SM1%d;", sm1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SM1", 3) == 0) { sscanf(buf, "SM1%3d", &sm1); } else if (strncmp(buf, "ST1", 3) == 0) { sscanf(buf, "ST1%3d", &st); } else if (strncmp(buf, "ST;", 3) == 0) { sprintf(buf, "ST%d;", st); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simxiegug90.c0000644000175000017500000002542114752216205014430 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include #include "../src/misc.h" #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_CW; mode_t modeB = RIG_MODE_USB; 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 keyspd = 20; void dumphex(const 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; 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; } } //printf("Error %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; 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; 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; 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; 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; 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 0xb0: freq = freqA; freqA = freqB; freqB = freq; break; } printf("set_vfo to %s\n", rig_strvfo(current_vfo)); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; case 0x0f: if (frame[5] == 0) { split = 0; } else { split = 1; } printf("set split %d\n", 1); frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); break; #if 0 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("n=write 8 bytes\n"); dump_hex(frame, 8); write(fd, frame, 8); break; #endif case 0x14: switch (frame[5]) { static int power_level = 0; static int level = 0; case 0x01: level = 255; printf("Using AF level %d\n", level); to_bcd(&frame[6], (long long) level, 2); frame[8] = 0xfd; write(fd, frame, 9); 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; write(fd, frame, 9); break; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 2); frame[8] = 0xfd; write(fd, frame, 9); } break; } break; case 0x15: switch (frame[5]) { static int meter_level = 0; 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; write(fd, frame, 9); break; } break; #if 0 case 0x18: // miscellaneous things frame[5] = 1; frame[6] = 0xfd; write(fd, frame, 7); break; #endif case 0x19: frame[6] = 0x00; frame[7] = 0x80; frame[8] = 0xfd; write(fd, frame, 9); 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; write(fd, frame, 8); break; } break; case 0x1c: switch (frame[5]) { case 0: if (frame[6] == 0xfd) { frame[6] = ptt; frame[7] = 0xfd; write(fd, frame, 8); } else { ptt = frame[6]; frame[7] = 0xfb; frame[8] = 0xfd; 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("get_freqA=%.0f\n", freqA); } else { to_bcd(&frame[6], (long long)freqB, (civ_731_mode ? 4 : 5) * 2); printf("get_freqB=%.0f\n", freqB); } frame[11] = 0xfd; 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; write(fd, frame, 6); } 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; write(fd, frame, 10); } else { for (int i = 0; i < 12; ++i) { printf("%02x:", frame[i]); } if (frame[5] == 0) { modeA = frame[6]; datamodeA = frame[7]; } else { modeB = frame[6]; datamodeB = frame[7]; } frame[4] = 0xfb; frame[5] = 0xfd; write(fd, frame, 6); } printf("\n"); break; #else case 0x25: frame[4] = 0xfa; frame[5] = 0xfd; break; case 0x26: frame[4] = 0xfa; frame[5] = 0xfd; break; #endif default: printf("cmd 0x%02x unknown\n", frame[4]); } // 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]); } frameParse(fd, buf, len); rigStatus(); } return 0; } hamlib-4.6.2/simulators/simkenwood.c0000644000175000017500000002370614752216205014441 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 fd = openPort(argv[1]); int freqa = 14074000, freqb = 140735000; int modeA = 0; // , modeB = 0; 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;"; write(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; write(fd, pbuf, strlen(pbuf)); } 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 ; write(fd, ifbuf, strlen(ifbuf)); continue; } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "MG050;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "AG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "AG100;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; write(fd, pbuf, strlen(pbuf)); continue; } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); 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;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strncmp(buf, "PC;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PC100;"); write(fd, buf, strlen(buf)); printf("%s\n", buf); continue; } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; write(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; 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); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); write(fd, buf, strlen(buf)); continue; } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; write(fd, pbuf, strlen(pbuf)); 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); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "EX", 2) == 0) { continue; } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); write(fd, buf, strlen(buf)); continue; } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); 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;"); write(fd, buf, strlen(buf)); continue; } if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); write(fd, buf, strlen(buf)); continue; } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator 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); 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); 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); 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); 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, "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; } hamlib-4.6.2/simulators/simts590.c0000644000175000017500000002734214752216205013657 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include #include "sim.h" #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 keyspd = 25; int width_high = 0; int width_low = 0; int afgain = 50; int usb_af = 9; int usb_af_input = 9; int mic_gain = 50; int getmyline(int fd, char *buf) { char c; int i = 0; memset(buf, 0, BUFSIZE); hl_usleep(5 * 1000); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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 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 = "RM50005;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "AN030;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "IF000503130001000+0000000000030000000;"; sprintf(ifbuf, "IF%011d1000+0000000000030000000;", freqa); //pbuf = "IF00010138698 +00000000002000000 ; WRITE(fd, ifbuf, strlen(ifbuf)); } else if (strcmp(buf, "NB;") == 0) { hl_usleep(mysleep * 1000); pbuf = "NB0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RA;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RA01;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "RG;") == 0) { hl_usleep(mysleep * 1000); pbuf = "RG055;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "MG;") == 0) { hl_usleep(mysleep * 1000); SNPRINTF(buf, sizeof(buf), "MG%03d;", mic_gain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MG", 2) == 0) { sscanf(buf, "MG%d", &mic_gain); } else if (strcmp(buf, "AG0;") == 0) { SNPRINTF(buf, sizeof(buf), "AG0%03d;", afgain); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "AG0", 3) == 0) { sscanf(buf, "AG0%d", &afgain); } else if (strncmp(buf, "AG", 2) == 0) { WRITE(fd, "?;", 2); } else if (strcmp(buf, "FV;") == 0) { hl_usleep(mysleep * 1000); pbuf = "FV1.2;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "IS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "IS+0000;"); WRITE(fd, buf, strlen(buf)); printf("%s\n", buf); } else if (strncmp(buf, "IS", 2) == 0) { } else if (strncmp(buf, "SM;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SM0035;"); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FW;") == 0) { //usleep(mysleep * 1000); pbuf = "FW240"; WRITE(fd, pbuf, strlen(pbuf)); hl_usleep(20 * 1000); pbuf = "0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strncmp(buf, "FW", 2) == 0) { } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); int id = 24; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); WRITE(fd, buf, strlen(buf)); } #if 0 else if (strncmp(buf, "AI", 2) == 0) { if (strcmp(buf, "AI;")) { printf("%s\n", buf); hl_usleep(mysleep * 1000); n = fprintf(fp, "%s", "AI0;"); } } #endif else if (strcmp(buf, "VS;") == 0) { printf("%s\n", buf); hl_usleep(mysleep * 1000); pbuf = "VS0;"; WRITE(fd, pbuf, strlen(pbuf)); } else if (strcmp(buf, "EX0640000;") == 0) // TS-590S version { SNPRINTF(buf, sizeof(buf), "EX0640000%d;", usb_af_input); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0640000", 9) == 0) // TS-590S version { sscanf(buf, "EX0640000%d", &usb_af_input); } else if (strcmp(buf, "EX0650000;") == 0) // TS-590S version { SNPRINTF(buf, sizeof(buf), "EX0650000%d;", usb_af); // TS-590S version WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0650000", 9) == 0) // TS-590S version { sscanf(buf, "EX0650000%d", &usb_af); } else if (strcmp(buf, "EX0710000;") == 0) // TS-590SG version { SNPRINTF(buf, sizeof(buf), "EX0710000%d;", usb_af_input); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0710000", 9) == 0) // TS-590SG version { sscanf(buf, "EX0710000%d", &usb_af_input); } else if (strcmp(buf, "EX0720000;") == 0) // TS-590SG version { SNPRINTF(buf, sizeof(buf), "EX0720000%d;", usb_af); // TS-590SG version WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX0720000", 9) == 0) // TS-590S version { sscanf(buf, "EX0720000%d", &usb_af); } 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); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX", 2) == 0) { } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%011d;", freqa); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%011d;", freqb); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%d", &freqa); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%d", &freqb); } else if (strncmp(buf, "AI;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "AI0;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "PS;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SA;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "SA0;"); 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'); WRITE(fd, buf, strlen(buf)); } 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); } else if (strncmp(buf, "MD;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "MD%d;", modeA); // not worried about modeB yet for simulator WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { sscanf(buf, "MD%d", &modeA); // not worried about modeB yet for simulator } else if (strncmp(buf, "FL;", 3) == 0) { SNPRINTF(buf, sizeof(buf), "FL%03d;", filternum); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "FL", 2) == 0) { sscanf(buf, "FL%d", &filternum); } else if (strcmp(buf, "FR;") == 0) { SNPRINTF(buf, sizeof(buf), "FR%d;", vfo); WRITE(fd, buf, strlen(buf)); } 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); WRITE(fd, buf, strlen(buf)); } 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); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "DA", 2) == 0) { sscanf(buf, "DA%d", &datamode); } else if (strncmp(buf, "BD;", 3) == 0) { } else if (strncmp(buf, "BU;", 3) == 0) { } 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; } } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "KS", 2) == 0) { sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "SH", 2) == 0 && strlen(buf) > 4) { } else if (strncmp(buf, "SH", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SH%02d;", width_high); WRITE(fd, buf, strlen(buf)); } else if (strncmp(buf, "SL", 2) == 0 && strlen(buf) > 4) { sscanf(buf, "SL%d", &width_low); printf("width_main=%d, width_sub=%d\n", width_high, width_low); } else if (strncmp(buf, "SL", 2) == 0) { SNPRINTF(buf, sizeof(buf), "SL%02d;", width_low); WRITE(fd, buf, strlen(buf)); } else if (strcmp(buf, "KY;") == 0) { SNPRINTF(buf, sizeof(buf), "KY0;"); WRITE(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simtmd700.c0000644000175000017500000000772614752216205014012 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 double freqA = 147000000; double freqB = 148000000; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '0'; char modeB = '0'; int band = 0; int control = 1; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { if (c == 0x0d) { return strlen(buf); } buf[i++] = c; } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]; int n; int fd = openPort(argv[1]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "ID") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "ID TM-D700\r"); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "BC") == 0) { SNPRINTF(buf, sizeof(buf), "BC %d,%d\r", band, control); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "BC ", 3) == 0) { sscanf(buf, "BC %d,%d", &band, &control); SNPRINTF(buf, sizeof(buf), "BC %d,%d\r", band, control); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VMC ", 4) == 0) { SNPRINTF(buf, sizeof(buf), "VMC 0,0\r"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { SNPRINTF(buf, sizeof(buf), "AI 0\r"); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FQ", 2) == 0) { SNPRINTF(buf, sizeof(buf), "FQ %011.0f,0\r", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FQ ", 3) == 0) { sscanf(buf, "FQ %lf,0", &freqA); SNPRINTF(buf, sizeof(buf), "FQ %011.0f,0\r", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD", 2) == 0) { SNPRINTF(buf, sizeof(buf), "MD 0\r"); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simic275.c0000644000175000017500000003322214752216205013616 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #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 transceive = 0; int keyspd = 20; int rigtime = 1230; void dumphex(const 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, n; 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) { char mytime[256]; date_strget(mytime, sizeof(mytime), 1); printf("%s:", mytime); dumphex(buf, i); // echo n = write(fd, buf, i); if (n != i) { printf("%s: error on write: %s\n", __func__, strerror(errno)); } 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 %s\n", strerror(errno)); return 0; } void frameParse(int fd, unsigned char *frame, int len) { double freq; int n = 0; if (len == 0) { printf("%s: len==0\n", __func__); return; } 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 0xa0: current_vfo = freq = freqA; freqA = freqB; freqB = freq; break; case 0xb0: current_vfo = RIG_VFO_MAIN; 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; } if (frame[5] == 0xfd) { frame[5] = split; printf("get split %d\n", 1); frame[6] = 0xfd; n = write(fd, frame, 7); } 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; case 0x0c: dumphex(frame, 10); printf("subcmd=0x0c #1\n"); if (frame[6] != 0xfd) // then we have data { printf("subcmd=0x0c #1\n"); keyspd = from_bcd(&frame[6], 2); frame[6] = 0xfb; n = write(fd, frame, 7); } else { printf("subcmd=0x0c #1\n"); to_bcd(&frame[6], keyspd, 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 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 0x05: // FE FE 70 E0 1A 05 00 92 00 FD printf("0x05 received\n"); if (frame[6] == 0x00 && frame[7] == 0x92) { if (frame[8] == 0x00) { printf("0x05 0x00 0x92 received\n"); transceive = frame[8]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = transceive; frame[9] = 0xfb; frame[10] = 0xfd; n = write(fd, frame, 11); } } // FE FE 70 E0 1A 05 00 41 00 FD else if (frame[6] == 0x00 && frame[7] == 0x41) { if (frame[8] != 0xfd) { printf("0x05 0x00 0x41 received\n"); rigtime = frame[8] * 100 + frame[9]; frame[6] = 0xfb; frame[7] = 0xfd; n = write(fd, frame, 8); } else { frame[8] = rigtime / 100; frame[9] = rigtime % 100; frame[10] = 0xfd; n = write(fd, frame, 11); } } break; case 0x06: // Data mode if (frame[6] == 0xfd) // then we're replying with mode { frame[6] = datamodeA; frame[7] = 0xfd; n = write(fd, frame, 8); } else { datamodeA = frame[6]; frame[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } 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[4] = 0xfb; frame[5] = 0xfd; n = write(fd, frame, 6); } break; } break; 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; 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()); printf("x25/x26 command rejected\n"); #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; } hamlib-4.6.2/simulators/simftdx5000.c0000644000175000017500000001674614752216205014253 00000000000000// 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 #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; int vfo = 0; int ft = 0; int md0 = 1; int md1 = 1; int vs = 0; int tx = 0; int ai = 0; int sh = 25; int na = 0; int ex039 = 0; int ex103 = 0; // 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) { char c; int i = 0; memset(buf, 0, BUFSIZE); while (read(fd, &c, 1) > 0) { buf[i++] = c; if (c == ';') { return strlen(buf); } } if (strlen(buf) == 0) { hl_usleep(10 * 1000); } 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]); while (1) { if (getmyline(fd, buf)) { printf("Cmd:%s\n", buf); } else { continue; } if (strcmp(buf, "RM5;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "RM5100000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("RM5"); } } if (strcmp(buf, "AN0;") == 0) { printf("%s\n", buf); hl_usleep(50 * 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) { printf("%s\n", buf); hl_usleep(50 * 1000); pbuf = "IF059014200000+000000700000;"; n = write(fd, pbuf, strlen(pbuf)); printf("n=%d\n", n); if (n <= 0) { perror("IF"); } } else if (strcmp(buf, "ID;") == 0) { printf("%s\n", buf); hl_usleep(50 * 1000); int id = NC_RIGID_FTDX3000; SNPRINTF(buf, sizeof(buf), "ID%03d;", id); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n <= 0) { perror("ID"); } } else if (strcmp(buf, "EX032;") == 0) { static int ant = 0; ant = (ant + 1) % 3; printf("%s\n", buf); hl_usleep(50 * 1000); SNPRINTF(buf, sizeof(buf), "EX032%1d;", ant); n = write(fd, buf, strlen(buf)); printf("n=%d\n", n); if (n < 0) { perror("EX032"); } } else if (strcmp(buf, "FA;") == 0) { SNPRINTF(buf, sizeof(buf), "FA%08.0f;", freqA); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FA", 2) == 0) { sscanf(buf, "FA%f", &freqA); } else if (strcmp(buf, "FB;") == 0) { SNPRINTF(buf, sizeof(buf), "FB%08.0f;", freqB); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FB", 2) == 0) { sscanf(buf, "FB%f", &freqB); } else if (strcmp(buf, "FT;") == 0) { SNPRINTF(buf, sizeof(buf), "FT%d;", ft); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "FT", 2) == 0) { int tmp; sscanf(buf, "FT%d", &tmp); if (tmp == 2) { ft = 0; } else if (tmp == 3) { ft = 1; } else { printf("%s expected FT2; or FT3;\n", buf); } } else if (strcmp(buf, "MD0;") == 0) { SNPRINTF(buf, sizeof(buf), "MD0%d;", md0); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD0", 2) == 0) { sscanf(buf, "MD0%d", &md0); } else if (strcmp(buf, "MD1;") == 0) { SNPRINTF(buf, sizeof(buf), "MD1%d;", md1); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "MD1", 2) == 0) { sscanf(buf, "MD1%d", &md1); } else if (strcmp(buf, "VS;") == 0) { SNPRINTF(buf, sizeof(buf), "VS%d;", vs); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "VS", 2) == 0) { sscanf(buf, "VS%d", &vs); } else if (strcmp(buf, "TX;") == 0) { SNPRINTF(buf, sizeof(buf), "TX%d;", tx); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "TX", 2) == 0) { sscanf(buf, "TX%d", &tx); } else if (strcmp(buf, "AI;") == 0) { SNPRINTF(buf, sizeof(buf), "AI%d;", ai); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "AI", 2) == 0) { sscanf(buf, "AI%d", &ai); } else if (strcmp(buf, "SH0;") == 0) { SNPRINTF(buf, sizeof(buf), "SH0%d;", sh); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "SH0", 3) == 0) { sscanf(buf, "SH0%d", &sh); } else if (strcmp(buf, "NA0;") == 0) { SNPRINTF(buf, sizeof(buf), "NA0%d;", na); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "NA0", 3) == 0) { sscanf(buf, "NA0%d", &na); } else if (strcmp(buf, "EX039;") == 0) { SNPRINTF(buf, sizeof(buf), "EX039%d;", ex039); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX039", 5) == 0) { sscanf(buf, "EX039%d", &ex039); } else if (strcmp(buf, "EX103;") == 0) { SNPRINTF(buf, sizeof(buf), "EX103%d;", ex103); n = write(fd, buf, strlen(buf)); } else if (strncmp(buf, "EX103", 3) == 0) { sscanf(buf, "EX103%d", &ex103); } else if (strcmp(buf, "PS;") == 0) { SNPRINTF(buf, sizeof(buf), "PS1;"); n = write(fd, buf, strlen(buf)); } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); } } return 0; } hamlib-4.6.2/simulators/simft736.c0000644000175000017500000000556614752216205013650 00000000000000// can run this using rigctl/rigctld and socat pty devices // gcc -o simft897 simft897.c #define _XOPEN_SOURCE 700 // since we are POSIX here we need this #if 0 struct ip_mreq { int dummy; }; #endif #include #include #include #include #include #include "../include/hamlib/rig.h" #define BUFSIZE 256 float freqA = 14074000; float freqB = 14074500; char tx_vfo = '0'; char rx_vfo = '0'; char modeA = '1'; char modeB = '1'; int width_main = 500; int width_sub = 700; int getmyline(int fd, unsigned char *buf) { unsigned char c; int i = 0; int n = 0; memset(buf, 0, BUFSIZE); while (i < 5 && read(fd, &c, 1) > 0) { buf[i++] = c; n++; } printf("n=%d %02x %02x %02x %02x %02x\n", n, buf[0], buf[1], buf[2], buf[3], buf[4]); return n; } #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[]) { unsigned char buf[256]; again: int fd = openPort(argv[1]); while (1) { int bytes = getmyline(fd, buf); if (bytes == 0) { close(fd); goto again; } if (bytes != 5) { printf("Not 5 bytes? bytes=%d\n", bytes); continue; } switch (buf[4]) { case 0x00: printf("CAT On\n"); break; case 0x80: printf("CAT Off\n"); break; case 0x01: printf("FREQ_SET\n"); break; case 0x07: printf("MODE_SET\n"); break; case 0x0e: printf("Full Duplex On\n"); break; case 0x8e: printf("Full Duplex Off\n"); break; case 0x08: printf("Tx\n"); break; case 0x88: printf("Rx\n"); break; case 0x17: printf("Full Duplex Rx Mode\n"); break; case 0x27: printf("Full Duplex Tx Mode\n"); break; case 0x1e: printf("Full Duplex Rx Freq\n"); break; case 0x2e: printf("Full Duplex Tx Freq\n"); break; default: printf("Unknown cmd=%02x\n", buf[4]); } fflush(stdout); } return 0; } hamlib-4.6.2/README.multicast0000644000175000017500000001634714752216205012603 00000000000000Planned for version 4.6 -- comments/suggestions about this are more than welcome Example of multicast packet as of 2023-10-20 =================================================================== { "app": "Hamlib", "version": "4.6~git 2023-10-20T16:52:59Z SHA=d87671", "seq": 183, "time": "2023-10-20T20:13:53.139869-0000", "crc": 0, "rig": { "id": "FLRig:127.0.0.1:12345:30508", "status": "OK", "errorMsg": "", "name": "FLRig", "split": false, "splitVfo": "VFOA", "satMode": false, "modelist": "AM CW USB LSB FM CWR PKTLSB PKTUSB " }, "vfos": [ { "name": "VFOA", "freq": 14074270, "mode": "PKTUSB", "width": 3, "ptt": false, "rx": true, "tx": true }, { "name": "VFOB", "freq": 14074500, "mode": "", "width": 0, "ptt": false, "rx": false, "tx": false } ], "spectra": [ { "id": 0, "name": "?", "type": "FIXED", "minLevel": 0, "maxLevel": 0, "minStrength": 0, "maxStrength": 0, "centerFreq": 0, "span": 0, "lowFreq": 0, "highFreq": 0, "length": 0, "data": "" } ] } =========================================================== Multicast UDP broadcast containing rig snapshot data Bidirectional rig control and status Choice of token pairs or JSON All packets will be tagged with ID=[unique name] -- so multiple rigs can broadcast/rx on the same port Will eventually be able to set freq, mode, width, ptt, satmode, and split to start since those are common to many apps. More functions will be added as time goes on. Broadcast packet contents to be based on get_rig_info output Can be multiple VFO lines Parsers should allow for unknown tags that may be added in the future Rig command: \get_rig_info VFO=Main Freq=145000000 Mode=None Width=0 RX=1 TX=1 VFO=VFOB Freq=145000000 Mode=FM Width=15000 RX=0 TX=0 Split=0 SatMode=0 PTT=1 (1=On, 0=Off) Rig=Dummy (name of connected rig) App=Hamlib (name of application providing the packet) Version=20210429 1.0.0 (version YYYYMMDD) Status=OK (possible values OK, Offline, Error) ErrorMsg=msg text (pipe delimited multi-line error message) CRC=0xf49f4708 (this is just an example CRC and not accurate for this example) JSON data snapshot format for UDP packets: { "app": "Hamlib", "__comment_version__": "protocol version YYYYMMDD x.x.x, 1.0.0 will be used when this is implemented", "version": "20210521 0.0.0", "__comment_seq__": "Seq is 1-up sequence number 32-bit -- wraps around to 1 from 2^32-1", "seq": 1, "__comment_crc__": "32-bit CRC of the entire JSON record replacing the CRC value with 0", "crc": 0, "rig": { "__comment1__": "customizable rig identification -- will allow multiple rigs to be on the multicast", "id": { "model":"IC-7300", "endpoint":"com1", "process":"53535", } "name": "IC-7300", "ptt" : false, "split": true, "splitVfo": "VFOB", "satMode": false, "status": "OK"; "errorMsg": "OK", "modes":[ "AM", "CW", "USB" ] }, "vfos": [ { "name": "VFOA", "freq": 14074000, "mode": "USB", "width": 5000, "rx": true, "tx": false }, { "name": "VFOB", "freq": 14076000, "mode": "USB", "width": 5000, "rx": false, "tx": true }], "__comment_spectra__": "Rigs that have spectrum output may include this array data", "spectra": [ { "__comment_id__": "A numeric ID for the spectrum data stream. These IDs are exposed in rig caps.", "id": 0, "__comment_name__": "Name identifying the spectrum data stream and matching the ID. The name corresponds to VFOs.", "name": "Main", "__comment_spectrum_length__": "Length of spectrum FFT data in bytes", "length": 475, "__comment_spectrum_data__": "Spectrum FFT data in 2-char hexadecimal byte format, so that length of the string is 2 * length", "data": "00AAFF75BD2AAA...", "type": "FIXED|CENTER", "minLevel": 0, "maxLevel": 140, "minStrength": -100, "maxStrength": 0, "__comment_spectrum_frequencies__": "The following fields will be calculated automatically by Hamlib based on the spectrum information exposed by the rig", "centerFreq": 14267000, "span": 25000, "lowFreq": 14000000, "highFreq": 14250000 }, { "__comment_id__": "A numeric ID for the spectrum data stream. These IDs are exposed in rig caps.", "id": 1, "__comment_name__": "Name identifying the spectrum data stream and matching the ID. The name corresponds to VFOs.", "name": "Sub", "__comment_spectrum_length__": "Length of spectrum FFT data in bytes", "length": 475, "__comment_spectrum_data__": "Spectrum FFT data in 2-char hexadecimal byte format, so that length of the string is 2 * length", "data": "00AAFF75BD2AAA...", "type": "FIXED|CENTER", "minLevel": 0, "maxLevel": 140, "minStrength": -100, "maxStrength": 0, "__comment_spectrum_frequencies__": "The following fields will be calculated automatically by Hamlib based on the spectrum information exposed by the rig", "centerFreq": 14267000, "span": 25000, "lowFreq": 14000000, "highFreq": 14250000 }], "lastCommand": { "id": "MyApp 123", "command": "set_freq VFOA 14074000", "status": "OK" }, } An example UDP packet containing spectrum data from IC-7300 (crc, id and lastCommand not implemented yet): { "app": "Hamlib", "version": "4.5~git Sun Dec 19 20:56:24 2021 +0000 SHA=0fe723", "seq": 109, "crc": 0, "rig": { "id": "rig_id", "status": "OK", "errorMsg": "", "name": "IC-7300", "split": false, "splitVfo": "VFOA", "satMode": false }, "vfos": [ { "name": "VFOA", "freq": 3718000, "mode": "LSB", "width": 3000, "ptt": false, "rx": true, "tx": true }, { "name": "VFOB", "freq": 3698750, "mode": "", "width": 0, "ptt": false, "rx": false, "tx": false } ], "spectra": [ { "id": 0, "name": "Main", "type": "CENTER", "minLevel": 0, "maxLevel": 160, "minStrength": -80, "maxStrength": 0, "centerFreq": 3718000, "span": 50000, "lowFreq": 3693000, "highFreq": 3743000, "length": 475, "data": "121514000000000000000811070000060F12090000000000000908000A0B000000000A130D000A04100C0C17141D1B20353A2D404537341D06110608070200000D0D02000000000B0A000709000005050504000D0B00040400000000070F0D081F29240E262E2C21222E3D3E343C383235393E505361624E4445252A2220191A2B2D28222217121619130D0C1513130F060100000509090200090B03000000000003000000000001000A0802000500000000010C0907000100000000050B0B000100000600000808000306000806000000000C030000000000070000000000020E000A000001000C0B0008000B080700020709000400070100000000000000000A07000A0905000000000002000000000B05010307050506080B050C0F0E100702131528230A0B1E13160B10000000050812231B001422251209181B1A201E0B1713050C020C0D001B1A2209000100000C050400040B0B110D07000009192010040700000910020D0C1928302526282D353F3B2E1F191C25281F0D0A0B1518140A0603030907030100000300060B0000060000000403000400000811221B0A131200040E070000110F0B150005141515211B1F0C0000040500000000000400000000000000000808070D0B00000000000000000000000000000000" } ] } hamlib-4.6.2/scripts/0000755000175000017500000000000014752216241011453 500000000000000hamlib-4.6.2/scripts/build-VB.NET.sh0000644000175000017500000001554314752216205013770 00000000000000#!/bin/sh # A script to build a set of VB.NET 2002 Framework 1.1 binary DLLs from a # Hamlib tarball. This script assumes that the Hamlib tarball has been # extracted to the directory specified in $build_dir and that # libusb-win32-bin-1.x.y.z has also been extracted to $build_dir and a # libusb.pc file has been created. The MS VC++ Toolkit must also be # installed. # # See README.build-VB.NET for complete details. # Set this to a desired directory BUILD_DIR=~/builds # Set this to LibUSB archive extracted in $BUILD_DIR LIBUSB_VER=libusb-win32-bin-1.2.4.0 # Error return codes. See /usr/include/sysexits.h EX_USAGE=64 EX_NOINPUT=66 # Pass name of Hamlib archive extracted in $BUILD_DIR if [ $# -ne 1 ]; then echo echo "Usage: $(basename $0) hamlib-version" echo "See README.build-VB.NET for more information." exit $EX_USAGE fi # Make sure the Hamlib archive is where we expect if [ -d ${BUILD_DIR}/$1 ]; then echo echo "Building VB.NET binaries in ${BUILD_DIR}/$1" echo cd ${BUILD_DIR}/$1 else echo "Build directory, ${BUILD_DIR}/$1 not found!" echo "Check path for $1 or correct the version number." exit $EX_NOINPUT fi # FIXME: Determine RELEASE only from AC_INIT line to avoid any other similar # values and avoid hard coded version number. RELEASE=$(/usr/bin/awk 'BEGIN{FS="["; RS="]"} /\[3\./ {print $2}' ./configure.ac) INST_DIR=$(pwd)/mingw-inst ZIP_DIR=$(pwd)/hamlib-VB.NET-${RELEASE} LIBUSB_WIN32_BIN_PATH=${BUILD_DIR}/${LIBUSB_VER} # Create VB.NET specific README.VB.NET-bin file cat > README.VB.NET-bin <include/hamlib/rig_dll.h rm include/hamlib/rig_dll.h.orig # Configure and build hamlib for mingw32, with libusb-win32 ./configure --host=i586-mingw32msvc \ --prefix=$(pwd)/mingw-inst \ --without-cxx-binding \ PKG_CONFIG_LIBDIR=${LIBUSB_WIN32_BIN_PATH}/lib/pkgconfig make install mkdir -p ${ZIP_DIR}/bin ${ZIP_DIR}/lib/msvc ${ZIP_DIR}/lib/gcc ${ZIP_DIR}/include cp -a src/libhamlib.def ${ZIP_DIR}/lib/msvc/libhamlib-2.def; todos ${ZIP_DIR}/lib/msvc/libhamlib-2.def cp -a ${INST_DIR}/include/hamlib ${ZIP_DIR}/include/.; todos ${ZIP_DIR}/include/hamlib/*.h # C++ binding is useless on win32 because of ABI for f in *class.h ; do \ rm ${ZIP_DIR}/include/hamlib/${f} done for f in AUTHORS ChangeLog COPYING COPYING.LIB LICENSE README.md README.betatester README.VB.NET-bin THANKS ; do \ cp -a ${f} ${ZIP_DIR}/${f}.txt ; todos ${ZIP_DIR}/${f}.txt ; done # Copy build files into specific locations for Zip file cp -a ${INST_DIR}/lib/hamlib/hamlib-*.dll ${ZIP_DIR}/bin/. cp -a ${INST_DIR}/bin/libhamlib-?.dll ${ZIP_DIR}/bin/. cp -a ${INST_DIR}/lib/libhamlib.dll.a ${ZIP_DIR}/lib/gcc/. # NB: Do not strip libusb0.dll i586-mingw32msvc-strip ${ZIP_DIR}/bin/*.exe ${ZIP_DIR}/bin/*hamlib-*.dll cp -a ${LIBUSB_WIN32_BIN_PATH}/bin/x86/libusb0_x86.dll ${ZIP_DIR}/bin/libusb0.dll # Need VC++ free toolkit installed (default Wine directory installation shown) ( cd ${ZIP_DIR}/lib/msvc/ && wine ~/.wine/drive_c/Program\ Files/Microsoft\ Visual\ C++\ Toolkit\ 2003/bin/link.exe /lib /machine:i386 /def:libhamlib-2.def ) zip -r hamlib-VB.NET-${RELEASE}.zip $(basename ${ZIP_DIR}) hamlib-4.6.2/scripts/build-w64-jtsdk.sh0000755000175000017500000002337014752216205014571 00000000000000#!/bin/sh # Builds Hamlib 4.x W64 dl binary distribution under Windows Qt MinGW/MSYS2 # Customised for >= JTSDK 3.2.0 B3 stream(s) # A script to compile a set of W64 binary DLLs, executables and compiler # packages from a Hamlib source tarball. This script assumes uses the # JTSDK's previously deployed LibUSB (pointed to by JTSDK environment # variable $libusb_dir_f) # See future README.build-JTSDK for complete details. #Ensure that the Qt-supplied GCC compilers and tools can be found export PATH=$PATH:$GCCD_F:. # Set this to a desired directory if [[ -z "${BUILD_BASE_DIR}" ]]; then BUILD_DIR=~/builds else BUILD_DIR=~/${BUILD_BASE_DIR} fi # Set this to LibUSB archive extracted in $BUILD_DIR LIBUSB_VER=libusb-1.0.24 # Set to the correct HOST_ARCH= line for your minGW installation HOST_ARCH=x86_64-w64-mingw32 # Set to the strip name for your version of minGW HOST_ARCH_STRIP=strip.exe # Set to the name of the utility to provide Unix to DOS translation UNIX_TO_DOS_TOOL=unix2dos.exe # Error return codes. See /usr/include/sysexits.h EX_USAGE=64 EX_NOINPUT=66 # Pass name of Hamlib archive extracted in $BUILD_DIR if test $# -ne 1 then echo echo "Usage: $(basename $0) hamlib-version" echo "See README.build-Windows for more information." echo exit ${EX_USAGE} fi # Make sure the Hamlib archive is where we expect if test -d ${BUILD_DIR}/$1 then echo echo "Building W64 binaries in ${BUILD_DIR}/$1" echo cd ${BUILD_DIR}/$1 else echo echo "Build directory, ${BUILD_DIR}/$1 not found!" echo "Check path for $1 or correct the version number." echo exit ${EX_NOINPUT} fi RELEASE=$(/usr/bin/awk 'BEGIN{FS="["; RS="]"} /\[4\./ {print $2;exit}' ./configure.ac) HL_FILENAME=hamlib-w64-${RELEASE} INST_DIR=$(pwd)/mingw64-inst ZIP_DIR=$(pwd)/${HL_FILENAME} # LIBUSB_1_0_BIN_PATH=${BUILD_DIR}/${LIBUSB_VER} # REDUNDANT # Create W64 specific README.w64-bin file cat > README.w64-bin < Radio model 1020, or Yaesu FT-817 (use 'rigctl -l' for a list) -r -> Radio device, in this case COM1 -v -> Verbosity level. For testing four or five v characters are required. Five 'v's set a debug level of TRACE which generates a lot of screen output showing communication to the radio and values of important variables. These traces are vital information for Hamlib rig backend development. To run rigctl or rotctl open a cmd window (Start|Run|enter 'cmd' in the dialog). If text scrolls off the screen, you can scroll back with the mouse. To copy output text into a mailer or editor (I recommend Notepad++, a free editor also licensed under the GPL), highlight the text as a rectangle in the cmd window, press (or right-click the window icon in the upper left corner and select Edit, then Copy), and paste it into your editor with Ctl-V (or Edit|Paste from the typical GUI menu). All feedback is welcome to the mail address below. Uninstall ========= To uninstall, simply delete the Hamlib directory. You may wish to edit the PATH as above to remove the Hamlib bin path, if desired. Information for w64 Programmers ================================= The DLL has a cdecl interface. There is a libhamlib-4.def definition file for MS Visual C++/Visual Studio in lib/msvc. Refer to the sample commands below to generate a local libhamlib-4.lib file for use with the VC++/VS linker. Simply #include (add directory to include path), include libhamlib-4.lib in your project and you are done. Note: VC++/VS cannot compile all the Hamlib code, but the API defined by rig.h has been made MSVC friendly :-) As the source code for the library DLLs is licensed under the LGPL, your program is not considered a "derivative work" when using the published Hamlib API and normal linking to the front-end library, and may be of a license of your choosing. For linking the library with MS Visual C++ 2003, from the directory you installed Hamlib run the following commands to generate the libhamlib-4.lib file needed for linking with your MSVC project: cd lib\msvc c:\Program Files\Microsoft Visual C++ Toolkit 2003\bin\link.exe /lib /machine:amd64 /def:libhamlib-4.def To do the same for Visual Studio 2017: cd lib\msvc c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x86\bin\link.exe /lib /machine:i386 /def:libhamlib-4.def and for VS 2019: cd lib\msvc c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x86\bin\link.exe /lib /machine:i386 /def:libhamlib-4.def NOTE: feedback is requested on the previous two command examples as these do not appear to be correct to generate a 64 bit libhamlib-4.lib file! The published Hamlib API may be found at: http://hamlib.sourceforge.net/manuals/4.1/index.html Thank You! ========== Patches, feedback, and contributions are welcome. Please report problems or success to hamlib-developer@lists.sourceforge.net Cheers, Stephane Fillod - F8CFE Nate Bargmann - N0NB JTSDK Maintenance Team - JTSDK@GROUPS.IO http://www.hamlib.org END_OF_README # Configure and build hamlib for x86_64-w64-mingw32, with libusb-1.0 ./configure --host=${HOST_ARCH} \ --prefix=${INST_DIR} \ --without-cxx-binding \ --disable-static \ CPPFLAGS="-I${libusb_dir_f}/include" \ LDFLAGS="-L${libusb_dir_f}/MinGW64/dll" make -j ${CPUS} install mkdir -p ${ZIP_DIR}/bin ${ZIP_DIR}/lib/msvc ${ZIP_DIR}/lib/gcc ${ZIP_DIR}/include ${ZIP_DIR}/doc cp -a src/libhamlib.def ${ZIP_DIR}/lib/msvc/libhamlib-4.def ${UNIX_TO_DOS_TOOL} ${ZIP_DIR}/lib/msvc/libhamlib-4.def cp -a ${INST_DIR}/include/hamlib ${ZIP_DIR}/include/. ${UNIX_TO_DOS_TOOL} ${ZIP_DIR}/include/hamlib/*.h # C++ binding is useless on w64 because of ABI for f in *class.h do rm ${ZIP_DIR}/include/hamlib/${f} done for f in AUTHORS ChangeLog COPYING COPYING.LIB LICENSE README.md README.betatester README.w64-bin THANKS do cp -a ${f} ${ZIP_DIR}/${f}.txt ${UNIX_TO_DOS_TOOL} ${ZIP_DIR}/${f}.txt done # Generate HTML documents from nroff formatted man files for f in doc/man1/*.1 doc/man7/*.7 do /usr/bin/groff -mandoc -Thtml >${f}.html ${f} cp -a ${f}.html ${ZIP_DIR}/doc/. done cd ${BUILD_DIR}/$1 # Copy build files into specific locations for Zip file for f in *.exe do cp -a ${INST_DIR}/bin/${f} ${ZIP_DIR}/bin/. done cp -a ${INST_DIR}/bin/libhamlib-?.dll ${ZIP_DIR}/bin/. cp -a ${INST_DIR}/lib/libhamlib.dll.a ${ZIP_DIR}/lib/gcc/. # NB: Strip Hamlib DLLs and EXEs ${HOST_ARCH_STRIP} ${ZIP_DIR}/bin/*.exe ${ZIP_DIR}/bin/*hamlib-*.dll # Copy needed third party DLLs cp -a ${QTD_F}/libwinpthread-1.dll ${ZIP_DIR}/bin/. cp -a ${libusb_dir_f}/MinGW64/dll/libusb-1.0.dll ${ZIP_DIR}/bin/libusb-1.0.dll # Set for MinGW build - To Be safe ! FILE="${QTD_F}/libgcc_s_seh-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Copy over the main MSYS2 Runtime DLL (v2.0 at time of development) # This is dirty FILE="/usr/bin/msys-2.0.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 6.3 (Debian 9) FILE="/usr/lib/gcc/i686-w64-mingw32/6.3-posix/libgcc_s_sjlj-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 8.3 (Debian 10) FILE="/usr/lib/gcc/i686-w64-mingw32/8.3-posix/libgcc_s_sjlj-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi /usr/bin/zip -r ${HL_FILENAME}.zip $(basename ${ZIP_DIR}) hamlib-4.6.2/scripts/Makefile.am0000644000175000017500000000021614752216205013426 00000000000000EXTRA_DIST = README.scripts build-w32.sh build-w64.sh build-w64-jtsdk.sh README.build-Windows \ build-VB.NET.sh README.build-VB.NET astylerc hamlib-4.6.2/scripts/Makefile.in0000644000175000017500000003624714752216217013457 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = scripts ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = README.scripts build-w32.sh build-w64.sh build-w64-jtsdk.sh README.build-Windows \ build-VB.NET.sh README.build-VB.NET astylerc all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu scripts/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/scripts/README.build-VB.NET0000644000175000017500000000153014752216205014302 00000000000000The build-VB.NET.sh script creates a binary ZIP archive of Hamlib compiled for Win32 using the __stdcall interface for Visual Basic.NET 2002 Framework 1.1. The release is possibly usable by other VB versions, but success has not been reported to the Hamlib team. The script is very similar to the build-win32.sh script and has the same Prerequisites for development tools. The differences are the use of sed(1) to edit include/hamlib.rig_dll.h for __stdcall, output of a customized README.VB.NET-bin file, and naming of the ZIP archive. See README.build-win32 for more information. The Hamlib developers would appreciate help making Hamlib, and the binary release generated by the script, usable by other versions of Visual Basic. Interested developers may contact us by our mailing list: hamlib-developer@lists.sourceforge.net 73, Nate, N0NB hamlib-4.6.2/scripts/build-w32.sh0000755000175000017500000002334314752216205013447 00000000000000#!/bin/sh # Builds Hamlib 4.x W32 binary distribution. # A script to build a set of W32 binary DLLs and executables from a Hamlib # source tarball. This script assumes that the Hamlib source tarball has been # extracted to the directory specified in $BUILD_DIR and that libusb-1.x.y has # also been extracted to $BUILD_DIR. # See README.build-Windows for complete details. # Set this to a desired directory BUILD_DIR=~/builds # Set this to LibUSB archive extracted in $BUILD_DIR LIBUSB_VER=libusb-1.0.24 # Set to the correct HOST_ARCH= line for your MinGW installation HOST_ARCH=i686-w64-mingw32 # Set to the strip name for your version of MinGW HOST_ARCH_STRIP=i686-w64-mingw32-strip # Set to the dlltool name for your version of MinGW HOST_ARCH_DLLTOOL=i686-w64-mingw32-dlltool # Error return codes. See /usr/include/sysexits.h EX_USAGE=64 EX_NOINPUT=66 # Pass name of Hamlib archive extracted in $BUILD_DIR if test $# -ne 1 then echo echo "Usage: $(basename $0) hamlib-version" echo "See README.build-Windows for more information." echo exit ${EX_USAGE} fi # Make sure the Hamlib archive is where we expect if test -d ${BUILD_DIR}/$1 then echo echo "Building W32 binaries in ${BUILD_DIR}/$1" echo cd ${BUILD_DIR}/$1 else echo echo "Build directory, ${BUILD_DIR}/$1 not found!" echo "Check path for $1 or correct the version number." echo exit ${EX_NOINPUT} fi RELEASE=$(/usr/bin/awk 'BEGIN{FS="["; RS="]"} /\[4\./ {print $2;exit}' ./configure.ac) HL_FILENAME=hamlib-w32-${RELEASE} INST_DIR=$(pwd)/mingw32-inst ZIP_DIR=$(pwd)/${HL_FILENAME} LIBUSB_1_0_BIN_PATH=${BUILD_DIR}/${LIBUSB_VER} # Create W32 specific README.w32-bin file cat > README.w32-bin < Radio model 1020, or Yaesu FT-817 (use 'rigctl -l' for a list) -r -> Radio device, in this case COM1 -v -> Verbosity level. For testing four or five v characters are required. Five 'v's set a debug level of TRACE which generates a lot of screen output showing communication to the radio and values of important variables. These traces are vital information for Hamlib rig backend development. To run rigctl or rotctl open a cmd window (Start|Run|enter 'cmd' in the dialog). If text scrolls off the screen, you can scroll back with the mouse. To copy output text into a mailer or editor (I recommend Notepad++, a free editor also licensed under the GPL), highlight the text as a rectangle in the cmd window, press (or right-click the window icon in the upper left corner and select Edit, then Copy), and paste it into your editor with Ctl-V (or Edit|Paste from the typical GUI menu). All feedback is welcome to the mail address below. Uninstall ========= To uninstall, simply delete the Hamlib directory. You may wish to edit the PATH as above to remove the Hamlib bin path, if desired. Information for w32 Programmers ================================= The DLL has a cdecl interface. There is a libhamlib-4.def definition file for MS Visual C++/Visual Studio in lib/msvc. Refer to the sample commands below to generate a local libhamlib-4.lib file for use with the VC++/VS linker. Simply #include (add directory to include path), include libhamlib-4.lib in your project and you are done. Note: VC++/VS cannot compile all the Hamlib code, but the API defined by rig.h has been made MSVC friendly :-) As the source code for the library DLLs is licensed under the LGPL, your program is not considered a "derivative work" when using the published Hamlib API and normal linking to the front-end library, and may be of a license of your choosing. As of 08 Sep 2022 a .lib file is generated using the MinGW dlltool utility. If this file does not work for your project, follow the steps in the following section: For linking the library with MS Visual C++ 2003, from the directory you installed Hamlib run the following commands to generate the libhamlib-4.lib file needed for linking with your MSVC project: cd lib\msvc c:\Program Files\Microsoft Visual C++ Toolkit 2003\bin\link.exe /lib /machine:i386 /def:libhamlib-4.def To do the same for Visual Studio 2017: cd lib\msvc c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Tools\MSVC\14.16.27023\bin\Hostx64\x86\bin\link.exe /lib /machine:i386 /def:libhamlib-4.def For VS 2019: cd lib\msvc c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x86\bin\link.exe /lib /machine:i386 /def:libhamlib-4.def NOTE: feedback is requested on the previous two command examples! The published Hamlib API may be found at: http://hamlib.sourceforge.net/manuals/4.1/index.html Thank You! ========== Patches, feedback, and contributions are welcome. Please report problems or success to hamlib-developer@lists.sourceforge.net Cheers, Stephane Fillod - F8CFE Mike Black - W9MDB Nate Bargmann - N0NB http://www.hamlib.org END_OF_README # Configure and build hamlib for i686-w64-mingw32, with libusb-1.0 ./configure --host=${HOST_ARCH} \ --prefix=${INST_DIR} \ --without-cxx-binding \ --disable-static \ CPPFLAGS="-I${LIBUSB_1_0_BIN_PATH}/include" \ LDFLAGS="-L${LIBUSB_1_0_BIN_PATH}/MinGW32/dll" make -j 4 install mkdir -p ${ZIP_DIR}/bin ${ZIP_DIR}/lib/msvc ${ZIP_DIR}/lib/gcc ${ZIP_DIR}/include ${ZIP_DIR}/doc cp -a src/libhamlib.def ${ZIP_DIR}/lib/msvc/libhamlib-4.def todos ${ZIP_DIR}/lib/msvc/libhamlib-4.def cp -a ${INST_DIR}/include/hamlib ${ZIP_DIR}/include/. todos ${ZIP_DIR}/include/hamlib/*.h # C++ binding is useless on w32 because of ABI for f in *class.h do rm ${ZIP_DIR}/include/hamlib/${f} done for f in AUTHORS ChangeLog COPYING COPYING.LIB LICENSE README.md README.betatester README.w32-bin THANKS do cp -a ${f} ${ZIP_DIR}/${f}.txt todos ${ZIP_DIR}/${f}.txt done # Generate HTML documents from nroff formatted man files for f in doc/man1/*.1 doc/man7/*.7 do /usr/bin/groff -mandoc -Thtml >${f}.html ${f} cp -a ${f}.html ${ZIP_DIR}/doc/. done cd ${BUILD_DIR}/$1 # Copy build files into specific locations for Zip file for f in *.exe do cp -a ${INST_DIR}/bin/${f} ${ZIP_DIR}/bin/. done cp -a ${INST_DIR}/bin/libhamlib-?.dll ${ZIP_DIR}/bin/. cp -a ${INST_DIR}/lib/libhamlib.dll.a ${ZIP_DIR}/lib/gcc/. # NB: Strip Hamlib DLLs and EXEs ${HOST_ARCH_STRIP} ${ZIP_DIR}/bin/*.exe ${ZIP_DIR}/bin/*hamlib-*.dll # Copy needed third party DLLs cp -a /usr/i686-w64-mingw32/lib/libwinpthread-1.dll ${ZIP_DIR}/bin/. cp -a ${LIBUSB_1_0_BIN_PATH}/MinGW32/dll/libusb-1.0.dll ${ZIP_DIR}/bin/libusb-1.0.dll # Required for MinGW with GCC 6.3 (Debian 9) FILE="/usr/lib/gcc/i686-w64-mingw32/6.3-posix/libgcc_s_sjlj-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 8.3 (Debian 10) FILE="/usr/lib/gcc/i686-w64-mingw32/8.3-posix/libgcc_s_sjlj-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 10 (Debian 11) FILE="/usr/lib/gcc/i686-w64-mingw32/10-posix/libgcc_s_dw2-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 12 (Debian 12) FILE="/usr/lib/gcc/i686-w64-mingw32/12-posix/libgcc_s_dw2-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Generate .lib file for MSVC ${HOST_ARCH_DLLTOOL} --input-def ${ZIP_DIR}/lib/msvc/libhamlib-4.def --output-lib ${ZIP_DIR}/lib/msvc/libhamlib-4.lib /usr/bin/zip -r ${HL_FILENAME}.zip $(basename ${ZIP_DIR}) hamlib-4.6.2/scripts/astylerc0000644000175000017500000000206214752216205013144 00000000000000# astylerc--custom options for astyle # K&R style formatting/indenting with some tweaks. style=allman # Indent with a width of 4 spaces. indent=spaces=4 # Pad empty lines around header blocks (e.g. 'if', 'for', 'while'...). break-blocks # Remove extra space padding around parenthesis on the inside and outside. unpad-paren # Insert space padding around operators. pad-oper # Insert space padding after paren headers only (e.g. 'if', 'for', 'while'...). pad-header # Attach a pointer operator (*) to name (name) and reference operator (&) # to type (type). align-pointer=name align-reference=type # Add brackets to unbracketed one line conditional statements # (e.g. 'if', 'for', 'while'...). add-brackets # Don't break one-line blocks. keep-one-line-blocks # Don't break complex statements and multiple statements residing on a single line. keep-one-line-statements # Converts tabs into spaces in the non-indentation part of the line. convert-tabs # try to shorten long lines to 80 characters max-code-length=80 # Preserve the file date and time preserve-date hamlib-4.6.2/scripts/README.build-Windows0000644000175000017500000000554214752216205015007 00000000000000 This file is a HOWTO for the cross-compiling of Windows 32 and 64 bit binary DLLs built from a tarball generated by 'make dist' in a Git checkout. The resulting DLLs are built with a cdecl interface compatible with MS VC++. Prerequisites ============= In these steps the release or daily snapshot tarball is unpacked in $HOME/builds for the Windows build and all operations are done from there unless otherwise noted. Under Linux you need at least the following packages: mingw-w64 cross-compiler zip create the archive tofrodos convert to DOS text format (CR/LF) groff convert nroff manual pages to HTML On Debian 8 (Jessie) and later versions the mingw-w64 package works and is being used to build the daily Windows 32/64 snapshots and stable releases. The release and daily snapshots are built in a Debian 10 (Buster) virtual machine. Finally, the Windows version of libusb 1.0 must be available for the USB backends to be built. Download the latest libusb-1.0 from: https://sourceforge.net/projects/libusb/files/libusb-1.0/ and unzip the archive in $HOME/builds. libusb 1.0.20 is known to work. Presumably, any 1.X.X version should work. Several variables may need to be set differently at the top of the script file depending on your system. The script now relies on a pair of environment variables to locate the needed libusb files. The script generates HTML documents for the included .EXE files using groff to convert the nroff formatted man pages. Build for Windows 32/64, cross-compile on Linux: ================================================ Extract the Hamlib tarball into $HOME/builds (if you prefer another directory be sure to edit the BUILD_DIR variable in the build-w[32|64].sh script): $ tar xvfz $HOME/Downloads/hamlib-4.2~git-???????-20210214.tar.gz Invoke the build-w[32|64].sh script (either requires a Bourne compatible shell, e.g. bash, dash, etc.) with the name of the directory/Hamlib version to build (you need not cd into the hamlib directory, although it won't hurt. The build-w[32|64].sh script uses absolute paths): $ build-w32.sh hamlib-4.2~git or: $ build-w64.sh hamlib-4.2~git Release Info ============ The structure of the archive is: $ tree -d . |-- bin |-- doc |-- include | `-- hamlib |-- lib |-- gcc `-- msvc 8 directories The bin/ directory is where the executables and DLL files are placed. Header files are under include/Hamlib/ and compiler specific files are under lib/*. HTML documents for the .EXE programs are in doc/ while text documents (READMEs and such) are in the main archive directory. The doc/ directory contains the classic Unix manual pages converted to HTML. The embedded README.w[32|64]-bin.txt file generated by the build-w[32|64].sh script describes setting the PATH environment variable in Windows 2000, Windows XP, and Windows 7. 73, Nate, N0NB hamlib-4.6.2/scripts/build-w64.sh0000755000175000017500000002376114752216205013460 00000000000000#!/bin/sh # Builds Hamlib 4.x W64 binary distribution. # A script to build a set of W64 binary DLLs and executables from a Hamlib # source tarball. This script assumes that the Hamlib source tarball has been # extracted to the directory specified in $BUILD_DIR and that libusb-1.x.y has # also been extracted to $BUILD_DIR. # See README.build-Windows for complete details. # Set this to a desired directory BUILD_DIR=~/builds # Set this to LibUSB archive extracted in $BUILD_DIR LIBUSB_VER=libusb-1.0.24 # Set to the correct HOST_ARCH= line for your MinGW installation HOST_ARCH=x86_64-w64-mingw32 # Set to the strip name for your version of MinGW HOST_ARCH_STRIP=x86_64-w64-mingw32-strip # Set to the dlltool name for your version of MinGW HOST_ARCH_DLLTOOL=x86_64-w64-mingw32-dlltool # Error return codes. See /usr/include/sysexits.h EX_USAGE=64 EX_NOINPUT=66 # Pass name of Hamlib archive extracted in $BUILD_DIR if test $# -ne 1 then echo echo "Usage: $(basename $0) hamlib-version" echo "See README.build-Windows for more information." echo exit ${EX_USAGE} fi # Make sure the Hamlib archive is where we expect if test -d ${BUILD_DIR}/$1 then echo echo "Building W64 binaries in ${BUILD_DIR}/$1" echo cd ${BUILD_DIR}/$1 else echo echo "Build directory, ${BUILD_DIR}/$1 not found!" echo "Check path for $1 or correct the version number." echo exit ${EX_NOINPUT} fi RELEASE=$(/usr/bin/awk 'BEGIN{FS="["; RS="]"} /\[4\./ {print $2;exit}' ./configure.ac) HL_FILENAME=hamlib-w64-${RELEASE} INST_DIR=$(pwd)/mingw64-inst ZIP_DIR=$(pwd)/${HL_FILENAME} LIBUSB_1_0_BIN_PATH=${BUILD_DIR}/${LIBUSB_VER} # Create W64 specific README.w64-bin file cat > README.w64-bin < Radio model 1020, or Yaesu FT-817 (use 'rigctl -l' for a list) -r -> Radio device, in this case COM1 -v -> Verbosity level. For testing four or five v characters are required. Five 'v's set a debug level of TRACE which generates a lot of screen output showing communication to the radio and values of important variables. These traces are vital information for Hamlib rig backend development. To run rigctl or rotctl open a cmd window (Start|Run|enter 'cmd' in the dialog). If text scrolls off the screen, you can scroll back with the mouse. To copy output text into a mailer or editor (I recommend Notepad++, a free editor also licensed under the GPL), highlight the text as a rectangle in the cmd window, press (or right-click the window icon in the upper left corner and select Edit, then Copy), and paste it into your editor with Ctl-V (or Edit|Paste from the typical GUI menu). All feedback is welcome to the mail address below. Uninstall ========= To uninstall, simply delete the Hamlib directory. You may wish to edit the PATH as above to remove the Hamlib bin path, if desired. Information for w64 Programmers ================================= The DLL has a cdecl interface. There is a libhamlib-4.def definition file for MS Visual C++/Visual Studio in lib/msvc. Refer to the sample commands below to generate a local libhamlib-4.lib file for use with the VC++/VS linker. Simply #include (add directory to include path), include libhamlib-4.lib in your project and you are done. Note: VC++/VS cannot compile all the Hamlib code, but the API defined by rig.h has been made MSVC friendly :-) As the source code for the library DLLs is licensed under the LGPL, your program is not considered a "derivative work" when using the published Hamlib API and normal linking to the front-end library, and may be of a license of your choosing. As of 08 Sep 2022 a .lib file is generated using the MinGW dlltool utility. If this file does not work for your project, follow the steps in the following section: For linking the library with MS Visual C++ 2003, from the directory you installed Hamlib run the following commands to generate the libhamlib-4.lib file needed for linking with your MSVC project: cd lib\msvc c:\Program Files\Microsoft Visual C++ Toolkit 2003\bin\link.exe /lib /machine:amd64 /def:libhamlib-4.def To do the same for Visual Studio 2017: cd lib\msvc c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x86\bin\link.exe /lib /machine:i386 /def:libhamlib-4.def and for VS 2019: cd lib\msvc c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x86\bin\link.exe /lib /machine:i386 /def:libhamlib-4.def NOTE: feedback is requested on the previous two command examples as these do not appear to be correct to generate a 64 bit libhamlib-4.lib file! For VS 2022: cd lib/msvc c:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.32.31326\bin\Hostx64\x86\lib.exe /lib /machine:i386 /def:libhamlib-4.def The published Hamlib API may be found at: http://hamlib.sourceforge.net/manuals/4.1/index.html Thank You! ========== Patches, feedback, and contributions are welcome. Please report problems or success to hamlib-developer@lists.sourceforge.net Cheers, Stephane Fillod - F8CFE Mike Black - W9MDB Nate Bargmann - N0NB http://www.hamlib.org END_OF_README # Configure and build hamlib for x86_64-w64-mingw32, with libusb-1.0 ./configure --host=${HOST_ARCH} \ --prefix=${INST_DIR} \ --without-cxx-binding \ --disable-static \ CPPFLAGS="-I${LIBUSB_1_0_BIN_PATH}/include" \ LDFLAGS="-L${LIBUSB_1_0_BIN_PATH}/MinGW64/dll" make -j 4 install mkdir -p ${ZIP_DIR}/bin ${ZIP_DIR}/lib/msvc ${ZIP_DIR}/lib/gcc ${ZIP_DIR}/include ${ZIP_DIR}/doc cp -a src/libhamlib.def ${ZIP_DIR}/lib/msvc/libhamlib-4.def todos ${ZIP_DIR}/lib/msvc/libhamlib-4.def cp -a ${INST_DIR}/include/hamlib ${ZIP_DIR}/include/. todos ${ZIP_DIR}/include/hamlib/*.h # C++ binding is useless on w64 because of ABI for f in *class.h do rm ${ZIP_DIR}/include/hamlib/${f} done for f in AUTHORS ChangeLog COPYING COPYING.LIB LICENSE README.md README.betatester README.w64-bin THANKS do cp -a ${f} ${ZIP_DIR}/${f}.txt todos ${ZIP_DIR}/${f}.txt done # Generate HTML documents from nroff formatted man files for f in doc/man1/*.1 doc/man7/*.7 do /usr/bin/groff -mandoc -Thtml >${f}.html ${f} cp -a ${f}.html ${ZIP_DIR}/doc/. done cd ${BUILD_DIR}/$1 # Copy build files into specific locations for Zip file for f in *.exe do cp -a ${INST_DIR}/bin/${f} ${ZIP_DIR}/bin/. done cp -a ${INST_DIR}/bin/libhamlib-?.dll ${ZIP_DIR}/bin/. cp -a ${INST_DIR}/lib/libhamlib.dll.a ${ZIP_DIR}/lib/gcc/. # NB: Strip Hamlib DLLs and EXEs ${HOST_ARCH_STRIP} ${ZIP_DIR}/bin/*.exe ${ZIP_DIR}/bin/*hamlib-*.dll # Copy needed third party DLLs cp -a /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll ${ZIP_DIR}/bin/. cp -a ${LIBUSB_1_0_BIN_PATH}/MinGW64/dll/libusb-1.0.dll ${ZIP_DIR}/bin/libusb-1.0.dll # Required for MinGW with GCC 6.3 (Debian 9) FILE="/usr/lib/gcc/i686-w64-mingw32/6.3-posix/libgcc_s_sjlj-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 8.3 (Debian 10) FILE="/usr/lib/gcc/i686-w64-mingw32/8.3-posix/libgcc_s_sjlj-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 10 (Debian 11) FILE="/usr/lib/gcc/i686-w64-mingw32/10-posix/libgcc_s_dw2-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Required for MinGW with GCC 12 (Debian 12) FILE="/usr/lib/gcc/i686-w64-mingw32/12-posix/libgcc_s_dw2-1.dll" if test -f "$FILE" then cp -a ${FILE} ${ZIP_DIR}/bin/. fi # Generate .lib file for MSVC ${HOST_ARCH_DLLTOOL} --input-def ${ZIP_DIR}/lib/msvc/libhamlib-4.def --output-lib ${ZIP_DIR}/lib/msvc/libhamlib-4.lib /usr/bin/zip -r ${HL_FILENAME}.zip $(basename ${ZIP_DIR}) hamlib-4.6.2/scripts/README.scripts0000644000175000017500000000077114752216205013746 00000000000000The scripts/ directory will contain helper scripts for building Hamlib binary releases for Microsoft Windows 32 and 64 bit architectures and possibly other target platforms. Each script should be accompanied by a companion README file with information on the script and build requirements. Scripts: build-w32.sh and build-w64.sh for building Microsoft Windows 32 and 64 bit DLLs and EXEs for use with MS VC++. build-VB.NET.sh for building Win32 DLLs and EXEs for use with MS VB.NET 2002 Framework 1.1 hamlib-4.6.2/build-aux/0000755000175000017500000000000014752216241011656 500000000000000hamlib-4.6.2/build-aux/ar-lib0000755000175000017500000001336314752216215012701 00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2019-07-04.01; # UTC # Copyright (C) 2010-2020 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin | msys) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.2/build-aux/config.guess0000755000175000017500000012637314752216215014133 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval "$set_cc_for_build" cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" # If ldd exists, use it to detect musl libc. if command -v ldd >/dev/null && \ ldd --version 2>&1 | grep -q ^musl then LIBC=musl fi ;; esac # Note: order is significant - the case branches are not exclusive. case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ [ "$TARGET_BINARY_INTERFACE"x = x ] then echo m88k-dg-dgux"$UNAME_RELEASE" else echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "$HP_ARCH" = "" ]; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ "$HP_ARCH" = hppa2.0w ] then eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) case "$UNAME_MACHINE" in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) if objdump -f /bin/sh | grep -q elf32-x86-64; then echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 else echo "$UNAME_MACHINE"-pc-linux-"$LIBC" fi exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; NSV-*:NONSTOP_KERNEL:*:*) echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: hamlib-4.6.2/build-aux/missing0000755000175000017500000001533614752216215013206 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2020 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.2/build-aux/install-sh0000755000175000017500000003577614752216215013625 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.2/build-aux/depcomp0000755000175000017500000005602014752216215013157 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2020 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.2/build-aux/test-driver0000755000175000017500000001112714752216215013777 00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2020 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <$log_file 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>$log_file # Report outcome to console. echo "${col}${res}${std}: $test_name" # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.2/build-aux/config.sub0000755000175000017500000010645014752216215013570 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo "$1" | sed 's/-[^-]*$//'` if [ "$basic_machine" != "$1" ] then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2*) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; nsv-tandem) basic_machine=nsv-tandem ;; nsx-tandem) basic_machine=nsx-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh5el) basic_machine=sh5le-unknown ;; simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; x64) basic_machine=x86_64-pc ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases that might get confused # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # es1800 is here to avoid being matched by es* (a different OS) -es1800*) os=-ose ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -xray | -os68k* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4*) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -pikeos*) # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. case $basic_machine in arm*) os=-eabi ;; *) os=-elf ;; esac ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; pru-*) os=-elf ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac echo "$basic_machine$os" exit # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: hamlib-4.6.2/build-aux/py-compile0000755000175000017500000001216414752216215013607 00000000000000#!/bin/sh # py-compile - Compile a Python program scriptversion=2020-02-19.23; # UTC # Copyright (C) 2000-2020 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . if [ -z "$PYTHON" ]; then PYTHON=python fi me=py-compile usage_error () { echo "$me: $*" >&2 echo "Try '$me --help' for more information." >&2 exit 1 } basedir= destdir= while test $# -ne 0; do case "$1" in --basedir) if test $# -lt 2; then usage_error "option '--basedir' requires an argument" else basedir=$2 fi shift ;; --destdir) if test $# -lt 2; then usage_error "option '--destdir' requires an argument" else destdir=$2 fi shift ;; -h|--help) cat <<\EOF Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..." Byte compile some python scripts FILES. Use --destdir to specify any leading directory path to the FILES that you don't want to include in the byte compiled file. Specify --basedir for any additional path information you do want to be shown in the byte compiled file. Example: py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py Report bugs to . EOF exit $? ;; -v|--version) echo "$me $scriptversion" exit $? ;; --) shift break ;; -*) usage_error "unrecognized option '$1'" ;; *) break ;; esac shift done files=$* if test -z "$files"; then usage_error "no files given" fi # if basedir was given, then it should be prepended to filenames before # byte compilation. if [ -z "$basedir" ]; then pathtrans="path = file" else pathtrans="path = os.path.join('$basedir', file)" fi # if destdir was given, then it needs to be prepended to the filename to # byte compile but not go into the compiled file. if [ -z "$destdir" ]; then filetrans="filepath = path" else filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)" fi python_major=$($PYTHON -V 2>&1 | sed -e 's/.* //;s/\..*$//;1q') if test -z "$python_major"; then echo "$me: could not determine $PYTHON major version, guessing 3" >&2 python_major=3 fi # The old way to import libraries was deprecated. if test "$python_major" -le 2; then import_lib=imp import_test="hasattr(imp, 'get_tag')" import_call=imp.cache_from_source import_arg2=', False' # needed in one call and not the other else import_lib=importlib import_test="hasattr(sys.implementation, 'cache_tag')" import_call=importlib.util.cache_from_source import_arg2= fi $PYTHON -c " import sys, os, py_compile, $import_lib files = '''$files''' sys.stdout.write('Byte-compiling python modules...\n') for file in files.split(): $pathtrans $filetrans if not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py'): continue sys.stdout.write(file) sys.stdout.flush() if $import_test: py_compile.compile(filepath, $import_call(filepath), path) else: py_compile.compile(filepath, filepath + 'c', path) sys.stdout.write('\n')" || exit $? # this will fail for python < 1.5, but that doesn't matter ... $PYTHON -O -c " import sys, os, py_compile, $import_lib # pypy does not use .pyo optimization if hasattr(sys, 'pypy_translation_info'): sys.exit(0) files = '''$files''' sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n') for file in files.split(): $pathtrans $filetrans if not os.path.exists(filepath) or not (len(filepath) >= 3 and filepath[-3:] == '.py'): continue sys.stdout.write(file) sys.stdout.flush() if $import_test: py_compile.compile(filepath, $import_call(filepath$import_arg2), path) else: py_compile.compile(filepath, filepath + 'o', path) sys.stdout.write('\n')" 2>/dev/null || : # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: hamlib-4.6.2/build-aux/ltmain.sh0000755000175000017500000117716714752216212013443 00000000000000#! /bin/sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2014-01-03.01 # libtool (GNU libtool) 2.4.6 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.6 Debian-2.4.6-15" package_revision=2.4.6 ## ------ ## ## Usage. ## ## ------ ## # Run './libtool --help' for help with using this script from the # command line. ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # After configure completes, it has a better idea of some of the # shell tools we need than the defaults used by the functions shared # with bootstrap, so set those here where they can still be over- # ridden by the user, but otherwise take precedence. : ${AUTOCONF="autoconf"} : ${AUTOMAKE="automake"} ## -------------------------- ## ## Source external libraries. ## ## -------------------------- ## # Much of our low-level functionality needs to be sourced from external # libraries, which are installed to $pkgauxdir. # Set a version string for this script. scriptversion=2015-01-20.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 # Copyright (C) 2004-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # As a special exception to the GNU General Public License, if you distribute # this file as part of a program or library that is built using GNU Libtool, # you may include this file under the same distribution terms that you use # for the rest of that program. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # Evaluate this file near the top of your script to gain access to # the functions and variables defined here: # # . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh # # If you need to override any of the default environment variable # settings, do that before evaluating this file. ## -------------------- ## ## Shell normalisation. ## ## -------------------- ## # Some shells need a little help to be as Bourne compatible as possible. # Before doing anything else, make sure all that help has been provided! DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # NLS nuisances: We save the old values in case they are required later. _G_user_locale= _G_safe_locale= for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test set = \"\${$_G_var+set}\"; then save_$_G_var=\$$_G_var $_G_var=C export $_G_var _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Make sure IFS has a sensible default sp=' ' nl=' ' IFS="$sp $nl" # There are apparently some retarded systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi ## ------------------------- ## ## Locate command utilities. ## ## ------------------------- ## # func_executable_p FILE # ---------------------- # Check that FILE is an executable regular file. func_executable_p () { test -f "$1" && test -x "$1" } # func_path_progs PROGS_LIST CHECK_FUNC [PATH] # -------------------------------------------- # Search for either a program that responds to --version with output # containing "GNU", or else returned by CHECK_FUNC otherwise, by # trying all the directories in PATH with each of the elements of # PROGS_LIST. # # CHECK_FUNC should accept the path to a candidate program, and # set $func_check_prog_result if it truncates its output less than # $_G_path_prog_max characters. func_path_progs () { _G_progs_list=$1 _G_check_func=$2 _G_PATH=${3-"$PATH"} _G_path_prog_max=0 _G_path_prog_found=false _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} for _G_dir in $_G_PATH; do IFS=$_G_save_IFS test -z "$_G_dir" && _G_dir=. for _G_prog_name in $_G_progs_list; do for _exeext in '' .EXE; do _G_path_prog=$_G_dir/$_G_prog_name$_exeext func_executable_p "$_G_path_prog" || continue case `"$_G_path_prog" --version 2>&1` in *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; *) $_G_check_func $_G_path_prog func_path_progs_result=$func_check_prog_result ;; esac $_G_path_prog_found && break 3 done done done IFS=$_G_save_IFS test -z "$func_path_progs_result" && { echo "no acceptable sed could be found in \$PATH" >&2 exit 1 } } # We want to be able to use the functions in this file before configure # has figured out where the best binaries are kept, which means we have # to search for them ourselves - except when the results are already set # where we skip the searches. # Unless the user overrides by setting SED, search the path for either GNU # sed, or the sed that truncates its output the least. test -z "$SED" && { _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for _G_i in 1 2 3 4 5 6 7; do _G_sed_script=$_G_sed_script$nl$_G_sed_script done echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed _G_sed_script= func_check_prog_sed () { _G_path_prog=$1 _G_count=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo '' >> conftest.nl "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin rm -f conftest.sed SED=$func_path_progs_result } # Unless the user overrides by setting GREP, search the path for either GNU # grep, or the grep that truncates its output the least. test -z "$GREP" && { func_check_prog_grep () { _G_path_prog=$1 _G_count=0 _G_path_prog_max=0 printf 0123456789 >conftest.in while : do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo 'GREP' >> conftest.nl "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break diff conftest.out conftest.nl >/dev/null 2>&1 || break _G_count=`expr $_G_count + 1` if test "$_G_count" -gt "$_G_path_prog_max"; then # Best one so far, save it but keep looking for a better one func_check_prog_result=$_G_path_prog _G_path_prog_max=$_G_count fi # 10*(2^10) chars as input seems more than enough test 10 -lt "$_G_count" && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out } func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin GREP=$func_path_progs_result } ## ------------------------------- ## ## User overridable command paths. ## ## ------------------------------- ## # All uppercase variable names are used for environment variables. These # variables can be overridden by the user before calling a script that # uses them if a suitable command of that name is not already available # in the command search PATH. : ${CP="cp -f"} : ${ECHO="printf %s\n"} : ${EGREP="$GREP -E"} : ${FGREP="$GREP -F"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} ## -------------------- ## ## Useful sed snippets. ## ## -------------------- ## sed_dirname='s|/[^/]*$||' sed_basename='s|^.*/||' # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s|\([`"$\\]\)|\\\1|g' # Same as above, but do not quote variable references. sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' # Sed substitution that converts a w32 file name or path # that contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-'\' parameter expansions in output of sed_double_quote_subst that # were '\'-ed in input to the same. If an odd number of '\' preceded a # '$' in input to sed_double_quote_subst, that '$' was protected from # expansion. Since each input '\' is now two '\'s, look for any number # of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. _G_bs='\\' _G_bs2='\\\\' _G_bs4='\\\\\\\\' _G_dollar='\$' sed_double_backslash="\ s/$_G_bs4/&\\ /g s/^$_G_bs2$_G_dollar/$_G_bs&/ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" ## ----------------- ## ## Global variables. ## ## ----------------- ## # Except for the global variables explicitly listed below, the following # functions in the '^func_' namespace, and the '^require_' namespace # variables initialised in the 'Resource management' section, sourcing # this file will not pollute your global namespace with anything # else. There's no portable way to scope variables in Bourne shell # though, so actually running these functions will sometimes place # results into a variable named after the function, and often use # temporary variables in the '^_G_' namespace. If you are careful to # avoid using those namespaces casually in your sourcing script, things # should continue to work as you expect. And, of course, you can freely # overwrite any of the functions or variables defined here before # calling anything to customize them. EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # Allow overriding, eg assuming that you follow the convention of # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # # debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: # By convention, finish your script with: # # exit $exit_status # # so that you can set exit_status to non-zero if you want to indicate # something went wrong during execution without actually bailing out at # the point of failure. exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath=$0 # The name of this program. progname=`$ECHO "$progpath" |$SED "$sed_basename"` # Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` progpath=$progdir/$progname ;; *) _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS=$_G_IFS test -x "$progdir/$progname" && break done IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` progpath=$progdir/$progname ;; esac ## ----------------- ## ## Standard options. ## ## ----------------- ## # The following options affect the operation of the functions defined # below, and should be set appropriately depending on run-time para- # meters passed on the command line. opt_dry_run=false opt_quiet=false opt_verbose=false # Categories 'all' and 'none' are always available. Append any others # you will pass as the first argument to func_warning from your own # code. warning_categories= # By default, display warnings according to 'opt_warning_types'. Set # 'warning_func' to ':' to elide all warnings, or func_fatal_error to # treat the next displayed warning as a fatal error. warning_func=func_warn_and_continue # Set to 'all' to display all warnings, 'none' to suppress all # warnings, or a space delimited list of some subset of # 'warning_categories' to display only the listed warnings. opt_warning_types=all ## -------------------- ## ## Resource management. ## ## -------------------- ## # This section contains definitions for functions that each ensure a # particular resource (a file, or a non-empty configuration variable for # example) is available, and if appropriate to extract default values # from pertinent package files. Call them using their associated # 'require_*' variable to ensure that they are executed, at most, once. # # It's entirely deliberate that calling these functions can set # variables that don't obey the namespace limitations obeyed by the rest # of this file, in order that that they be as useful as possible to # callers. # require_term_colors # ------------------- # Allow display of bold text on terminals that support it. require_term_colors=func_require_term_colors func_require_term_colors () { $debug_cmd test -t 1 && { # COLORTERM and USE_ANSI_COLORS environment variables take # precedence, because most terminfo databases neglect to describe # whether color sequences are supported. test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} if test 1 = "$USE_ANSI_COLORS"; then # Standard ANSI escape sequences tc_reset='' tc_bold=''; tc_standout='' tc_red=''; tc_green='' tc_blue=''; tc_cyan='' else # Otherwise trust the terminfo database after all. test -n "`tput sgr0 2>/dev/null`" && { tc_reset=`tput sgr0` test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` tc_standout=$tc_bold test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` } fi } require_term_colors=: } ## ----------------- ## ## Function library. ## ## ----------------- ## # This section contains a variety of useful functions to call in your # scripts. Take note of the portable wrappers for features provided by # some modern shells, which will fall back to slower equivalents on # less featureful shells. # func_append VAR VALUE # --------------------- # Append VALUE onto the existing contents of VAR. # We should try to minimise forks, especially on Windows where they are # unreasonably slow, so skip the feature probes when bash or zsh are # being used: if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then : ${_G_HAVE_ARITH_OP="yes"} : ${_G_HAVE_XSI_OPS="yes"} # The += operator was introduced in bash 3.1 case $BASH_VERSION in [12].* | 3.0 | 3.0*) ;; *) : ${_G_HAVE_PLUSEQ_OP="yes"} ;; esac fi # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is # useable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes if test yes = "$_G_HAVE_PLUSEQ_OP" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_append () { $debug_cmd eval "$1+=\$2" }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_append () { $debug_cmd eval "$1=\$$1\$2" } fi # func_append_quoted VAR VALUE # ---------------------------- # Quote VALUE and append to the end of shell variable VAR, separated # by a space. if test yes = "$_G_HAVE_PLUSEQ_OP"; then eval 'func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1+=\\ \$func_quote_for_eval_result" }' else func_append_quoted () { $debug_cmd func_quote_for_eval "$2" eval "$1=\$$1\\ \$func_quote_for_eval_result" } fi # func_append_uniq VAR VALUE # -------------------------- # Append unique VALUE onto the existing contents of VAR, assuming # entries are delimited by the first character of VALUE. For example: # # func_append_uniq options " --another-option option-argument" # # will only append to $options if " --another-option option-argument " # is not already present somewhere in $options already (note spaces at # each end implied by leading space in second argument). func_append_uniq () { $debug_cmd eval _G_current_value='`$ECHO $'$1'`' _G_delim=`expr "$2" : '\(.\)'` case $_G_delim$_G_current_value$_G_delim in *"$2$_G_delim"*) ;; *) func_append "$@" ;; esac } # func_arith TERM... # ------------------ # Set func_arith_result to the result of evaluating TERMs. test -z "$_G_HAVE_ARITH_OP" \ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ && _G_HAVE_ARITH_OP=yes if test yes = "$_G_HAVE_ARITH_OP"; then eval 'func_arith () { $debug_cmd func_arith_result=$(( $* )) }' else func_arith () { $debug_cmd func_arith_result=`expr "$@"` } fi # func_basename FILE # ------------------ # Set func_basename_result to FILE with everything up to and including # the last / stripped. if test yes = "$_G_HAVE_XSI_OPS"; then # If this shell supports suffix pattern removal, then use it to avoid # forking. Hide the definitions single quotes in case the shell chokes # on unsupported syntax... _b='func_basename_result=${1##*/}' _d='case $1 in */*) func_dirname_result=${1%/*}$2 ;; * ) func_dirname_result=$3 ;; esac' else # ...otherwise fall back to using sed. _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` if test "X$func_dirname_result" = "X$1"; then func_dirname_result=$3 else func_append func_dirname_result "$2" fi' fi eval 'func_basename () { $debug_cmd '"$_b"' }' # func_dirname FILE APPEND NONDIR_REPLACEMENT # ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. eval 'func_dirname () { $debug_cmd '"$_d"' }' # func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT # -------------------------------------------------------- # Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () { $debug_cmd '"$_b"' '"$_d"' }' # func_echo ARG... # ---------------- # Echo program name prefixed message. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname: $_G_line" done IFS=$func_echo_IFS } # func_echo_all ARG... # -------------------- # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_echo_infix_1 INFIX ARG... # ------------------------------ # Echo program name, followed by INFIX on the first line, with any # additional lines not showing INFIX. func_echo_infix_1 () { $debug_cmd $require_term_colors _G_infix=$1; shift _G_indent=$_G_infix _G_prefix="$progname: $_G_infix: " _G_message=$* # Strip color escape sequences before counting printable length for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" do test -n "$_G_tc" && { _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` } done _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes func_echo_infix_1_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_infix_1_IFS $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 _G_prefix=$_G_indent done IFS=$func_echo_infix_1_IFS } # func_error ARG... # ----------------- # Echo program name prefixed message to standard error. func_error () { $debug_cmd $require_term_colors func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 } # func_fatal_error ARG... # ----------------------- # Echo program name prefixed message to standard error, and exit. func_fatal_error () { $debug_cmd func_error "$*" exit $EXIT_FAILURE } # func_grep EXPRESSION FILENAME # ----------------------------- # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $debug_cmd $GREP "$1" "$2" >/dev/null 2>&1 } # func_len STRING # --------------- # Set func_len_result to the length of STRING. STRING may not # start with a hyphen. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_len () { $debug_cmd func_len_result=${#1} }' else func_len () { $debug_cmd func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } fi # func_mkdir_p DIRECTORY-PATH # --------------------------- # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { $debug_cmd _G_directory_path=$1 _G_dir_list= if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then # Protect directory names starting with '-' case $_G_directory_path in -*) _G_directory_path=./$_G_directory_path ;; esac # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done case $_G_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` done _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` func_mkdir_p_IFS=$IFS; IFS=: for _G_dir in $_G_dir_list; do IFS=$func_mkdir_p_IFS # mkdir can fail with a 'File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$_G_dir" 2>/dev/null || : done IFS=$func_mkdir_p_IFS # Bail out if we (or some other process) failed to create a directory. test -d "$_G_directory_path" || \ func_fatal_error "Failed to create '$1'" fi } # func_mktempdir [BASENAME] # ------------------------- # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, BASENAME is the basename for that directory. func_mktempdir () { $debug_cmd _G_template=${TMPDIR-/tmp}/${1-$progname} if test : = "$opt_dry_run"; then # Return a directory name, but don't create it in dry-run mode _G_tmpdir=$_G_template-$$ else # If mktemp works, use that first and foremost _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` if test ! -d "$_G_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race _G_tmpdir=$_G_template-${RANDOM-0}$$ func_mktempdir_umask=`umask` umask 0077 $MKDIR "$_G_tmpdir" umask $func_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$_G_tmpdir" || \ func_fatal_error "cannot create temporary directory '$_G_tmpdir'" fi $ECHO "$_G_tmpdir" } # func_normal_abspath PATH # ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. func_normal_abspath () { $debug_cmd # These SED scripts presuppose an absolute path with a trailing slash. _G_pathcar='s|^/\([^/]*\).*$|\1|' _G_pathcdr='s|^/[^/]*||' _G_removedotparts=':dotsl s|/\./|/|g t dotsl s|/\.$|/|' _G_collapseslashes='s|/\{1,\}|/|g' _G_finalslash='s|/*$|/|' # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` while :; do # Processed it all yet? if test / = "$func_normal_abspath_tpath"; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result"; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$_G_pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_notquiet ARG... # -------------------- # Echo program name prefixed message only when not in quiet mode. func_notquiet () { $debug_cmd $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_relative_path SRCDIR DSTDIR # -------------------------------- # Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. func_relative_path () { $debug_cmd func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=$func_dirname_result if test -z "$func_relative_path_tlibdir"; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test -n "$func_stripname_result"; then func_append func_relative_path_result "/$func_stripname_result" fi # Normalisation. If bindir is libdir, return '.' else relative path. if test -n "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result" func_relative_path_result=$func_stripname_result fi test -n "$func_relative_path_result" || func_relative_path_result=. : } # func_quote_for_eval ARG... # -------------------------- # Aesthetically quote ARGs to be evaled later. # This function returns two values: # i) func_quote_for_eval_result # double-quoted, suitable for a subsequent eval # ii) func_quote_for_eval_unquoted_result # has all characters that are still active within double # quotes backslashified. func_quote_for_eval () { $debug_cmd func_quote_for_eval_unquoted_result= func_quote_for_eval_result= while test 0 -lt $#; do case $1 in *[\\\`\"\$]*) _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; *) _G_unquoted_arg=$1 ;; esac if test -n "$func_quote_for_eval_unquoted_result"; then func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" else func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" fi case $_G_unquoted_arg in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and variable expansion # for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_quoted_arg=\"$_G_unquoted_arg\" ;; *) _G_quoted_arg=$_G_unquoted_arg ;; esac if test -n "$func_quote_for_eval_result"; then func_append func_quote_for_eval_result " $_G_quoted_arg" else func_append func_quote_for_eval_result "$_G_quoted_arg" fi shift done } # func_quote_for_expand ARG # ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { $debug_cmd case $1 in *[\\\`\"]*) _G_arg=`$ECHO "$1" | $SED \ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) _G_arg=$1 ;; esac case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") _G_arg=\"$_G_arg\" ;; esac func_quote_for_expand_result=$_G_arg } # func_stripname PREFIX SUFFIX NAME # --------------------------------- # strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_stripname () { $debug_cmd # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary variable first. func_stripname_result=$3 func_stripname_result=${func_stripname_result#"$1"} func_stripname_result=${func_stripname_result%"$2"} }' else func_stripname () { $debug_cmd case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; esac } fi # func_show_eval CMD [FAIL_EXP] # ----------------------------- # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} func_quote_for_expand "$_G_cmd" eval "func_notquiet $func_quote_for_expand_result" $opt_dry_run || { eval "$_G_cmd" _G_status=$? if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_show_eval_locale CMD [FAIL_EXP] # ------------------------------------ # Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { $debug_cmd _G_cmd=$1 _G_fail_exp=${2-':'} $opt_quiet || { func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || { eval "$_G_user_locale $_G_cmd" _G_status=$? eval "$_G_safe_locale" if test 0 -ne "$_G_status"; then eval "(exit $_G_status); $_G_fail_exp" fi } } # func_tr_sh # ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { $debug_cmd case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_verbose ARG... # ------------------- # Echo program name prefixed message in verbose mode only. func_verbose () { $debug_cmd $opt_verbose && func_echo "$*" : } # func_warn_and_continue ARG... # ----------------------------- # Echo program name prefixed warning message to standard error. func_warn_and_continue () { $debug_cmd $require_term_colors func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } # func_warning CATEGORY ARG... # ---------------------------- # Echo program name prefixed warning message to standard error. Warning # messages can be filtered according to CATEGORY, where this function # elides messages where CATEGORY is not listed in the global variable # 'opt_warning_types'. func_warning () { $debug_cmd # CATEGORY must be in the warning_categories list! case " $warning_categories " in *" $1 "*) ;; *) func_internal_error "invalid warning category '$1'" ;; esac _G_category=$1 shift case " $opt_warning_types " in *" $_G_category "*) $warning_func ${1+"$@"} ;; esac } # func_sort_ver VER1 VER2 # ----------------------- # 'sort -V' is not generally available. # Note this deviates from the version comparison in automake # in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a # but this should suffice as we won't be specifying old # version formats or redundant trailing .0 in bootstrap.conf. # If we did want full compatibility then we should probably # use m4_version_compare from autoconf. func_sort_ver () { $debug_cmd printf '%s\n%s\n' "$1" "$2" \ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n } # func_lt_ver PREV CURR # --------------------- # Return true if PREV and CURR are in the correct order according to # func_sort_ver, otherwise false. Use it like this: # # func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." func_lt_ver () { $debug_cmd test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: #! /bin/sh # Set a version string for this script. scriptversion=2015-10-07.11; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 # Copyright (C) 2010-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Please report bugs or propose patches to gary@gnu.org. ## ------ ## ## Usage. ## ## ------ ## # This file is a library for parsing options in your shell scripts along # with assorted other useful supporting features that you can make use # of too. # # For the simplest scripts you might need only: # # #!/bin/sh # . relative/path/to/funclib.sh # . relative/path/to/options-parser # scriptversion=1.0 # func_options ${1+"$@"} # eval set dummy "$func_options_result"; shift # ...rest of your script... # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file # starting with '# Written by ' and ending with '# warranty; '. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the # '# Written by ' line, like the one at the top of this file. # # The default options also support '--debug', which will turn on shell # execution tracing (see the comment above debug_cmd below for another # use), and '--verbose' and the func_verbose function to allow your script # to display verbose messages only when your user has specified # '--verbose'. # # After sourcing this file, you can plug processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. ## -------------- ## ## Configuration. ## ## -------------- ## # You should override these variables in your script after sourcing this # file so that they reflect the customisations you have added to the # option parser. # The usage line for option parsing errors and the start of '-h' and # '--help' output messages. You can embed shell variables for delayed # expansion at the time the message is displayed, but you will need to # quote other shell meta-characters carefully to prevent them being # expanded when the contents are evaled. usage='$progpath [OPTION]...' # Short help message in response to '-h' and '--help'. Add to this or # override it after sourcing this library to reflect the full set of # options your script accepts. usage_message="\ --debug enable verbose shell tracing -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -v, --verbose verbosely report processing --version print version information and exit -h, --help print short or long help message and exit " # Additional text appended to 'usage_message' in response to '--help'. long_help_message=" Warning categories include: 'all' show all warnings 'none' turn off all the warnings 'error' warnings are treated as fatal errors" # Help message printed before fatal option parsing errors. fatal_help="Try '\$progname --help' for more information." ## ------------------------- ## ## Hook function management. ## ## ------------------------- ## # This section contains functions for adding, removing, and running hooks # to the main code. A hook is just a named list of of function, that can # be run in order later on. # func_hookable FUNC_NAME # ----------------------- # Declare that FUNC_NAME will run hooks added with # 'func_add_hook FUNC_NAME ...'. func_hookable () { $debug_cmd func_append hookable_fns " $1" } # func_add_hook FUNC_NAME HOOK_FUNC # --------------------------------- # Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must # first have been declared "hookable" by a call to 'func_hookable'. func_add_hook () { $debug_cmd case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not accept hook functions." ;; esac eval func_append ${1}_hooks '" $2"' } # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ # Remove HOOK_FUNC from the list of functions called by FUNC_NAME. func_remove_hook () { $debug_cmd eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' } # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. # It is assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. func_run_hooks () { $debug_cmd _G_rc_run_hooks=false case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do if eval $_G_hook '"$@"'; then # store returned options list back into positional # parameters for next 'cmd' execution. eval _G_hook_result=\$${_G_hook}_result eval set dummy "$_G_hook_result"; shift _G_rc_run_hooks=: fi done $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result } ## --------------- ## ## Option parsing. ## ## --------------- ## # In order to add your own option parsing hooks, you must accept the # full positional parameter list in your hook function, you may remove/edit # any options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for # 'eval'. In this case you also must return $EXIT_SUCCESS to let the # hook's caller know that it should pay attention to # '_result'. Returning $EXIT_FAILURE signalizes that # arguments are left untouched by the hook and therefore caller will ignore the # result variable. # # Like this: # # my_options_prep () # { # $debug_cmd # # # Extend the existing usage message. # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' # # No change in '$@' (ignored completely by this hook). There is # # no need to do the equivalent (but slower) action: # # func_quote_for_eval ${1+"$@"} # # my_options_prep_result=$func_quote_for_eval_result # false # } # func_add_hook func_options_prep my_options_prep # # # my_silent_option () # { # $debug_cmd # # args_changed=false # # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in # --silent|-s) opt_silent=: # args_changed=: # ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift # args_changed=: # ;; # *) # Make sure the first unrecognised option "$_G_opt" # # is added back to "$@", we could need that later # # if $args_changed is true. # set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # # if $args_changed; then # func_quote_for_eval ${1+"$@"} # my_silent_option_result=$func_quote_for_eval_result # fi # # $args_changed # } # func_add_hook func_parse_options my_silent_option # # # my_option_validation () # { # $debug_cmd # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # # false # } # func_add_hook func_validate_options my_option_validation # # You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. # func_options_finish [ARG]... # ---------------------------- # Finishing the option parse loop (call 'func_options' hooks ATM). func_options_finish () { $debug_cmd _G_func_options_finish_exit=false if func_run_hooks func_options ${1+"$@"}; then func_options_finish_result=$func_run_hooks_result _G_func_options_finish_exit=: fi $_G_func_options_finish_exit } # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the # individual implementations for details. func_hookable func_options func_options () { $debug_cmd _G_rc_options=false for my_func in options_prep parse_options validate_options options_finish do if eval func_$my_func '${1+"$@"}'; then eval _G_res_var='$'"func_${my_func}_result" eval set dummy "$_G_res_var" ; shift _G_rc_options=: fi done # Save modified positional parameters for caller. As a top-level # options-parser function we always need to set the 'func_options_result' # variable (regardless the $_G_rc_options value). if $_G_rc_options; then func_options_result=$_G_res_var else func_quote_for_eval ${1+"$@"} func_options_result=$func_quote_for_eval_result fi $_G_rc_options } # func_options_prep [ARG]... # -------------------------- # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and # needs to propagate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before # returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). func_hookable func_options_prep func_options_prep () { $debug_cmd # Option defaults: opt_verbose=false opt_warning_types= _G_rc_options_prep=false if func_run_hooks func_options_prep ${1+"$@"}; then _G_rc_options_prep=: # save modified positional parameters for caller func_options_prep_result=$func_run_hooks_result fi $_G_rc_options_prep } # func_parse_options [ARG]... # --------------------------- # The main option parsing loop. func_hookable func_parse_options func_parse_options () { $debug_cmd func_parse_options_result= _G_rc_parse_options=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. if func_run_hooks func_parse_options ${1+"$@"}; then eval set dummy "$func_run_hooks_result"; shift _G_rc_parse_options=: fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' func_echo "enabling shell trace mode" $debug_cmd ;; --no-warnings|--no-warning|--no-warn) set dummy --warnings none ${1+"$@"} shift ;; --warnings|--warning|-W) if test $# = 0 && func_missing_arg $_G_opt; then _G_rc_parse_options=: break fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above func_append_uniq opt_warning_types " $1" ;; *all) opt_warning_types=$warning_categories ;; *none) opt_warning_types=none warning_func=: ;; *error) opt_warning_types=$warning_categories warning_func=func_fatal_error ;; *) func_fatal_error \ "unsupported warning category: '$1'" ;; esac shift ;; --verbose|-v) opt_verbose=: ;; --version) func_version ;; -\?|-h) func_usage ;; --help) func_help ;; # Separate optargs to long options (plugins may need this): --*=*) func_split_equals "$_G_opt" set dummy "$func_split_equals_lhs" \ "$func_split_equals_rhs" ${1+"$@"} shift ;; # Separate optargs to short options: -W*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "$func_split_short_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-v*|-x*) func_split_short_opt "$_G_opt" set dummy "$func_split_short_opt_name" \ "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) _G_rc_parse_options=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; *) set dummy "$_G_opt" ${1+"$@"}; shift _G_match_parse_options=false break ;; esac $_G_match_parse_options && _G_rc_parse_options=: done if $_G_rc_parse_options; then # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} func_parse_options_result=$func_quote_for_eval_result fi $_G_rc_parse_options } # func_validate_options [ARG]... # ------------------------------ # Perform any sanity checks on option settings and/or unconsumed # arguments. func_hookable func_validate_options func_validate_options () { $debug_cmd _G_rc_validate_options=false # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" if func_run_hooks func_validate_options ${1+"$@"}; then # save modified positional parameters for caller func_validate_options_result=$func_run_hooks_result _G_rc_validate_options=: fi # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE $_G_rc_validate_options } ## ----------------- ## ## Helper functions. ## ## ----------------- ## # This section contains the helper functions used by the rest of the # hookable option parser framework in ascii-betical order. # func_fatal_help ARG... # ---------------------- # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { $debug_cmd eval \$ECHO \""Usage: $usage"\" eval \$ECHO \""$fatal_help"\" func_error ${1+"$@"} exit $EXIT_FAILURE } # func_help # --------- # Echo long help message to standard output and exit. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message" exit 0 } # func_missing_arg ARGNAME # ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $debug_cmd func_error "Missing argument for '$1'." exit_cmd=exit } # func_split_equals STRING # ------------------------ # Set func_split_equals_lhs and func_split_equals_rhs shell variables after # splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ && _G_HAVE_XSI_OPS=yes if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_equals () { $debug_cmd func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} test "x$func_split_equals_lhs" = "x$1" \ && func_split_equals_rhs= }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_equals () { $debug_cmd func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= test "x$func_split_equals_lhs" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals # func_split_short_opt SHORTOPT # ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. if test yes = "$_G_HAVE_XSI_OPS" then # This is an XSI compatible shell, allowing a faster implementation... eval 'func_split_short_opt () { $debug_cmd func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"} }' else # ...otherwise fall back to using expr, which is often a shell builtin. func_split_short_opt () { $debug_cmd func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt # func_usage # ---------- # Echo short help message to standard output and exit. func_usage () { $debug_cmd func_usage_message $ECHO "Run '$progname --help |${PAGER-more}' for full usage" exit 0 } # func_usage_message # ------------------ # Echo short help message to standard output. func_usage_message () { $debug_cmd eval \$ECHO \""Usage: $usage"\" echo $SED -n 's|^# || /^Written by/{ x;p;x } h /^Written by/q' < "$progpath" echo eval \$ECHO \""$usage_message"\" } # func_version # ------------ # Echo version message to standard output and exit. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' /(C)/!b go :more /\./!{ N s|\n# | | b more } :go /^# Written by /,/# warranty; / { s|^# || s|^# *$|| s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| p } /^# Written by / { s|^# || p } /^warranty; /q' < "$progpath" exit $? } # Local variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. scriptversion='(GNU libtool) 2.4.6' # func_echo ARG... # ---------------- # Libtool also displays the current mode in messages, so override # funclib.sh func_echo with this custom definition. func_echo () { $debug_cmd _G_message=$* func_echo_IFS=$IFS IFS=$nl for _G_line in $_G_message; do IFS=$func_echo_IFS $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" done IFS=$func_echo_IFS } # func_warning ARG... # ------------------- # Libtool warnings are not categorized, so override funclib.sh # func_warning with this simpler definition. func_warning () { $debug_cmd $warning_func ${1+"$@"} } ## ---------------- ## ## Options parsing. ## ## ---------------- ## # Hook in the functions to make sure our own options are parsed during # the option parsing loop. usage='$progpath [OPTION]... [MODE-ARG]...' # Short help message in response to '-h'. usage_message="Options: --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --mode=MODE use operation mode MODE --no-warnings equivalent to '-Wnone' --preserve-dup-deps don't remove duplicate dependency libraries --quiet, --silent don't print informational messages --tag=TAG use configuration variables from tag TAG -v, --verbose print more informational messages than default --version print version information -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. func_help () { $debug_cmd func_usage_message $ECHO "$long_help_message MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. When passed as first option, '--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. Try '$progname --help --mode=MODE' for a more detailed description of MODE. When reporting a bug, please describe a test case to reproduce it and include the following information: host-triplet: $host shell: $SHELL compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) version: $progname $scriptversion Debian-2.4.6-15 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . GNU libtool home page: . General help using GNU software: ." exit 0 } # func_lo2o OBJECT-NAME # --------------------- # Transform OBJECT-NAME from a '.lo' suffix to the platform specific # object suffix. lo2o=s/\\.lo\$/.$objext/ o2lo=s/\\.$objext\$/.lo/ if test yes = "$_G_HAVE_XSI_OPS"; then eval 'func_lo2o () { case $1 in *.lo) func_lo2o_result=${1%.lo}.$objext ;; * ) func_lo2o_result=$1 ;; esac }' # func_xform LIBOBJ-OR-SOURCE # --------------------------- # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) # suffix to a '.lo' libtool-object suffix. eval 'func_xform () { func_xform_result=${1%.*}.lo }' else # ...otherwise fall back to using sed. func_lo2o () { func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` } func_xform () { func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` } fi # func_fatal_configuration ARG... # ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func__fatal_error ${1+"$@"} \ "See the $PACKAGE documentation for more information." \ "Fatal configuration error." } # func_config # ----------- # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # ------------- # Display the features supported by this script. func_features () { echo "host: $host" if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag TAGNAME # ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname=$1 re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf=/$re_begincf/,/$re_endcf/p # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # libtool_options_prep [ARG]... # ----------------------------- # Preparation for options parsed by libtool. libtool_options_prep () { $debug_mode # Option defaults: opt_config=false opt_dlopen= opt_dry_run=false opt_help=false opt_mode= opt_preserve_dup_deps=false opt_quiet=false nonopt= preserve_args= _G_rc_lt_options_prep=: # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; *) _G_rc_lt_options_prep=false ;; esac if $_G_rc_lt_options_prep; then # Pass back the list of options. func_quote_for_eval ${1+"$@"} libtool_options_prep_result=$func_quote_for_eval_result fi $_G_rc_lt_options_prep } func_add_hook func_options_prep libtool_options_prep # libtool_parse_options [ARG]... # --------------------------------- # Provide handling for libtool specific options. libtool_parse_options () { $debug_cmd _G_rc_lt_parse_options=false # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) func_config ;; --dlopen|-dlopen) opt_dlopen="${opt_dlopen+$opt_dlopen }$1" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) func_features ;; --finish) set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $_G_opt && break opt_mode=$1 case $1 in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $_G_opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" ;; --no-warnings|--no-warning|--no-warn) opt_warning=false func_append preserve_args " $_G_opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $_G_opt" ;; --silent|--quiet) opt_quiet=: opt_verbose=false func_append preserve_args " $_G_opt" ;; --tag) test $# = 0 && func_missing_arg $_G_opt && break opt_tag=$1 func_append preserve_args " $_G_opt $1" func_enable_tag "$1" shift ;; --verbose|-v) opt_quiet=false opt_verbose=: func_append preserve_args " $_G_opt" ;; # An option not handled by this hook function: *) set dummy "$_G_opt" ${1+"$@"} ; shift _G_match_lt_parse_options=false break ;; esac $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done if $_G_rc_lt_parse_options; then # save modified positional parameters for caller func_quote_for_eval ${1+"$@"} libtool_parse_options_result=$func_quote_for_eval_result fi $_G_rc_lt_parse_options } func_add_hook func_parse_options libtool_parse_options # libtool_validate_options [ARG]... # --------------------------------- # Perform any sanity checks on option settings and/or unconsumed # arguments. libtool_validate_options () { # save first non-option argument if test 0 -lt $#; then nonopt=$1 shift fi # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" case $host in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match test yes != "$build_libtool_libs" \ && test yes != "$build_old_libs" \ && func_fatal_configuration "not configured to build any kind of library" # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test execute != "$opt_mode"; then func_error "unrecognized option '-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help=$help help="Try '$progname --help --mode=$opt_mode' for more information." } # Pass back the unparsed argument list func_quote_for_eval ${1+"$@"} libtool_validate_options_result=$func_quote_for_eval_result } func_add_hook func_validate_options libtool_validate_options # Process options as early as possible so that --help and --version # can return quickly. func_options ${1+"$@"} eval set dummy "$func_options_result"; shift ## ----------- ## ## Main. ## ## ----------- ## magic='%%%MAGIC variable%%%' magic_exe='%%%MAGIC EXE variable%%%' # Global variables. extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # func_generated_by_libtool # True iff stdin has been generated by Libtool. This function is only # a basic sanity check; it will hardly flush out determined imposters. func_generated_by_libtool_p () { $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file # True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test yes = "$lalib_p" } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { test -f "$1" && $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $debug_cmd save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # 'FILE.' does not work on cygwin managed mounts. func_source () { $debug_cmd case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $debug_cmd if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=$1 if test yes = "$build_libtool_libs"; then write_lobj=\'$2\' else write_lobj=none fi if test yes = "$build_old_libs"; then write_oldobj=\'$3\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $debug_cmd # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $debug_cmd if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $debug_cmd # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $debug_cmd if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result=$1 fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $debug_cmd if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result=$3 fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $debug_cmd case $4 in $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $debug_cmd $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $debug_cmd case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result=$1 } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $debug_cmd func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $debug_cmd if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd=func_convert_path_$func_stripname_result fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $debug_cmd func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result=$1 } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $debug_cmd func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_dll_def_p FILE # True iff FILE is a Windows DLL '.def' file. # Keep in sync with _LT_DLL_DEF_P in libtool.m4 func_dll_def_p () { $debug_cmd func_dll_def_p_tmp=`$SED -n \ -e 's/^[ ]*//' \ -e '/^\(;.*\)*$/d' \ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ -e q \ "$1"` test DEF = "$func_dll_def_p_tmp" } # func_mode_compile arg... func_mode_compile () { $debug_cmd # Get the compilation command and the source file. base_compile= srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg=$arg arg_mode=normal ;; target ) libobj=$arg arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs=$IFS; IFS=, for arg in $args; do IFS=$save_ifs func_append_quoted lastarg "$arg" done IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg=$srcfile srcfile=$arg ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj=$func_basename_result } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test yes = "$build_libtool_libs" \ || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname=$func_basename_result xdir=$func_dirname_result lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test no = "$compiler_c_o"; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext lockfile=$output_obj.lock else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test yes = "$build_old_libs"; then if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix '.c' with the library object suffix, '.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the '--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE use a list of object files found in FILE to specify objects -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with '-') are ignored. Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in '.la', then a libtool library is created, only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created using 'ar' and 'ranlib', or on Windows using 'lib'. If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test : = "$opt_help"; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | $SED '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $debug_cmd # The first argument is the command name. cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "'$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir=$func_dirname_result ;; *) func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file=$progdir/$program fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if $opt_dry_run; then # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd=\$cmd$args fi } test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $debug_cmd libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "'$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument '$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $debug_cmd # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=false stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=: if $isdir; then destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." destdir=$func_dirname_result destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking '$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname=$1 shift srcname=$realname test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= ;; esac ;; os2*) case $realname in *_dll.a) tstripme= ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name=$func_basename_result instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest=$destfile destfile= ;; *) func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile=$destdir/$destname else func_basename "$file" destfile=$func_basename_result destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script '$wrapper'" finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then func_warning "'$lib' has not been installed in '$libdir'" finalize=false fi done relink_command= func_source "$wrapper" outputname= if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file=$func_basename_result outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file=$outputname else func_warning "cannot relink '$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name=$func_basename_result # Set up the ranlib parameters. oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $debug_cmd my_outputname=$1 my_originator=$2 my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* External symbol declarations for the compiler. */\ " if test yes = "$dlself"; then func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi func_show_eval '$RM "${nlist}I"' if test -n "$global_symbol_to_import"; then eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[];\ " if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ static void lt_syminit(void) { LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; for (; symbol->name; ++symbol) {" $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" echo >> "$output_objdir/$my_dlsyms" "\ } }" fi echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = { {\"$my_originator\", (void *) 0}," if test -s "$nlist"I; then echo >> "$output_objdir/$my_dlsyms" "\ {\"@INIT@\", (void *) <_syminit}," fi case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $debug_cmd func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $debug_cmd win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || func_cygming_gnu_implib_p "$1" then win32_nmres=import else win32_nmres= fi ;; *) func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s|.*|import| p q } }'` ;; esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $debug_cmd sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $debug_cmd match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive that possess that section. Heuristic: eliminate # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $debug_cmd if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result= fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $debug_cmd f_ex_an_ar_dir=$1; shift f_ex_an_ar_oldlib=$1 if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $debug_cmd my_gentop=$1; shift my_oldlibs=${1+"$@"} my_oldobjs= my_xlib= my_xabs= my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` func_basename "$darwin_archive" darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches; do func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" cd "unfat-$$/$darwin_base_archive-$darwin_arch" func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result=$my_oldobjs } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include #define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ #if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC #elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined other platforms ... */ #endif #if defined PATH_MAX # define LT_PATHMAX PATH_MAX #elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) #if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; size_t tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined HAVE_DOS_BASED_FILE_SYSTEM if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined HAVE_DOS_BASED_FILE_SYSTEM } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = (size_t) (q - p); p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (STREQ (str, pat)) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else size_t len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { size_t orig_value_len = strlen (orig_value); size_t add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ size_t len = strlen (new_value); while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $debug_cmd case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_suncc_cstd_abi # !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! # Several compiler flags select an ABI that is incompatible with the # Cstd library. Avoid specifying it if any are in CXXFLAGS. func_suncc_cstd_abi () { $debug_cmd case " $compile_command " in *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) suncc_use_cstd_abi=no ;; *) suncc_use_cstd_abi=yes ;; esac } # func_mode_link arg... func_mode_link () { $debug_cmd case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=false prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test yes != "$build_libtool_libs" \ && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir=$arg prev= continue ;; dlfiles|dlprefiles) $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=: } case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test no = "$dlself"; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test dlprefiles = "$prev"; then dlself=yes elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols=$arg test -f "$arg" \ || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex=$arg prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir=$arg prev= continue ;; mllvm) # Clang does not use LLVM to link, so we can simply discard any # '-mllvm $arg' options when doing the link step. prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object fi # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; os2dllname) os2dllname=$arg prev= continue ;; precious_regex) precious_files_regex=$arg prev= continue ;; release) release=-$arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds=$arg prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg=$arg case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between '-L' and '$1'" else func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of '$dir'" dir=$absdir ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test X-lc = "X$arg" && continue ;; esac elif test X-lc_r = "X$arg"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -mllvm) prev=mllvm continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module=$wl-multi_module continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "'-no-install' is ignored for $host" func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -os2dllname) prev=os2dllname continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs=$IFS; IFS=, for flag in $args; do IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer # -fuse-ld=* Linker select flags for GCC # -static-* direct GCC to link specific libraries statically # -fcilkplus Cilk Plus language extension features for C/C++ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; -Z*) if test os2 = "`expr $host : '.*\(os2\)'`"; then # OS/2 uses -Zxxx to specify OS/2-specific options compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case $arg in -Zlinker | -Zstack) prev=xcompiler ;; esac continue else # Otherwise treat like 'Some other compiler flag' below func_quote_for_eval "$arg" arg=$func_quote_for_eval_result fi ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test none = "$pic_object" && test none = "$non_pic_object"; then func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result test none = "$pic_object" || { # Prepend the subdirectory the object is found in. pic_object=$xdir$pic_object if test dlfiles = "$prev"; then if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg=$pic_object } # Non-PIC object. if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test none = "$pic_object"; then arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg=$func_quote_for_eval_result ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the '$prevarg' option requires an argument" if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname=$func_basename_result libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" # Definition is injected by LT_CONFIG during libtool generation. func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" func_dirname "$output" "/" "" output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs=$tmp_deplibs fi if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass"; then libs=$deplibs deplibs= fi if test prog = "$linkmode"; then case $pass in dlopen) libs=$dlfiles ;; dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs=$dlprefiles fi if test dlopen = "$pass"; then # Collect dlpreopened libraries save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test lib != "$linkmode" && test prog != "$linkmode"; then func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib=$searchdir/lib$name$search_ext if test -f "$lib"; then if test .la = "$search_ext"; then found=: else found=false fi break 2 fi done done if $found; then # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll=$l done if test "X$ll" = "X$old_library"; then # only static version available found=false func_dirname "$lib" "" "." ladir=$func_dirname_result lib=$ladir/$old_library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi else # deplib doesn't seem to be a libtool library if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi ;; # -l *.ltframework) if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=: fi ;; pass_all) valid_a_lib=: ;; esac if $valid_a_lib; then echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." fi ;; esac continue ;; prog) if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test conv = "$pass"; then deplibs="$deplib $deplibs" elif test prog = "$linkmode"; then if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=: continue ;; esac # case $deplib $found || test -f "$lib" \ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir=$func_dirname_result dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test lib,link = "$linkmode,$pass" || test prog,scan = "$linkmode,$pass" || { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test prog != "$linkmode" && test lib != "$linkmode"; then func_fatal_error "'$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test yes = "$prefer_static_libs" || test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib=$l done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. if test dlopen = "$pass"; then test -z "$libdir" \ && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || test yes != "$dlopen_support" || test no = "$build_libtool_libs" then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir=$ladir fi ;; esac func_basename "$lib" laname=$func_basename_result # Find the relevant object directory and library name. if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library '$lib' was moved." dir=$ladir absdir=$abs_ladir libdir=$abs_ladir else dir=$lt_sysroot$libdir absdir=$lt_sysroot$libdir fi test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir=$ladir absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else dir=$ladir/$objdir absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test dlpreopen = "$pass"; then if test -z "$libdir" && test prog = "$linkmode"; then func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=false if test no != "$link_all_deplibs" || test -z "$library_names" || test no = "$build_libtool_libs"; then linkalldeplibs=: fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && { { test no = "$prefer_static_libs" || test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if $alldeplibs && { test pass_all = "$deplibs_check_method" || { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule=$dlpremoduletest break fi done if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test lib = "$linkmode" && test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc* | *os2*) func_arith $current - $age major=$func_arith_result versuffix=-$major ;; esac eval soname=\"$soname_spec\" else soname=$realname fi # Make a new name for the extract_expsyms_cmds to use soroot=$soname func_basename "$soroot" soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test no = "$hardcode_direct"; then add=$dir/$linklib case $host in *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add=$dir/$old_library fi elif test -n "$old_library"; then add=$dir/$old_library fi fi esac elif test no = "$hardcode_minus_L"; then case $host in *-*-sunos*) add_shlibpath=$dir ;; esac add_dir=-L$dir add=-l$name elif test no = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; relink) if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$dir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name elif test yes = "$hardcode_shlibpath_var"; then add_shlibpath=$dir add=-l$name else lib_linked=no fi ;; *) lib_linked=no ;; esac if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test yes != "$hardcode_direct" && test yes != "$hardcode_minus_L" && test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test yes = "$hardcode_direct" && test no = "$hardcode_direct_absolute"; then add=$libdir/$linklib elif test yes = "$hardcode_minus_L"; then add_dir=-L$libdir add=-l$name elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add=-l$name elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib"; then add=$inst_prefix_dir$libdir/$linklib else add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add=-l$name fi if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test unsupported != "$hardcode_direct"; then test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test yes = "$build_libtool_libs"; then # Not a shared library if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test lib = "$linkmode"; then if test -n "$dependency_libs" && { test yes != "$hardcode_into_libs" || test yes = "$build_old_libs" || test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of '$dir'" absdir=$dir fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names"; then for tmp in $deplibrary_names; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl"; then depdepl=$absdir/$objdir/$depdepl darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) path=-L$absdir/$objdir ;; esac else eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "'$deplib' seems to be moved" path=-L$absdir fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test link = "$pass"; then if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs=$newdependency_libs if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test dlopen != "$pass"; then test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= } if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" else vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Add Sun CC postdeps if required: test CXX = "$tagname" && { case $host_os in linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; solaris*) func_cc_basename "$CC" case $func_cc_basename_result in CC* | sunCC*) func_suncc_cstd_abi if test no != "$suncc_use_cstd_abi"; then func_append postdeps ' -library=Cstd -library=Crun' fi ;; esac ;; esac } # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i= ;; esac if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test prog = "$linkmode"; then dlfiles=$newdlfiles fi if test prog = "$linkmode" || test lib = "$linkmode"; then dlprefiles=$newdlprefiles fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs=$output func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test no = "$module" \ && func_fatal_help "libtool library '$output' must begin with 'lib'" if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test pass_all != "$deplibs_check_method"; then func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test no = "$dlself" \ || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test 1 -lt "$#" \ && func_warning "ignoring multiple '-rpath's for a libtool library" install_libdir=$1 oldlibs= if test -z "$rpath"; then if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift IFS=$save_ifs test -n "$7" && \ func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major=$1 number_minor=$2 number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|freebsd-elf|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_revision ;; freebsd-aout|qnx|sunos) current=$number_major revision=$number_minor age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age=$number_minor revision=$number_minor lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type '$version_type'" ;; esac ;; no) current=$1 revision=$2 age=$3 ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT '$current' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION '$revision' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE '$age' must be a nonnegative integer" func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE '$age' is greater than the current interface number '$current'" func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" # On Darwin other compilers case $CC in nagfor*) verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" ;; *) verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; esac ;; freebsd-aout) major=.$current versuffix=.$current.$revision ;; freebsd-elf) func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; irix | nonstopux) if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring_prefix$major.$iface:$verstring done # Before this point, $major must not contain '.'. major=.$major versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=.$current.$age.$revision verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring=$verstring:$iface.0 done # Make executables depend on our current version. func_append verstring ":$current.0" ;; qnx) major=.$current versuffix=.$current ;; sco) major=.$current versuffix=.$current ;; sunos) major=.$current versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result versuffix=-$major ;; *) func_fatal_configuration "unknown library version type '$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring=0.0 ;; esac if test no = "$need_version"; then versuffix= else versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided if test yes,no = "$avoid_version,$need_version"; then major= versuffix= verstring= fi # Check to see if the archive will have undefined symbols. if test yes = "$allow_undefined"; then if test unsupported = "$allow_undefined_flag"; then if test yes = "$build_old_libs"; then func_warning "undefined symbols not allowed in $host shared libraries; building static only" build_libtool_libs=no else func_fatal_error "can't build $host shared library unless -no-undefined is specified" fi fi else # Don't allow undefined symbols. allow_undefined_flag=$no_undefined_flag fi fi func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" test " " = "$libobjs" && libobjs= if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release= versuffix= major= newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib= ;; esac fi if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib= break 2 fi done done fi if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test yes = "$allow_libtool_libs_with_static_runtimes"; then for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test yes = "$droppeddeps"; then if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** 'nm' from GNU binutils and a full rebuild may help." fi if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test no = "$build_old_libs"; then oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test yes = "$build_libtool_libs"; then # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath=$finalize_rpath test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath=$finalize_shlibpath test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname=$realname fi if test -z "$dlname"; then dlname=$soname fi lib=$output_objdir/$realname linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS=$save_ifs if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi ${skipped_export-false} && { func_verbose "generating symbol list for '$libname.la'" export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols=$export_symbols test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi } libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs=$IFS; IFS='~' for cmd in $cmds; do IFS=$sp$nl eval cmd=\"$cmd\" IFS=$save_ifs $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS=$save_ifs # Restore the uninstalled library and exit if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. dlname=$soname fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ func_warning "'-version-info' is ignored for objects" test -n "$release" && \ func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj=$output ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # if reload_cmds runs $LD directly, get rid of -Wl from # whole_archive_flag_spec and hope we can get by with turning comma # into space. case $reload_cmds in *\$LD[\ \$]*) wl= ;; esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS } if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "'-version-info' is ignored for programs" test -n "$release" && \ func_warning "'-release' is ignored for programs" $preload \ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " $wl-bind_at_load" func_append finalize_command " $wl-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath=$rpath rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath=$rpath if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=false ;; *cygwin* | *mingw* ) test yes = "$build_libtool_libs" || wrappers_required=false ;; *) if test no = "$need_relink" || test yes != "$build_libtool_libs"; then wrappers_required=false fi ;; esac $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.$objext"; then func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test yes = "$no_install"; then # We don't need to create a wrapper script. link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi case $hardcode_action,$fast_install in relink,*) # Fast installation is not supported link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath func_warning "this platform does not like uninstalled shared libraries" func_warning "'$output' will be relinked during installation" ;; *,yes) link_command=$finalize_var$compile_command$finalize_rpath relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` ;; *,no) link_command=$compile_var$compile_command$compile_rpath relink_command=$finalize_var$finalize_command$finalize_rpath ;; *,needless) link_command=$finalize_var$compile_command$finalize_rpath relink_command= ;; esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource=$output_path/$objdir/lt-$output_name.c cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do case $build_libtool_libs in convenience) oldobjs="$libobjs_save $symfileobj" addlibs=$convenience build_libtool_libs=no ;; module) oldobjs=$libobjs_save addlibs=$old_convenience build_libtool_libs=no ;; *) oldobjs="$old_deplibs $non_pic_objects" $preload && test -f "$symfileobj" \ && func_append oldobjs " $symfileobj" addlibs=$old_convenience ;; esac if test -n "$addlibs"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test yes = "$installed"; then if test -z "$install_libdir"; then break fi output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name=$func_basename_result func_resolve_sysroot "$deplib" eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name=$func_basename_result eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } if test link = "$opt_mode" || test relink = "$opt_mode"; then func_mode_link ${1+"$@"} fi # func_mode_uninstall arg... func_mode_uninstall () { $debug_cmd RM=$nonopt files= rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic=$magic for arg do case $arg in -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir=$func_dirname_result if test . = "$dir"; then odir=$objdir else odir=$dir/$objdir fi func_basename "$file" name=$func_basename_result test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif $rmforce; then continue fi rmfiles=$file case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.$objext" if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name"; then func_append rmfiles " $odir/lt-$noexename.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then func_mode_uninstall ${1+"$@"} fi test -z "$opt_mode" && { help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: hamlib-4.6.2/AUTHORS0000644000175000017500000001635414752216205010765 00000000000000This file is licensed to you under the license specified in the included file `COPYING'. Look there for further details. Authors of the Hamlib API, original code: Frank Singleton and Stephane Fillod Contributors: (if any is missing, please email the current maintainer). For any reason, if you prefer not to appear in this list, please let me know. M: Current maintainer C: Contributors W: Web-page with status/info S: Status, one of the following: Supported: Someone is actually bothered to look after this. Maintained: Someone actually looks after it. Odd Fixes: It has a maintainer but they don't have time to do much other than throw the odd patch in. See below.. Orphan: No current maintainer [but maybe you could take the role as you write your new code]. Obsolete: Old code. Something tagged obsolete generally means it has been replaced by a better system and you should be using that. Backends: [adat: ADT-200A] M: Frank Goenninger DG1SBG [alinco: DX77-T] M: Ben Coleman NJ8J [aor] C: testing by John Ronan [aor: AR-7030] M: Friedrich Melchert DC9RP [aor: AR-7030 Plus] M: Larry Gadallah VE6VQ [aor: AR-3030] M: Tristan Mills [aor: AR-8200] M: Rob Walker [drake] M: Mark J. Fine [icom: ic7000] M: Kent Hill, AD7AI [icom: ic7200] M: James Watson, HZ1JW [icom: ic718] M: Chuck Gilkes, WD0FCL/4 [icom: icr7000] M: Chuck Hemker, N2POR [icom: ic735] C: Darren Hatcher, G0WCW [icom: ic751] C: Lars E. Pettersson, SM6RPZ [icom: icr75] M: Mark J. Fine [icom: OptoScan] M: Michael Smith, KE4RJQ [icom] M: Stephane Fillod, F8CFE [jrc] M: Mark J. Fine C: Manual and testing by Bob Parnass, AJ9S [kenwood] M: Joop Stakenborg, PG4I C: Alessandro Zummo, IZ1PRB [kenwood: K2] M: Nate Bargmann, N0NB M: Brian Mury, VE7NGR C: Leigh Klotz, WA5ZNU [kenwood: K3] M: Nate Bargmann, N0NB C: Alexander Sack [kenwood: TS-480SAT] M: Juergen Rinas, DC3BW [kenwood: TS-570] M: Rob Frohne, KL7NA C: Thomas Beierlein, DL1JBE [kenwood: R-5000] M: Mark J. Fine [kenwood: tmd700] M: Charles Suprin, AA1VS [kenwood: thg71,tmv7,tmd700] C: Thierry Leconte, F4DWV [kenwood: thg71,tmv7] M: Andrew McNamara [kenwood: thd7] M: Stephane Fillod, F8CFE [kenwood: ts-850] C: Rob Frohne, KL7NA [kit: Si570 AVR-USB] C: Fabrice, F4AVI [kit: Elektor SDR] C: John Nogatch, AC6SL [pcr: pcr100,pcr1000] M: Alessandro Zummo, IZ1PRB C: Darren Hatcher, G0WCW [tentec] M: C: testing by James Chance, N3TKD [tentec: tt516] M: James Nykiel [tentec: tt538] M: Mike Markowski AB3AP [tentec: tt550] M: Ken Koster, N7IPB [tentec: tt565] M: Martin Ewing AA6E [tentec: Argonaut V] C: Dave Freese, W1HKJ [tentec: tt585] C: Bert, KG4BEC [tentec: rx331] M: Berndt Josef Wulf, VK5ABN [uniden: 245xlt] M: Eric Cottrell WB1HBU [winradio] M: C: Pascal Brisset [yeasu: ft1000d] M: Serge Pashenkov [yeasu: ft100] M: Alex V Flinsch, KC2IVL [yaesu: ft736] C: Ron Patterson, W6FM [yaesu: ft747] M: C: Chris Bryant, G3WIE C: Frank Singleton, VK3FCS [yaesu: ft767gx] M: Steve Conklin, AI4QR [yaesu: ft817] M: Chris Karpinsky, AA1VL [yaesu: ft847] M: Jim Jerzycke, KQ6EA C: Frank Singleton, VK3FCS [yaesu: ft920, ft890, ft900] M: Nate Bargmann, N0NB [yaesu: ft980] M: Wolfgang Buesser, DK1BW [yaesu: ft990] M: Berndt Josef Wulf, VK5ABN [yaesu: ft950,newcat] M: Terry Embry, KJ4EED [yaesu: VR-5000] M: Jacob Heder [yaesu: FT-600] C: KÄrlis Millers [CM108 GPIO PTT] M: Andrew Errington, ZL3AME Rotators [celestron] M: Stephane Fillod, F8CFE C: Eric/N3KQX [easycomm] M: Luc Langehegermann, LX2GT C: Francois Retief [fodtrack] M: Luc Langehegermann, LX2GT [amsat/if-100] M: Stephane Fillod, F8CFE C: Patrick Strasser, OE6PSE [heathkit:HD 1780 Intellirotor] M: Rob Frohne, KL7NA [rotorez] M: Nate Bargmann, N0NB [spid] M: Norvald H. Ryeng, LA6YKA [m2] M: Magne Mæhre, LA1BFA C: Ron Patterson, W6FM [ars] M: Stephane Fillod, F8CFE C: Chris Bryant, G3WIE [ts7400] M: Øystein HÃ¥rberg, LA7LKA [indi] M: Norbert Varga, HA2NON [Frontend] M: Stephane Fillod, F8CFE [src/locator.c] M: Dave Hines, M1CXW C: Stephane Fillod, F8CFE C: Nate Bargmann, N0NB [test utilities] M: Stephane Fillod, F8CFE C: Nate Bargmann, N0NB C: Nirgal Vourgère [platform: FreeBSD] M: Diane Bruce, VA3DB [platform: NetBSD] M: Berndt Josef Wulf, VK5ABN [platform: win32] M: Stephane Fillod, F8CFE C: VB & testing by Darren Hatcher, G0WCW C: VB.NET wrapper by Michael Benz [packaging: debian] M: Kamal Mostafa, KA6MAL M: Jaime Robles, EA4TV C: Joop Stakenborg, PG4I [packaging: RPM] M: Alexandru Csete, OZ9AEC M: Joop Stakenborg, PG4I [Web site: http://www.hamlib.org] M: Joop Stakenborg, PG4I M: Stephane Fillod, F8CFE M: Nate Bargmann, N0NB E-mail addresses: Frank Singleton, VK3FCS, Stephane Fillod, F8CFE, Pascal Brisset Nate Bargmann, N0NB, Chris Karpinsky, AA1VL, Joop Stakenborg, PG4I, Bob Parnass, AJ9S, Francois Retief, James Chance, N3TKD, Chuck Hemker, N2POR, Alex V Flinsch, KC2IVL, Chuck Gilkes, WD0FCL/4, Dale E. Edmons, KD7ENI, Michael Smith, KE4RJQ Berndt Josef Wulf, VK5ABN Mark J. Fine Jim Jerzycke, KQ6EA Alexandru Csete OZ9AEC Diane Bruce, VA3DB Dave Hines, M1CXW, Darren Hatcher, G0WCW, Ben Coleman, NJ8J, Serge Pashenkov Lars E. Pettersson SM6RPZ Thomas Beierlein, DL1JBE, Kent Hill, AD7AI, Dave Freese, W1HKJ, Rob Frohne, KL7NA, Steve Conklin, AI4QR, Martin Ewing, AA6E, Terry Embry, KJ4EED, Alessandro Zummo, IZ1PRB Norvald H. Ryeng, LA6YKA Larry Gadallah, VE6VQ Kamal Mostafa, KA6MAL, Jaime Robles, EA4TV, Wolfgang Buesser, DK1BW, Magne Mæhre, LA1BFA, Charles Suprin, AA1VS, Robert Steinhäußer, DL1NC, James Watson, HZ1JW, Juergen Rinas, DC3BW, Kamal Mostafa, KA6MAL, Roger, Tristan Mills, Terry Dawson, VK2KTJ, Øystein HÃ¥rberg, LA7LKA, Alexander Sack Nirgal Vourgère Andrew Errington KÄrlis Millers YL3ALK Norbert Varga HA2NON hamlib-4.6.2/doc/0000755000175000017500000000000014752216241010531 500000000000000hamlib-4.6.2/doc/footer.html0000644000175000017500000000234214752216205012636 00000000000000
hamlib-4.6.2/doc/hamlib.cfg.in0000644000175000017500000000324714752216205013001 00000000000000## hamlib.cfg.in--converted into hamlib.cfg by config.status PROJECT_NAME = Hamlib PROJECT_NUMBER = @VERSION@ PROJECT_LOGO = @top_srcdir@/doc/hamlib.png # Output OUTPUT_DIRECTORY= . OUTPUT_LANGUAGE = English GENERATE_HTML = YES GENERATE_LATEX = NO GENERATE_RTF = NO GENERATE_MAN = NO # User can set to YES for local man pages MAN_EXTENSION = .3 # Set GENERATE_LATEX to YES to generate the needed files for the PDF manual # and run 'make doc'. Then 'cd latex ; make' to generate the PDF manual. # # See section 1.3.1.2 in @top_srcdir@/README.developer for the needed LaTeX # packages. USE_PDFLATEX = YES PDF_HYPERLINKS = YES EXTRA_PACKAGES = pmboxdraw # Input CASE_SENSE_NAMES = YES FULL_PATH_NAMES = NO INPUT = @top_srcdir@/doc/index.doxygen \ @top_srcdir@/include/hamlib/ \ @top_srcdir@/src/ EXCLUDE = @top_srcdir@/src/amp_conf.h \ @top_srcdir@/include/hamlib/ampclass.h \ @top_srcdir@/include/hamlib/rotclass.h INCLUDE_PATH = @top_srcdir@/include EXAMPLE_PATH = @top_srcdir@/tests/testrig.c \ @top_srcdir@ \ @top_srcdir@/scripts \ @top_builddir@/scripts QUIET = YES HTML_FOOTER = @top_srcdir@/doc/footer.html HTML_EXTRA_STYLESHEET = @top_srcdir@/doc/hamlib.css EXTRACT_ALL = NO EXTRACT_STATIC = NO HIDE_UNDOC_MEMBERS = NO SHOW_INCLUDE_FILES = YES INHERIT_DOCS = YES ENABLED_SECTIONS = "" PREDEFINED = DOXYGEN "DOC_HIDDEN" JAVADOC_AUTOBRIEF = NO OPTIMIZE_OUTPUT_FOR_C = YES MAN_LINKS = NO MACRO_EXPANSION = YES hamlib-4.6.2/doc/Makefile.am0000644000175000017500000000307514752216205012512 00000000000000EXTRA_DIST = hamlib.cfg index.doxygen hamlib.css footer.html hamlib.png dist_man_MANS = man1/ampctl.1 man1/ampctld.1 \ man1/rigctl.1 man1/rigctld.1 man1/rigmem.1 man1/rigsmtr.1 \ man1/rigswr.1 man1/rotctl.1 man1/rotctld.1 man1/rigctlcom.1 man1/rigctlsync.1 \ man7/hamlib.7 man7/hamlib-primer.7 man7/hamlib-utilities.7 SRCDOCLST = \ ../include/hamlib/amplifier.h \ ../include/hamlib/amplist.h \ ../include/hamlib/rig.h \ ../include/hamlib/rotator.h \ ../include/hamlib/rotlist.h \ ../src/amp_conf.c \ ../src/amp_settings.c \ ../src/amplifier.c \ ../src/cal.c \ ../src/cm108.c \ ../src/conf.c \ ../src/debug.c \ ../src/event.c \ ../src/ext.c \ ../src/extamp.c \ ../src/locator.c \ ../src/mem.c \ ../src/misc.c \ ../src/network.c \ ../src/parallel.c \ ../src/rig.c \ ../src/rot_conf.c \ ../src/rot_ext.c \ ../src/rot_settings.c \ ../src/rotator.c \ ../src/tones.c \ ../src/serial.c \ ../src/settings.c \ ../src/sleep.c \ ../src/token.h \ ../src/tones.c \ ../src/usb_port.c # Just the file names, the paths are assigned below. SCRIPTSLST = build-w32.sh build-w64.sh # Use GNU source-highlight to generate highlighted shell scripts for the # Doxygen manual. doc: hamlib.cfg $(SRCDOCLST) for script in $(SCRIPTSLST) ; \ do \ source-highlight -n -f html -i $(top_srcdir)/scripts/$${script} -o $(top_builddir)/scripts/$${script}.html ; \ source-highlight -n -f latex -i $(top_srcdir)/scripts/$${script} -o $(top_builddir)/scripts/$${script}.tex ; \ done doxygen hamlib.cfg clean-local: -rm -rf $(top_builddir)/doc/html $(top_builddir)/doc/latex hamlib-4.6.2/doc/Makefile.in0000644000175000017500000005304514752216215012526 00000000000000# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/macros/ax_append_flag.m4 \ $(top_srcdir)/macros/ax_cflags_warn_all.m4 \ $(top_srcdir)/macros/ax_cxx_compile_stdcxx.m4 \ $(top_srcdir)/macros/ax_lib_indi.m4 \ $(top_srcdir)/macros/ax_lib_nova.m4 \ $(top_srcdir)/macros/ax_lib_readline.m4 \ $(top_srcdir)/macros/ax_lua.m4 \ $(top_srcdir)/macros/ax_pkg_swig.m4 \ $(top_srcdir)/macros/ax_pthread.m4 \ $(top_srcdir)/macros/ax_python_devel.m4 \ $(top_srcdir)/macros/gr_pwin32.m4 \ $(top_srcdir)/macros/hl_getaddrinfo.m4 \ $(top_srcdir)/macros/libtool.m4 \ $(top_srcdir)/macros/ltoptions.m4 \ $(top_srcdir)/macros/ltsugar.m4 \ $(top_srcdir)/macros/ltversion.m4 \ $(top_srcdir)/macros/lt~obsolete.m4 \ $(top_srcdir)/macros/perl.m4 $(top_srcdir)/macros/pkg.m4 \ $(top_srcdir)/macros/tcl.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/hamlib/config.h CONFIG_CLEAN_FILES = hamlib.cfg CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man7dir)" man7dir = $(mandir)/man7 NROFF = nroff MANS = $(dist_man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ $(srcdir)/hamlib.cfg.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ABI_AGE = @ABI_AGE@ ABI_REVISION = @ABI_REVISION@ ABI_VERSION = @ABI_VERSION@ ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMP_BACKENDEPS = @AMP_BACKENDEPS@ AMP_BACKEND_LIST = @AMP_BACKEND_LIST@ AMTAR = @AMTAR@ AM_CFLAGS = @AM_CFLAGS@ AM_CPPFLAGS = @AM_CPPFLAGS@ AM_CXXFLAGS = @AM_CXXFLAGS@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BINDINGS = @BINDINGS@ BINDING_ALL = @BINDING_ALL@ BINDING_CHECK = @BINDING_CHECK@ BINDING_CLEAN = @BINDING_CLEAN@ BINDING_DISTCHECK = @BINDING_DISTCHECK@ BINDING_DISTCLEAN = @BINDING_DISTCLEAN@ BINDING_INSTALL_EXEC = @BINDING_INSTALL_EXEC@ BINDING_LIB_TARGETS = @BINDING_LIB_TARGETS@ BINDING_LIST = @BINDING_LIST@ BINDING_UNINSTALL = @BINDING_UNINSTALL@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ INDI_LIBS = @INDI_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBUSB = @LIBUSB@ LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ LIBUSB_LIBS = @LIBUSB_LIBS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LUA = @LUA@ LUA_EXEC_PREFIX = @LUA_EXEC_PREFIX@ LUA_INCLUDE = @LUA_INCLUDE@ LUA_LIB = @LUA_LIB@ LUA_PLATFORM = @LUA_PLATFORM@ LUA_PREFIX = @LUA_PREFIX@ LUA_SHORT_VERSION = @LUA_SHORT_VERSION@ LUA_VERSION = @LUA_VERSION@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIBS = @MATH_LIBS@ MKDIR_P = @MKDIR_P@ NET_LIBS = @NET_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NOVA_LIBS = @NOVA_LIBS@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OSXLDFLAGS = @OSXLDFLAGS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL_INC_DIR = @PERL_INC_DIR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PTHREAD_CC = @PTHREAD_CC@ PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ PTHREAD_LIBS = @PTHREAD_LIBS@ PYTHON = @PYTHON@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RC = @RC@ READLINE_LIBS = @READLINE_LIBS@ RIG_BACKENDEPS = @RIG_BACKENDEPS@ RIG_BACKEND_LIST = @RIG_BACKEND_LIST@ ROT_BACKENDEPS = @ROT_BACKENDEPS@ ROT_BACKEND_LIST = @ROT_BACKEND_LIST@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SWIG = @SWIG@ SWIG_LIB = @SWIG_LIB@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_CFLAGS = @TCL_CFLAGS@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LIBS = @TCL_LIBS@ TCL_LIB_FILE = @TCL_LIB_FILE@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@ TCL_SRC_DIR = @TCL_SRC_DIR@ TCL_VERSION = @TCL_VERSION@ USRP_CFLAGS = @USRP_CFLAGS@ USRP_LIBS = @USRP_LIBS@ VERSION = @VERSION@ WINEXELDFLAGS = @WINEXELDFLAGS@ WINLDFLAGS = @WINLDFLAGS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cf_with_cxx = @cf_with_cxx@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ luadir = @luadir@ luaexecdir = @luaexecdir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pkgluadir = @pkgluadir@ pkgluaexecdir = @pkgluaexecdir@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pyexecdir = @pyexecdir@ pythondir = @pythondir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = hamlib.cfg index.doxygen hamlib.css footer.html hamlib.png dist_man_MANS = man1/ampctl.1 man1/ampctld.1 \ man1/rigctl.1 man1/rigctld.1 man1/rigmem.1 man1/rigsmtr.1 \ man1/rigswr.1 man1/rotctl.1 man1/rotctld.1 man1/rigctlcom.1 man1/rigctlsync.1 \ man7/hamlib.7 man7/hamlib-primer.7 man7/hamlib-utilities.7 SRCDOCLST = \ ../include/hamlib/amplifier.h \ ../include/hamlib/amplist.h \ ../include/hamlib/rig.h \ ../include/hamlib/rotator.h \ ../include/hamlib/rotlist.h \ ../src/amp_conf.c \ ../src/amp_settings.c \ ../src/amplifier.c \ ../src/cal.c \ ../src/cm108.c \ ../src/conf.c \ ../src/debug.c \ ../src/event.c \ ../src/ext.c \ ../src/extamp.c \ ../src/locator.c \ ../src/mem.c \ ../src/misc.c \ ../src/network.c \ ../src/parallel.c \ ../src/rig.c \ ../src/rot_conf.c \ ../src/rot_ext.c \ ../src/rot_settings.c \ ../src/rotator.c \ ../src/tones.c \ ../src/serial.c \ ../src/settings.c \ ../src/sleep.c \ ../src/token.h \ ../src/tones.c \ ../src/usb_port.c # Just the file names, the paths are assigned below. SCRIPTSLST = build-w32.sh build-w64.sh all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): hamlib.cfg: $(top_builddir)/config.status $(srcdir)/hamlib.cfg.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-man7: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man7dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man7dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man7dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.7[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man7dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man7dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man7dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man7dir)" || exit $$?; }; \ done; } uninstall-man7: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man7dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.7[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^7][0-9a-z]*$$,7,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man7dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man7dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-man7 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 uninstall-man7 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-man7 install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-man uninstall-man1 uninstall-man7 .PRECIOUS: Makefile # Use GNU source-highlight to generate highlighted shell scripts for the # Doxygen manual. doc: hamlib.cfg $(SRCDOCLST) for script in $(SCRIPTSLST) ; \ do \ source-highlight -n -f html -i $(top_srcdir)/scripts/$${script} -o $(top_builddir)/scripts/$${script}.html ; \ source-highlight -n -f latex -i $(top_srcdir)/scripts/$${script} -o $(top_builddir)/scripts/$${script}.tex ; \ done doxygen hamlib.cfg clean-local: -rm -rf $(top_builddir)/doc/html $(top_builddir)/doc/latex # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: hamlib-4.6.2/doc/hamlib.png0000644000175000017500000000437014752216205012417 00000000000000‰PNG  IHDR00Ø`nпIDATxÚíXkl\Gž33÷Þ}{×Î:öúÑ$&I“”¼è P%ª„EDŠ„@BÀB<ƒâG‰(Ôþ(H€Z©"µ¢U[@­Ê3"H¨’Ôqb;~?b;ëݽ{3sÐìÝ—ë‡h¥‚²ÚwïΜùæÌ9ßùÎÀÙ³gÉ;éCÉ;ìsÐz¾ê[”’  „–#¢T„`”,ª*Ô¶t{ÕYõv”Zbyƒ€Xª CÇUvQ/Å9KE U°Ñój˜i, ¦¡}_ŠõhÀ0X*¢=_ÛAÓ`‘0Šž§ öò½­¥œâ)1·¾oìøQâûþÔLöñ‰/b}(´ÿneÒ`ÉÜ‹¯9W¯ÖŽmñÞhhB–78¼ø«Wc¡=;cÇ>H8óúoä~÷tsÏÎĉãe;ë{1÷òëîÌ00ˆ÷C)ÕÂââs/)âY÷…ïÝO v€•Ê>÷’Ó?”ší±cGˆiÄ«˜¾uûù_Sv{¶E޾Å"ö¹Þ>ó<;ú¦Gz+v6Ô4™àV Âa"•^€Q–JòHRŸb)t,C «|ž§›yºY¹®wí†Pu’Áy4ÉÓ-2—C£X(zýÿf©O¤h,Z¶³Ñ,“…ÔѲÀ2Áà(e)Ò+VPAÈrúÄÌ-«³Ãêî YçR?XfýJÊõx* +ý*_p¯ZÝèºeÐêT@»èM ãŠ™¹åH)o`H¹ÅС}4Ο¿ècÎÖ鬀Â5zºIÈp._3ZÓÒ¶ã‡ß]|ó¬Îë¤=Çò¿ÿkî•× ÑùÌqaW’ ˜†¼µàö 7Ì»{XS Ó“Ó¼»CÙv,ÝB£‘â_þ±˜+°d‚ïÚ±†{’µ$CïÙ:´ÏÚµƒHYõ„21>厎éVÞ¾•¥[ÌL›71éŒÃR6B)ÃöŠ|®Ø×Úµƒ'ã¨$MJU¾}ÿ½Ï<Ññ‹n9õEåzKR”‚sá ºÏ´m¬µ…ßÕ¾p.¾‰K 7Ú¿—)²sÆ»¶±T!’Ø|  /T¾€ŽƒEwé_„Y¼|•š¦?15þ¹oœI#çòUôjСä!Ö–Ž{PL͆ï;„:äqÓ¥£vp”–¾P_+À4ý¡Q19MLNÈ\‚Úaþìœ}ØÜÓS Ðã-cËw¾œcöù7Ö. |ÓÕO³°é^³s`š[OËܵ•c“S_{T.d¾ëÖÁ=A«íb1¯s#'ókÍ S?¹ü¦ä6Ï÷n(Ï7;Ú® ˜&˜†Ñ™1;ÛQ ð&ÚnùÔªFÆÊÏ”®ku@h•_¨ÕQ¥TÁVÅúB'üBÖþÛ¿”g›;ºh"Š®G|AÖµ»GyNñÂ%13«)[J¥ úßêòP2µìå²0YEÂ"ú7Ç•ç±ToK…è¸þèAäí­,™PŽëL |KЧ›N'Œªù¬?s (5º24’¹‚?2ÎRMFûV"ˆH,½á1MH™­$˜¸> BtÅÐ<+ËN¢”Zf $´iJu=)¥!ú~Ùh©xaè,r]]£–…B,Q,Ú”…R4rR¦¶Ô| õGVÎ;­³– ¨Ðz~-Jô¬Â’1eS+^®Ÿe:Ï—¯uTá®1k—wDþÿY×ÈÐuλ:fY«¯3ËÇ@™Z7‘pFM3|䋦JõrPI@P¡Îùj‘±Lݽ V©A³†ç¯±Ï€ÆÔbÞ›˜&Fg;D«`¢à*ÇÕþÊ–^Ck{£+SÖùœûc“*›#ŒAà6ÊX"ÆÚÒš„hꀔ¢‰XñìùÉo~Ïüìtøþƒ*WX²'¥h$:ýÝ9×®P#AMƒ(×U¾mfºº_ø¥&$¥Xþ=Bˆ™˜úÙÙŸüÜ¿9ÞüÕϯzfoé(嬹g§¹»'ÖûPêS‡H8ÿ§s^ÿ Y+n=)¥[D}åP½;¢µ«*)k«?]‰I‹|¥ ëh™/ˆ…E‹³•Ç×ÞFh2AjÁ‹Z©aùªŠ6%h4ü„H˜%›ô}šë®<8Ý–îhäÈ$¡:ßÊaƒ€ô –U|£Oå ºDhjAÂXøÀ^m‹³â…Ë(„7< –Asû‚k†ÐÁ}5n¤ N¤,üñ“Ó‹/ü¥2Ò[ÌîŒ. +ñ‘è‹ü